webpack-babelyarn init -ywebpackyarn add webpack webpack-cli -Dwebpack 插件yarn add -D html-webpack-plugin clean-webpack-pluginhtml-webpack-plugin 用于自动生成 index.htmlclean-webpack-plugin 用于每次打包时对上一次的 dist 文件进行清除,这两个插件跟 babel 没关系,只是这里用起来方便webpack-dev-server 用于启动一个 web 服务yarn add -D webpack-dev-serversrc 及入口文件 index.js,内容如下let ele = document.createElement("div")ele.innerHTML = "Hello world!"document.body.appendChild(ele)webpack 配置文件,内容如下const { CleanWebpackPlugin } = require('clean-webpack-plugin');const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = { entry: { index: "./src/index.js" }, devServer: { port: 9998 }, plugins: [ new CleanWebpackPlugin(), new HtmlWebpackPlugin({ title: '管理输出' }) ],}package.json 中增加脚本"scripts": { "serve": "webpack-dev-server --config webpack.config.js", "build": "webpack"}yarn serve
成了!举国欢庆 ~yarn build
此时目录结构(打包后)准备工作就绪之后,开始 babel 相关的部分
安装相关包
yarn add -D babel-loader @babel/core @babel/preset-envbabel-loader 允许你使用 Babel 和 webpack 转译 JavaScript 文件
@babel/core 用于转换新的语法
@babel/preset-env 用于配置哪些语法或者 API 需要转换
首先修改 index.js 内容
let a = 1;console.log(a);const fn = () => { };console.log(fn);这里使用了 ES6 的 let,和 箭头函数
使用 Can I use 查询语法支持情况,红色是不支持


IE11 上,这两种语法是都不支持的,实际运行的结果也是如此
报语法错误修改 webpack.config.js
module: { rules: [ { test: /\.m?js$/, exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { presets: [ [ '@babel/preset-env', { debug: true, targets: { browsers: ["ie >= 11"] } } ] ], } } } ]},再跑一次
yarn serve
没有再报错了webpack.config.js 的配置,将模式设置为 development,以便 yarn build 时看到的代码是未经压缩的。此外,关闭 sourcemap。mode: "development", // 强制公告为 development 模式devtool: "none" // 关闭 sourcemapyarn build
假如我们把条件换成支持这两种语法的浏览器呢?
webpack.config.js,chrome 60 版本已经支持 let 和 箭头函数,打包后代码 不应该 再被转换。browsers: ["chrome >= 60"]yarn build
此时并没有被转换补充一下,假如开启了
debug,即可以在终端查看相关代码转换信息开启 debug 后
换回之前的条件,继续调试
browsers: ["ie >= 11"]清空 index.js,将 index.js 的内容改为
const fn = async () => { let r = await Promise.resolve(666) console.log(r)}fn()运行 yarn serve 继续在 ie11 中查看
报错了从报错可以看到,需要引入 regenerator-runtime。可以通过以下三种方式处理:
方法1:引入 @babel/polyfill,注意是生产依赖
yarn add @babel/polyfill引入 @babel/polyfill 后,可以发现还引入了两个依赖, core-js 和 regenerator-runtime,然后者正是我们需要的

补充一下
@babel/core,core-js和regenerator-runtime的作用
| 名称 | 作用 |
|---|---|
| @babel/core | 解决新语法,比方 模板字符串,let,const,扩展运算符 等 |
| core-js | 解决新 API,比方 Promise,Set,Map,Object.assign 等 |
| regenerator-runtime | 解决 async,await,generator 等 |
以上内容可在开启 debug 后,在终端查看日志

在 index.js 中引入 @babel/polyfill,注意,是在所有代码最上面引入
import "@babel/polyfill"运行
yarn serve
成功运行打包看一下
yarn build一万多行。。
dist/index.jsasync,但是引入的是完整的 @babel/polyfill,等于把好多不用的 API 都引了进来,查看打包后的文件,可以看到
includes,values 等方法都被引入useBuiltIns 配置项了presets: [ [ '@babel/preset-env', { debug: true, targets: { browsers: ["ie >= 11"] }, useBuiltIns: "usage" // 看这里 } ] ]再次打包,剩下 2000 多行,只保留了解决 async 的部分

@babel/preset-env 的 useBuiltIns
| 值 | 作用 | 能否需要在入口文件引入 @babel/polyfill |
|---|---|---|
| false | 默认值,无脑引入完整的 polyfill | 是 |
| entry | 引入 targets 中指定的浏览器版本所需的一律 polyfill | 是 |
| usage | 引入代码中用到的并且是 targets 中指定的浏览器版本所需的 polyfill | 否(安装还是需要安的,就是不需要在入口引入了) |
以上可以通过开启 debug 在控制台中查看
当配置为 entry 时
当配置为 usage 时方法二:
首先移除 @babel/polyfill
yarn remove @babel/polyfill安装@babel/plugin-transform-runtime,@babel/runtime
yarn add -D @babel/plugin-transform-runtimeyarn add @babel/runtime安装 @babel/runtime 时可以发现只有 regenerator-runtime,没有 core-js,这就意味着 Promise,assign 不会被转译

webpack.config.js 中 babel-loader 的部分配置plugins: [ [ "@babel/plugin-transform-runtime" ]]运行一下

core-js 导致部 Promise,assign 不能被支持。假如希望被支持,则还需安装 @babel/polyfill方法三:
先移除 @babel/runtime 再安装 @babel/runtime-corejs2
yarn remove @babel/runtimeyarn add @babel/runtime-corejs2
webpack.config.js 中 babel-loader 配置项module: { rules: [ { test: /\.m?js$/, exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { presets: [ [ '@babel/preset-env', { debug: true, targets: { browsers: ["ie >= 11"] // browsers: ["chrome >= 60"] }, useBuiltIns: "usage" } ] ], plugins: [ [ "@babel/plugin-transform-runtime", { "corejs": 2, } ] ] } } } ]}修改后,再次运行项目,又恢复了正常 Promise,async,Object.assign 均可以跑在 IE11 上了

@babel/polyfill 的方式和引入 @babel/plugin-transform-runtime + @babel/runtime-corejs2 的方式区别在于,前者会污染全局变量。@babel/polyfill 的方式,在 IE11 控制台输入 Promise 会正常打印,而使用后面的方式,在 IE11 控制台中输入 Promise 则会提醒未定义
@babel/polyfill
@babel/plugin-transform-runtime + @babel/runtime-corejs2