webpack—使用 Babel 处理 ES6 语法(转成ES5)

8,512 阅读3分钟

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"会污染全局污染。所以需要修改使用另外的处理方式。

这里我们就要使用到babel7的新功能,useBuiltIns,它有三个参数可选:

//需要在 webpack 的⼊⼝⽂件⾥ import "@babel/polyfill" ⼀次。 babel
会根据你的使⽤情况导⼊垫⽚,没有使⽤的功能不会被导⼊相应的垫⽚
useBuiltIns: "entry",  
// 按需注⼊,不需要 import ,全⾃动检测,但是要安装 @babel/polyfill 
useBuiltIns: "usage",  
 //如果你 import "@babel/polyfill" ,它不会排除掉没有使⽤的垫⽚,程序体积会庞⼤。(不推荐)
useBuiltIns: "false" 
复制代码

那么这个特性要怎么配置呢,有以下两种方式:

// 第一种:在webpack.config.js中配置
options: {
    presets: [
        [
            "@babel/preset-env",
            {
                targets: {
                    edge: "17",
                    firefox: "60",
                    chrome: "67",
                    safari: "11.1"
                },
            corejs: 2,//新版本需要指定核⼼库版本
            useBuiltIns: "usage"//按需注⼊
            }
        ]
    ]
}
复制代码
// 第二种: 新建.babelrc⽂件,把options部分移⼊到该⽂件中
{
    presets: [
        [
            "@babel/preset-env",
            {
                targets: {
                    edge: "17",
                    firefox: "60",
                    chrome: "67",
                    safari: "11.1"
                },
                corejs: 2, //新版本需要指定核⼼库版本
                useBuiltIns: "usage" //按需注⼊
            }
        ]
    ]
}
复制代码

注意:这里有个需要注意的问题是如果你使用了比较高版本的,比如es11这种特性,就需要使用corejs 3.x的版本了,他会比2多一些新特性。


参考文档: