webpack—使用 Babel 处理 ES6 语法(转成ES5)+ 实现对React框架代码的打包

@一棵菜菜  July 16, 2019

Babel: 下一代 JavaScript 语法的编译器

为什么要使用Babel?

我们用ES6的语法写了一个网页,谷歌浏览器比较支持ES6的语法,所以可以直接运行。但是其他浏览器(比如IE等)不支持ES6语法,则无法运行我们的代码。那如何解决呢?—— 使用Babel将ES6转ES5语法,则其他浏览器都可以识别了。

具体操作

1. 使用Babel将ES6转成ES5语法

webpack配置babel(选择webpack)

(1)babel-loader

babel-loader:架起连接webpack和babel的桥梁

下载:


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

webpack.config.js 配置Babel:

module: {
  rules: [
    // 对js文件进行babel-loader处理(将ES6语法转换成ES5)
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader"
      }
  ]
}
exclude [ɪk'sklʊd]:排除。意思为如果我们的js文件在node_modules文件夹下就不使用babel-loader进行处理。因为node_modules文件夹里的是第三方的代码,都是编译过的,所以我们也完全没有必要再去处理一遍。

(2)@babel/preset-env

**@babel/preset-env:支持将ES6语法转成ES5。

您已经配置了Babel,但是还没有让它实际执行任何操作,现在只是架起了连接webpack和babel的桥梁,还无法进行ES6转ES5。所以要借助env preset

下载:

// 能将ES6转ES5
npm install @babel/preset-env --save-dev

webpack.config.js 配置 options:

module: {
  rules: [
      // 对js文件进行babel-loader处理(使支持ES6语法)
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader", // 架桥梁
        options: {
          presets: [
            [
              "@babel/preset-env",// 将ES6语法转成ES5
              {
                // 低版本浏览器中只补充项目中使用到的ES6语法
                useBuiltIns: "usage" 
              }
            ]
          ]
        }
      }
  ]
}

现在在打包好的js中可以看到ES6编写的代码被转成ES5了。

2. 用@babel/polyfill使低版本浏览器也支持所有ES6的语法

官方文档《@babel/polyfill》

虽然做了语法翻译,但只是一部分。在低版本浏览器还是没有比如Promise、数组的map等。所以不仅要使用@babel/preset-env进行ES6转ES5,还要借助 @babel/polyfill把缺失的变量或者函数补充到低版本的浏览器里

这将模拟一个完整的ES2015+环境(即ES6)(没有< Stage 4提案),并将用于应用程序而不是库/工具。(使用babel-node时自动加载此polyfill)。
这意味着您可以使用新的内置函数,如Promise或WeakMap,静态方法如Array.from或 Object.assign,实例方法比如Array.prototype等。为了做到这一点,polyfill添加了全局范围和原生原型,比如String。

使用polyfill后,打包后的这个入口文件大小相比不使用时要大的多一些了(因为相当于配置了一个完整的ES6环境)。
如果只想补充代码中使用到的ES6语法,而不是把所有的一股脑全补充,那么建议对preset使用useBuiltIns: "usage"(如上方代码里)

下载:

npm install --save @babel/polyfill
注意:
因为这是一个polyfill(它将在您的源代码之前运行),所以我们需要它是一个依赖项,而不是devDependency。所以不应该用--save-dev

在入口js文件的顶部引入:(entry配置的js文件)

import "@babel/polyfill";

如果我们是写项目的业务逻辑,则使用"@babel/polyfill"即可。但如果我们写的是一个第三方库,则"@babel/polyfill"会污染全局污染。所以需要修改使用另外的处理方式【未完】


Webpack 实现对React框架代码的打包

拆分成.babelrc文件

options对象的内容可摘出来单独放到.babelrc文件中

module.exports = {
module:{
    rules:[
        {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader"
        // options:{} // options对象的内容可摘出来单独放到.babelrc文件中
      }
    ]
}
}

安装

// 安装react
cnpm install react react-dom --save

// 安装@babel/preset-react
npm install @babel/preset-react --save-dev

配置.babelrc

配置"@babel/preset-react"支持对react语法转换。

注意:babelrc文件里presets语法转换是有顺序的,从下往上,从右往左

即:先把react的jsx语法代码转换,再将ES6转换成ES5。

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "chrome": "67" // chrome浏览器版本大于67时就不做转换
        },
        "useBuiltIns": "usage" // 低版本浏览器中只补充项目中使用到的es6语法
      }
    ],
    "@babel/preset-react"
  ]
}

小结

  1. 使用Babel将ES6转ES5:
    babel-loader(架桥梁)
    @babel/preset-env(实际将ES6转ES5)
  2. 使低版本浏览器也支持所有ES6的语法:
    @babel/polyfill
    useBuiltIns: "usage"
  3. Webpack 实现对React框架代码的打包
    @babel/preset-react

module.exports = {
...
  module: {
    rules: [
      // 对js文件进行babel-loader处理(使支持ES6语法)
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader", // 架桥梁
        options: {
          presets: [
            [
              "@babel/preset-env",// 2. 将ES6语法转成 ES5
              {
                targets: {
                  chrome: "67", // chrome浏览器版本大于67时就不做转换
                },
                useBuiltIns: "usage", // 低版本浏览器中只补充项目中使用到的es6语法
              },
            ],
            "@babel/preset-react" // 1. 先把react 的jsx 转换成 React.createElement() 普通的js函数调用
          ],
        },
      },
    ],
  },
};

添加新评论