Babel学习和插件
核心库
Babel 的核心功能在 @babel/core 模块。通过以下命令安装:
npm install --save-dev @babel/core
CLI 工具
@babel/cli 是一个允许你从终端使用 babel 的工具。下面是安装命令和基本用法的示例:
npm install --save-dev @babel/core @babel/cli
./node_modules/.bin/babel src --out-dir lib
它使用我们设置的解析方式来解析 src 目录中的所有 JavaScript 文件,并将转换后每个文件输出到 lib 目录。由于我们还没有设置解析方式,这里输出代码将与输入相同(不保留确切的代码样式)。我们可以通过将它们作为选项传入来指定我们想要的解析方式。
我们使用上面的 --out-dir 选项。你可以通过使用 --help 运行它来查看 cli 工具接受的其余选项。但对我们来说最重要的是 --plugins 和 --presets。
Plugins & Presets 插件和presets 预设值如何对代码进行转换
代码转换以插件的形式出现,插件是小型 JavaScript 程序,它指示 Babel 如何对代码进行转换。你甚至可以编写自己的插件来应用你想要的任何代码转换。要将ES2015+ 语法转换为 ES5,
npm install --save-dev @babel/plugin-transform-arrow-functions // 可以使用箭头函数的插件
./node_modules/.bin/babel src --out-dir lib --plugins=@babel/plugin-transform-arrow-functions
现在我们代码中的所有箭头函数都将转换为 ES5 兼容函数表达式:
const fn = ()=> 1;// converted tovar fn = functionfn(){
return 1;
};
这是一个好的开始!如果想要转换代码中还有其他 ES2015+ 功能。我们可以使用 "preset" 来代替预先设定的一组插件,而不是逐一添加我们想要的所有插件。
就像使用 plugins 一样,你也可以创建自己的 preset,分享你需要的任何插件组合。在这个例子中,我们使用了 env preset。
preset与plugin的关系:
preset中已经包含了一组用来转换ES6+的语法的插件,如果只使用少数新特性而非大多数新特性,可以不使用preset而只使用对应的转换插件
babel默认只转换语法,而不转换新的API,如需使用新的API,还需要使用对应的转换插件或者polyfill
例如,默认情况下babel可以将箭头函数,class等语法转换为ES5兼容的形式,但是却不能转换Map,Set,Promise等新的全局对象,这时候就需要使用polyfill去模拟这些新特性
Polyfill
@babel/polyfill 模块包括 core-js 和自定义 regenerator runtime 来模拟完整的 ES2015+ 环境。
这意味着你可以使用像 Promise 或 WeakMap 这样的新内置函数,像 Array.from 或 Object.assign 这样的静态方法,像Array.prototype.includes 这样的实例方法,以及 generator 函数(提供给你使用 regenerator 插件)。为了做到这一点,polyfill 增加了全局范围以及像 String 这样的原生原型。
对于库/工具的作者来说,太冗余了。如果你不需要像 Array.prototype.includes 这样的实例方法,可以使用 transform runtime 插件而不是污染全局的 @babel/polyfill。
更进一步,如果你确切知道需要实现的功能,可以直接从 core-js 中获取它们。
由于我们正在构建一个应用程序,我们可以只安装 @babel/polyfill:
npm install --save @babel/polyfill
Babel 默认只转换新的 JavaScript 句法(syntax),而不转换新的 API,比如Iterator、Generator、Set、Map、Proxy、Reflect、Symbol、Promise等全局对象,以及一些定义在全局对象上的方法(比如Object.assign)都不会转码。
举例来说,ES6 在Array对象上新增了Array.from方法。Babel 就不会转码这个方法。如果想让这个方法运行,必须使用babel-polyfill,为当前环境提供一个垫片。
总结
我们使用 @babel/cli 从终端运行 Babel,@babel/polyfill 来实现所有新的 JavaScript 功能,env preset 只包含我们使用的功能的转换,实现我们的目标浏览器中缺少的功能。