掌握Javascript(八)

本文是掌握Javascript系列的最后一篇,介绍ES6相关工具。


模块

将js文件拆分成小文件,就是模块modules。好处是:

可维护、重用、抽象。

可维护和重用比较好理解,抽象举个例子:

const _radius = new WeakMap()

class Circle{

    …

    _radius.set(this,radius);

    …

}

如果调用类Circle的代码与类在同一个文件中,实际上它就可以用下列语句得到私有属性

const radius = _radius.get(this)

但如果将类Circle和弱映射 _radius包在模块里,且只对外公开Circle类,外部调用模块则无法访问_radius,也就实现隐藏私有属性,达到了抽象的目的。

ES5是没有模块的,一些天才程序员就自己开发了模块,主要有AMD、CommonJS、UMD等,AMD用于浏览器,CommonJS用于Node,而UMD可以在浏览器和Node中都可用。ES6则自带模块语法。本文主要介绍CommonJS和ES6的原生模块。


CommonJS 模块

高度相关的东西才放在一起,模块也一样。

默认情况下,模块内容是私有的,除非指定公开。

如果想公开一个模块的类,比如Circle,可以在模块后面加上

module.exports.Circle=Circle;

module.exports.Square=Square;

这样,module.exports对象就有了两个属性 Circle 和 Square。

使用该模块的程序就可以访问了。

如果只引入一个类 Circle,可以简化成:

module.exports = Circle;

然后,其他程序比如 index.js调用该模块,就可以

const Circle = require(‘./circle’);

circle会自动加上js后缀,相当于引用circle.js,上面语句会返回上面公开的对象Circle。然后就可以使用了:

const c = new Circle(10);

c.draw();

在node环境下,可以用 node index.js测试下效果。


ES6 模块

新建一个circle.js文件, 具体内容如下:

const _radius = new WeakMap();

export class Circle {

    constructor(radius) {

        _radius.set(this, radius);

    }

    draw() {

        console.log(“Circle with radius ” + _radius.get(this));

    }

}

注意 class Circle 前面有 export,表示外部可以访问。没有加就不能访问,比如外部就不能访问 _radius 对象。

下面开始在 index.js中调用。

import { Circle } from “./circle.js”;

const c = new Circle(10);

c.draw();

这里有个小问题是,网页中测试这段代码会出错,一般是用webpack解决。为了演示,可以将 包含 index.js的index.html修改一下,设置index.js的类型为module。

<script type=”module” src=”./index.js”></script>

type改成 module后,import语句要写全扩展名circle.js,否则会出错。而类型不是模块的话,则可以省略扩展名。

import { Circle } from ‘./circle.js’;


ES6 工具

如果在浏览器上开发Javascript,工具很重要;而如果只在node.js中开发,则工具不重要。

工具主要是两类:转换器和打包器。

转换器的作用是转换和编译,转换成所有浏览器都能识别的代码,比如BABEL,它可以将Javascript转换成ES5,这是所有浏览器都识别的。

打包器的作用是将许多js 文件合成一个 js文件,最受欢迎的是webpack,它有精简作用。


Babel

需要 node,但我们无需了解太多,只需安装node,因为会用到它的npm。

npm是用来安装第三方库和工具的软件。

从 https://nodejs.org 下载最新稳定版。

检查版本:node -v

建立一个文件夹:mkdir es6-tooling

进入新建文件夹:cd es6-tooling

初始化:npm init –yes  将创建一个package.json文件

安装babel:npm i babel-cli@6.26.0 babel-core@6.26.0 babel-preset-env@1.6.1

上面的 @ 表示特定的版本,也可省略安装最新的版本,不过最后参照官网执行,命令有可能会有变化。

打开 vscode:code .

新建一个index.js文件,简单写些代码,然后使用Babel转换。

编辑当前目录的package.json文件,修改:

“scripts”: {

“babel”: “babel –preset env index.js -o build/index.js”

},

注意事先建立build文件夹,因为转换的文件将放在该文件夹下。

回到控制台,执行刚才配置的脚本:npm run babel

可以在build/index.js中看到转换的内容。

这里的问题是:如果有成千上万个js文件需要转换,该怎么办?

这就需要webpack上场了!


Webpack

这里我们用实际的工作路径来演示。前面ES6模块一节有两个模块:circle.js和index.js,以及index.html文件。

新建src文件夹,将circle.js和index.js移进去。

安装webpack:sudo npm i -g  webpack-cli

* windows不用sudo,webpack后面也可加特定版本如webpack-cli@2.0.14

初始化:webpack-cli init .

* 回答一些问题,并安装很多包,包括babel。

初始化,创建package.json:npm init –yes

修改package.json,添加 build脚本命令,如下:

“scripts”: {

“build”: “webpack”

},

执行打包命令:npm run build

创建了一个main.js文件,就是src文件夹里的circle.js和index.js的打包。

回到 index.html中,修改script的指向:

<script src=”dist/main.js”></script>

这里还有个问题,改了源码之后,都要重新用 “npm run build” 打包,很麻烦。可以修改package.json的build脚本,webpack加上参数 -w即可。这样源码修改后将自动打包。

“build”: “webpack -w”

另外,用了webpack打包后,import不用写明扩展名 js 了,比如在index.js中的import语句中,直接可以用circle而不用写明circle.js

import { Circle } from “./circle”;


结束语

掌握Javascript系列写完了,感谢关注的朋友们,希望这个系列能帮助到您。

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注