webpack之Babel的使用

1,634 阅读3分钟

Babel 是一个把ES6语法转译成ES5语法的工具,目的是为了保证项目最终能够运行在一些老旧的浏览器上面

安装

npm install babel-loader @babel-core --save-dev

npm install @babel/preset-env --save-dev

babel-loader: babel 翻译JavaScript文件,但仅是这样并不能让他工作起来,还需要其他插件

@babel-core: 把 js 代码分析成 ast ,方便各个插件分析语法进行相应的处理。有些语法在低版本是不存在的,例如箭头函数,rest参数等,需要先转义

@babel/preset-env: 会根据你的环境配置,把ES6+的语法转换成ES5代码,但会造成环境污染问题

index.js

let arr = [1, 2, 3, 4];
let p = new Promise(() => {
  console.log('你好世界')
})

webpack.config.js 配置如下

const path = require('path');

module.exports = {
  mode: "development",
  entry: './src/js/index.js',
  output: {
    filename: "index.js",
    path: path.resolve(__dirname, 'build')
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-env']
        }
      }
    ]
  }
}

但其实你如果查看打包之后的文件,其实Promise并没有被转换成ES5代码,如果放在IE就炸了,我们就需要安装另外一个插件

npm install @babel/polyfill --save-dev

@babel/polyfill: 完成对内置对象的转义

在index.js文件中引入

import '@babel/polyfill'
let arr = [1, 2, 3, 4];
let p = new Promise(() => {
  console.log('你好世界')
})

当前的转义有一个小小的问题, babel/polyfill在翻译的时候, 把哪些在ES5中不存在的一个对象或是方法都给封装出来了, 导致最终的打包文件分外的大,这种情况明显太过于臃肿了.

{
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        options: {
          presets: [
            '@babel/preset-env',
            {
              useBuiltIns: 'usage', // 当用户在使用polufill进行填充自定义函数时候,会按需引入
              targets: { // 针对指定浏览器做转义
                edge: '17',
                chrome: '67',
                safari: '11.1'
              }
            },
          ]
        }
      }
polyfill 的缺陷是替代方式
polyfill实现方式是直接进行全局注入,就相当于修改了全局的配置,这对于一些业务代码来说自然没啥,要是对于要开发一个组件来说,就有点hold不住了,所以我们某些迪岑开发场景,可以使用其他转义方法

npm install @babel/plugin-transform-runtime --save-dev

npm install @babel/runtime --save-dev

npm install @babel/runtime-corejs2 --save-dev

这样就避免了全局污染

webpack.config.js

    {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        options: {
          'plugins': [
            [
              '@babel/plugin-transform-runtime',
              {
                'absoluteRuntime': false,
                'corejs': 2,
                'helpers': true,
                'regenerator': true,
                'useESModules': false
              }
            ]
          ]
        }
      }

tree Shaking 详解

咱们日常灰白那些很多函数库,但是这些函数中的函数不是每一个都会在项目中用到,但是如果我们每一个函数都放在最想代码中间,这样就会影响网页的加载速度,如果我们能够在最后发布到生产环境中的那些不用的去除掉,这样就好了,tree shaking 就是是实现这个功能的

假设我有两个方法

// math.js
export const add = (a, b) => {
	console.log(a + b)
}
export const minus = (a, b) => {
    console.log(a - b)
}

导入这两个方法

import { add } from './math.js'
add(1, 2)

webpack打包的时候会注解某个文件最终导出的接口有哪些,并且会标注到底有些导出的被使用了

  optimization: {
    usedExports: true
  }

需要注意的是**开发环境下,为了保证能够给用户提示正确的错误代码行数位置信息等,即使增加了该选项依然不会进行削减

import '@babel/polyfill'
let arr = [1, 2, 3, 4];
let p = new Promise(() => {
  console.log('你好世界')
})

我们如果偏偏导入了polyfill 但这个polyfill的方法或者函数什么的都是直接定义在全局的,没啥东西导出,如果被tree shaking 解析的时候发现polyfill 里面啥也导出,可能就被忽略,所以我们要对这一个文件特殊标记,表示他被排除在tree shaking的检测之外

package.json 文件新增该配置

"sideEffects": false

sideEffects:就是之排除到tree Shaking系统之外的配置: false:默认值, 默认不排除任何情况

  "sideEffects": [
    "@babel/poly-fill",
    "*.css"
  ],

当使用了数组作为配置值得时候, 数据的每个项目都是一个匹配规则: 左侧第一个规则就是排除@babel/poly-fill模块 第二个规则就是排除所有导入的css文件

关于后期更新

其实webpack目前来说,会在下周进行更新完毕,包括内容会有一些代码分割,打包分析,打包优化,vue-cli 的配置讲解,整个webpack就会结束了 或许会更新两章HTTPHTTPS的知识,一章mock.js 知识,然后大致在月中就会开启微信小程序的学习了,敬请期待!