在webpack中使用babel来编译你的es6和es7
muwoo opened this issue · 0 comments
你需要了解的babel
babel 是一个javaScript 编译工具,babel 已经支持最新的 javascript 版本,下面我们来介绍 babel 常用的几个工具
babel-preset-env
安装:
npm install babel-preset-env --save-dev
不需要任何配置,babel-preset-env
表现的同babel-preset-latest一样(或者可以说同babel-preset-es2015, babel-preset-es2016, and babel-preset-es2017结合到一起,表现的一致)
你也可以通过配置polyfills和transforms来支持你所需要支持的浏览器,仅配置需要支持的语法来使你的打包文件更轻量级。
{
"presets": ["env"]
}
有了上面这些调研,我们来看一下vue-cli 脚手架里有这样一段话:
{"presets": [["env", {
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}]]
}
通过上面的这些研究,我们知道了:
- ">1% " 兼容全球使用率大于1%的流览器
- last 2 versions 兼容每个游览器的最近两个版本
- not ie <= 8 不兼容ie8及以下
说到这里,我们开始我们第一个demo,我们来编译我们的ES6 项目:
// src/test.js
export default 'hello ES6'
// src/index.js
import test from './test'
console.log(test)
// webpack.config.js
const path = require('path')
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, "dist"),
filename: '[name].bundle.js'
},
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
options: {
presets: [["env", {
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}]]
}
}
]
}
}
但是随着项目的复杂度增加,我们在options里面的配置会越来越多,所以我们可以利用babel 提供的.babelrc
来提供相同的用法:
// .babelrc
presets: [["env", {
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}]]
babel-polyfill
babel 本身只提供预发的转换,当我们使用一些箭头函数这样的新的语法,其实在babel看来,更像是一种语法糖。但是babel不能转义一些ES6、ES7...的新的全局属性,例如 Promise 、新的原生方法如 String.padStart (left-pad) 等。这个时候我们就需要使用babel-polyfill.
npm install --save babel-polyfill
更详细的介绍可以参考:https://babeljs.cn/docs/usage/polyfill
这里主要体积一下:
Babel 转译后的代码要实现源代码同样的功能需要借助一些帮助函数,例如,{ [name]: 'JavaScript' } 转译后的代码如下所示:
'use strict';
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
var obj = _defineProperty({}, 'name', 'JavaScript');
类似上面的帮助函数 _defineProperty 可能会重复出现在一些模块里,导致编译后的代码体积变大。Babel 为了解决这个问题,提供了单独的包 babel-runtime 供编译模块复用工具函数。
启用插件 babel-plugin-transform-runtime 后,Babel 就会使用 babel-runtime 下的工具函数,转译代码如下:
'use strict';
// 之前的 _defineProperty 函数已经作为公共模块 `babel-runtime/helpers/defineProperty` 使用
var _defineProperty2 = require('babel-runtime/helpers/defineProperty');
var _defineProperty3 = _interopRequireDefault(_defineProperty2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var obj = (0, _defineProperty3.default)({}, 'name', 'JavaScript');
只不过那些需要修改内置api才能达成的功能,譬如:扩展String.prototype,给上面增加includes方法,就属于修改内置API的范畴。这类操作就由polyfill提供,所以项目中可以视情况选择不同的类型库