后面就介绍一些我在打包es6语法时踩过的坑:
误区一、 直接使用babel-loader:
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}
刚开始我在使用webpack打包时,也是意识到了需要将es6语法打包成es5,所以我直接百度复制过来了webpack的配置代码,打包、运行,发现代码完全可以运行,当时的我也没想太多,以为已经成功的转成了es5,但是我最近在看webpack视频的时候,才发现大错特错,之所以能运行是因为我用的是谷歌浏览器,默认就支持es6语法,这时我打包看了一下打包后生成的代码:
发现果然不行。解决办法:
这时候我们再打开babel官网看一下,发现如果我们需要转成es5的语法,那就需要再安装一个包 @babel/preset-env (做语法转换),代码如下:
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
},
发现之前的const打包后已经变成了var
误区二、 以为解决了上面的问题就可以了:
如果像我之前以为的那样,看到已经转成var就已经可以直接继续开发项目了那就又错了,相信大家现在开发promise的使用也很频繁的,那么我在源码中写一个promise看看打包后的是什么样:
// 源码中
function testPromise() {
return new Promise((resolve, reject) => {
resolve(12313)
})
}
testPromise().then(res => {
console.log(res)
})
这时候我们会发现testPromise 这个方法只是把箭头函数转成了function的形式,但是promise直接复制了下来,这样在一些不支持promise的浏览器中就会出现问题。解决办法:
再安装一个包babel官网的babel-polyfill,对一些没有promise之类语法的浏览器进行这些方法的补充。我们直接安装babel-polyfill后,在文件的顶部引入这个包:
// index.js 顶部
import "@babel/polyfill"
好了继续打包:
可以发现,我们只使用了promise,但是很多其他的语法我们没有用到却被打包进来了。虽然已经解决了promise在浏览器内的兼容问题,但是很明显,打包后的代码体积变大了,打包了很多没用到的内容。误区三、 引入babel-polyfill后,打包体积过大:
解决办法:
在webpack config配置中添加一个属性 useBuiltIns: 'usage', 当我们配置了这个属性后,import "@babel/polyfill"不写也可以自动打包出我们需要的方法
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [['@babel/preset-env', {
useBuiltIns: 'usage'
}]]
}
}
},
这时候再来打包一下:
可以看到这个明显变少了,之前很多没用到的方法就没有被打包。四、联系实际项目需求配置
打开babel官网使用指南, 可以继续配置presets,
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [['@babel/preset-env', {
targets: {
chrome: "67"
},
useBuiltIns: 'usage'
}]]
}
}
},
我设置了targets中的chrome版本后,再进行打包,发现promise的兼容方法没有被打包进来,这是因为我们设置了项目的运行环境,而谷歌浏览器本身是支持promise语法的,所以就没有对这部分进行打包。
这样如果我们的项目有一些指定的运行环境,即可使用这个方法,可以优化webpack打包后的代码。