本文是掌握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系列写完了,感谢关注的朋友们,希望这个系列能帮助到您。