Babel 是一个让我们能够使用 ES 新特性的 JS 编译工具,我们可以在
webpack中配置Babel,以便使用 ES6、ES7 标准来编写 JS 代码。
本文以当前最新版本的 babel - 7.10 为例, 做 babel 的配置. 相关版本号如下
1 | { |
babel-loader 和 @babel/core
建立基本的 webpack 配置文件
1 | mkdir webpack-babel => cd webpack-babel => yarn init -y // 初始化 |
- yarn : 和
npm几乎一样,本文使用yarn安装… - babel-loader: 转义 js 文件代码的 loader
- @babel/core:babel 核心库
根目录下添加 webpack.config.js
1 | const path = require('path') |
src/index.js
1 | const func = () => { |
执行 yarn build 后就可以打包成功,打包后的代码是压缩后的。而 yarn start 后的代码是未压缩的。为了使代码可读性高一点,我们可以在webpack.config.js添加:
1 | module.exports = { |
@babel-preset-env
打包后我们可以发现箭头函数并未转化为 ES5 语法!
查阅 babel plugins 文档,如果要转义箭头函数,需要使用到 @babel/plugin-transform-arrow-functions 这个插件
同理转义 class 需要使用 @babel/plugin-transform-classes
1 | yarn add @babel/plugin-transform-arrow-functions @babel/plugin-transform-classes -D |
根目录下建立 .babelrc 文件:
1 | { |
yarn build 之后可以看出 箭头函数和类都被转义了。
但是假如你再使用 async await 之类的 es6 语法,你还得一个个添加,这是不实际的。
@babel-preset-env 就整合了这些语法转义插件:
1 | Using plugins: |
使用如下:
1 | yarn add @babel-preset-env -D |
.babelrc
1 | { |
@babel/polyfill
Babel 默认只转换新的 JavaScript 句法(syntax),而不转换新的 API ,比如 Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise 等全局对象,以及一些定义在全局对象上的方法(比如 Object.assign)都不会转码。
这样就导致了一些新的 API 老版浏览器不兼容。如上述所说,对于新的 API,你可能需要引入 @babel-polyfill 来进行兼容
1 | yarn add @babel-polyfill -D |
修改 weboack.config.js
1 | module.exports = { |
yarn build 发现文件体积大了很多,因为上面的代码表示将 @babel-polyfill 的代码也打包进去了。
当然这不是我们希望的,如何按需编译呢? 我们可以这么做:
index.js
1 | import '@babel/polyfill' // 引入 |
还原 webpack.config.js
1 | module.exports = { |
修改 .babelrc
1 | { |
yarn build 后发现我们的代码体积就变得很小了!
@babel/runtime 和 @babel/plugin-transform-runtime
babel-polyfill会污染全局作用域, 如引入Array.prototype.includes修改了 Array 的原型,除此外还有 String…babel-polyfill引入新的对象:Promise、WeakMap等
这也不是我们希望出现的。
@babel/runtime的作用:- 提取辅助函数。ES6 转码时,babel 会需要一些辅助函数,例如 _extend。babel 默认会将这些辅助函数内联到每一个 js 文件里, babel 提供了 transform-runtime 来将这些辅助函数“搬”到一个单独的模块
babel-runtime中,这样做能减小项目文件的大小。 - 提供
polyfill:不会污染全局作用域,但是不支持实例方法如 Array.includes
- 提取辅助函数。ES6 转码时,babel 会需要一些辅助函数,例如 _extend。babel 默认会将这些辅助函数内联到每一个 js 文件里, babel 提供了 transform-runtime 来将这些辅助函数“搬”到一个单独的模块
@transform-runtime的作用:babel-runtime更像是分散的polyfill模块,需要在各自的模块里单独引入,借助 transform-runtime 插件来自动化处理这一切,也就是说你不要在文件开头 import 相关的polyfill,你只需使用,transform-runtime会帮你引入。
1 | yarn add @babel/runtime-corejs2 |
修改 .babelrc
1 | { |
index.js 移除 import '@babel/polyfill'
@babel/plugin-proposal-decorators
添加装饰器模式的支持
1 | yarn add @babel/plugin-proposal-decorators -D |
index.js
1 | function annotation(target) { |
.babelrc
1 | { |