前些天使用了 babel7
,特来作个笔记。原文发布在GitHub。javascript
在 babel7
中,已经废弃了以前的阶段性提案,如今统一使用 @babel/preset-env
。因此呢,这里却是省去了一些麻烦。在 webpack
配置中 preset-env
配合 babel-loader
就能够转换 ES2015+
语法了。同时,官方建议咱们使用 targets
设定目标浏览器决定须要兼容的功能。举个例子:java
module.exports = { presets: [ [ '@babel/preset-env', { targets: { ie: "11" } } ] ] }
polyfill
在以前都是用来引入新的 api
和功能的。如咱们经常使用的 promise
,Object.assign
等。在 babel6
及以前,只须要在入口引入 polyfill
便可。然而这也带来了问题,一次性加载了整个 polyfill
,十分冗余。 而用了 babel7
经过简单的配置就能够达成按需加载的目的,咱们也再也不须要手动引入 polyfill
。node
没错,使用这个新的配置项,就能够实现按需加载 polyfill
。其值可取如下3个:webpack
值为 false
的时候,至关于没用,这时就得手动引入全部的 polyfill
。git
使用 entry
的时候,也须要手动引入 polyfill
,即 import '@babel/polyfill';
,同时也引入了全部的 polyfill
。这个配置项,总以为没什么用,若是有老哥知道的话能够在评论区提出一块儿讨论。github
值为 usage
的时候,无需引入 polyfill
,babel
会自动按需加载须要的功能:web
{ \\... useBuiltIns: 'usage' }
若是须要在命令行打印加载项,能够设置 debug
:npm
{ \\... useBuiltIns: 'usage', dubug: true }
例如使用 class(类)
的时候,babel
会在这前面添加一个帮助函数。以下所示:
源代码:api
// source code class Test {}
编译后:promise
"use strict"; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Test = function Test() { _classCallCheck(this, Test); };
能够看到,在编译输出的代码里,helper
函数被直接嵌入代码中。若是你只有这一个 js
文件用到了这个 helper
,那这样并无问题。但试想一下,若是你有不少个脚本文件,每个你都用到了 class
,babel
可无论你这么多,每一个编译后的文件都包含一个如出一辙的 helper
函数,便形成了冗余。所幸,咱们可使用 @babel/plugin-transform-runtime
和 @babel/runtime
来解决这个问题。添加以下配置:
plugins: [ '@babel/plugin-transform-runtime' ]
此时再编译上面的代码,获得的结果以下:
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var Test = function Test() { (0, _classCallCheck2.default)(this, Test); };
此时再也不是直接把 helper
函数嵌入代码中,而是使用 require
加载公共 helper
。
polyfill
仍是 runtime
@babel/runtime
比较合适。由于 @babel/polyfill
会污染全局环境,别人引入你的库可能会形成没必要要的污染。@babel/runtime
不能提供一些实例方法,诸如 "foobar".includes("foo")
这类的。还需本身手动引入。对于本身的应用项目,仍是引入 @babel/polyfill
更好,提供的功能更全面,也不须要担忧全局污染。但如我上面所说的,一些 helper
函数,若是不使用 @babel/plugin-transform-runtime
插件的话,会引入冗余的代码。而这二者放在一块儿使用的时候,若是没有对 plugin-transform-runtime
进行配置,是不会有重复功能的引入的。
上面说了这么多,如今给出 babel7
和 webpack
的实践做为结束。
1.添加依赖
cnpm i --save-dev babel-loader @babel/core @babel/preset-env @babel/plugin-transform-runtime // & cnpm i --save @babel/polyfill @babel/runtime
2.webpack
配置
module.exports = { // ... module: { rules: [ { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ } ] } };
3.babel
配置
如下是在本身的应用项目中的配置:
// babel.config.js module.exports = { presets: [ [ '@babel/preset-env', { useBuiltIns: 'usage', targets: { ie: 10 // 根据本身的目标环境进行配置 }, debug: true, // corejs这一项也须要加上,corejs有2和3两个版本 // 若是不肯定有没有下载core-js,可执行 cnpm i core-js@2 --save corejs: 2 } ] ], plugins: [ '@babel/plugin-transform-runtime' ] };
发布给别人使用的工具或库,可使用如下配置:
// babel.config.js module.exports = { presets: [ '@babel/preset-env' ], plugins: [ [ '@babel/plugin-transform-runtime', { corejs: 2 // ... } ] ] };