webpack 学习 3 - babel
这一篇的目标是——
编译 ES6/7 的代码。
通过这一篇,我们将了解:
- 什么是 loader
- 利用 babel-loader 「编译」ES6/7 的其他特性
- 利用 es3ify-loader 解决 IE8 不认关键字做属性的问题
修改版本号:yarn version --new-version 0.0.3
。
引子
在 [第一篇] 中,我们已经了解到,虽然 webpack 原生支持 import
和 export
,但对于其他的 ES6/7 特性却并没有处理,所以现在构建出来的代码并不能在所有的浏览器里都能玩。
正如 webpack 官方文档中说的:
Note that webpack will not alter any code other than import and export statements. If you are using other ES2015 features, make sure to use a transpiler such as Babel or Bublé.
我们就 Babel 吧。
loader(加载器)
先了解一下 webpack 的 loader(加载器) 的概念。
简言之,webpack 视一切为模块,但 JS 毕竟只认识 JS,所以 loader 的作用就是帮 webpack 「认识」这些「外乡人」,并知道如果处理它们。
你可以在这里找到有用的 loader 列表,其中之一就是 babel-loader,这正是我们需要的。
安装 babel-loader
安装以下依赖:
yarn add babel-loader babel-core babel-preset-env --dev
这里除了
babel-loader
之外,babel-core
和babel-preset-env
也是需要的,否则编译会报错。 babel-core 是 babel 的编译核心; babel-preset-env 能让我们免于写一堆的 presets。
修改配置
然后,我们修改一下 webpack.config.js
,添加如下代码:
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["env"]
}
}
}]
}
注意,这里的
presets
仅为 env。私下认为这并不是一个很好的设计,因为全局搜索代码将无法搜到babel-preset-env
的引用。
较一开始的配置,我们多了一个 module,这是我们为各种类型的文件指定 loader 的地方,loader 会帮助 webpack 把各种文件解释成 webpack 能够理解的 JS module。
参考文档 https://webpack.js.org/concepts/#loaders
这里,我们告诉 webpack:「项目下以 .js
结尾的文件(忽略 node_modules
目录),请用 babel-loader
进行处理,babel-loader
的配置也给你了,用那个叫做 env
的 preset。」
构建结果
再次运行 yarn build
,再去看构建出来的代码:
/******/ (function(modules) {
/******/ // webpackBootstrap
/******/ })
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _component = __webpack_require__(1);
var _component2 = _interopRequireDefault(_component);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
document.body.appendChild((0, _component2.default)());
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function () {
var text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "hello webpack";
var element = document.createElement("div");
element.innerHTML = text;
return element;
};
/***/ })
/******/ ]);
之前留存的 ES6 代码(箭头函数、参数默认值、const
)都已经被转成所有浏览器都能认识的了。
IE8
上面的代码中有 exports.default = ...
这样的代码,在 IE8 中是会报错的,会说「缺少标识符」。虽然 IE8 比较老,也是我们比较痛恨的浏览器,但可能还是需要解决它。
如果你愿意花时间尝试,对象属性名称为关键字的话,也是没有被加引号的:
console.log({
break: 'break',
catch: 'catch',
default: 'default'
});
这些同样在 IE8 下会报错。
我们需要 es3ify 来对代码进行转换,对于 webpack 而言,只需要 es3ify-loader 就行了。
yarn add es3ify-loader --dev
然后修改 webpack.config.js 的 module:
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: ["es3ify-loader", {
loader: "babel-loader",
options: {
presets: ["env"]
}
}]
}]
}
注意,es3ify-loader 必须放在 babel-loader 前面,否则会报错说「Illegal import declaration」。
这里,你应该已经注意到了 use 的多种写法,它可以支持字符串,对象,已经字符串和对象的混合数组。
执行构建 yarn build
,然后再看 dist/index.js 就会发现原来的 .default
变成了 ["default"]
。
总结
这一节,我们:
- 首次接触了 webpack 的 loader 概念
- 使用 babel-loader 及它的依赖完成 ES6/7 到 ES5 的编译
- 使用 es3ify-loader,兼容了 IE8 下关键字不可做属性名的问题
同样,打个 tag:
git add .
git commit -m 'CHORE use babel-loader and fix ie8 keyword issue'
git push
git tag 0.0.3
git push origin 0.0.3
代码参考:https://github.com/justnewbee/learn-webpack/tree/0.0.3
打完收工