webpack打包es6语法

3,799 阅读2分钟

在我们平时写项目时多多少少的都会用到es6语法,而实际上es6语法可能会在一些低版本浏览器不支持,导致我们的代码在低版本浏览器运行不了,这时候就需要我们使用webpack对项目代码进行打包,将我们的es6语法转换成浏览器可以识别的es5语法。
后面就介绍一些我在打包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打包后的代码。