webpack系列学习十(JS模块处理)

204 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第18天,点击查看活动详情

JS模块处理:

  • vue
  • jsx
  • 如何编写自定义plugin
  • 了解plugin的流程

Babel

Babel是一个JavaScript编译器,能将ES6代码转换成ES5代码,让我们开发过程中放⼼使⽤JS新特性⽽不⽤担⼼兼容性问题。并且还可以通过插件机制根据需求灵活的扩展。

Babel在执⾏编译的过程中,会从项⽬根⽬录下的 .babelrc JSON⽂件中读取配置。没有该⽂件会从loader的options地⽅读取配置。

安装

npm install babel-loader @babel/core -D
npm install @babel/preset-env -D

babel-loader是webpack 与 babel的通信桥梁,不会做把es6转成es5的⼯作,这部分⼯作需要⽤到@babel/preset-env来做

示例

  • 配置目标浏览器集合.browserslistrc
last 2 versions
>1%
  • index.js
const arr = [new Promise(() => { }), new Promise(() => { })]
arr.map(item => {
  console.log(item);
})
  • 配置webpack.config.js
module: {
    rules: [
      {
        test: /\.js$/,
        use: {
          loader: "babel-loader",
          options: {
            presets: [
              "@babel/preset-env" // 做语法编译
            ]
          }
        }
      }
    ]
  },

使用babel前:

eval("const arr = [new Promise(() => {}), new Promise(() => {})];\narr.map(item => {\n  console.log(item);\n});\n\n//# sourceURL=webpack:///./src/index.js?");

使用babel后:

eval("var arr = [new Promise(function () {}), new Promise(function () {})];\narr.map(function (item) {\n  console.log(item);\n});\n\n//# sourceURL=webpack:///./src/index.js?");

这样处理之后,还是有一部分没有转化过来,在低版本的浏览器上面运行可能有些问题,这种时候可以采用 垫⽚原理 polyfill,把es的新特性都装进来,来弥补低版本浏览器中缺失的特性

@babel/polyfill

通过 Polyfill 方式在目标环境中添加缺失的特性 (通过引入第三方 polyfill 模块,例如 core-js

以全局变量的⽅式注⼊进来的。 windows.Promise,它会造成全局对象的污染

安装: npm install --save @babel/polyfill || npm install @babel/polyfill -S

因为polyfill是线上依赖,需要把这个代码打包到线上的版本,所以要把它安装到生产依赖中去

引入: 在入口模块的头部引入

//index.js 顶部
import "@babel/polyfill";

存在问题: 打包之后体积加大,这是因为polyfill默认会把所有特性注⼊进来

解决方案: 按需载入,减少冗余代码

  • 修改Webpack.config.js
{
    test: /\.js$/,
    use: {
      loader: "babel-loader",
      options: {
        presets: [
          // "@babel/preset-env" // 做语法编译
          [
            "@babel/preset-env",
            {
              // 目标浏览器集合
              targets: {
                edge: "17",
                firefox: "60",
                chrome: "67",
                safari: "11.1"
              },
              corejs: 2,//新版本需要指定核⼼库版本
              useBuiltIns: "usage"//按需注⼊
              // useBuiltIns: 设置babel如何配置babel/polyfill
              // entry: 需要在webpack的入口模块里 写上 import "@babel/polyfill",babel就会根据我们的代码情况,导入相应的垫片(特性代码),没有使用到的特性不会被导入
              // usage: 不需要在入口模块写上import代码,它是一个全自动检测的过程
              // false: 默认值,不会开启监测和识别,导致打包出来的文件特别大
              }
            ]
        ]
      }
    }
}

babelrc文件

新建.babelrc文件,把options部分移入到该文件中,就可以了

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "edge": "17",
          "firefox": "60",
          "chrome": "67",
          "safari": "11.1"
        },
        "corejs": 2,
        "useBuiltIns": "usage"
        }
      ]
  ]
}