Skip to content

webpack 之 babel 使用

babel 前端开发环境必备工具

环境搭建 & 基本配置

  • 环境搭建
  • .babelrc 配置 presets 和 pluins

1、环境配置文件 package.json

js
{
  "name": "09-babel-demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/cli": "^7.7.5",
    "@babel/core": "^7.7.5",
    "@babel/plugin-transform-runtime": "^7.7.5",
    "@babel/preset-env": "^7.7.5"
  },
  "dependencies": {
    "@babel/polyfill": "^7.7.0",
    "@babel/runtime": "^7.7.5"
  }
}

babel 配置文件 .babelrc

  • presets - 可以作为 Babel 插件的组合
  • pluins
js
{
    "presets": [
        [
            "@babel/preset-env",
            {
                "useBuiltIns": "usage",
                "corejs": 3
            }
        ]
    ],
    "plugins": [
        [
            "@babel/plugin-transform-runtime",
            {
                "absoluteRuntime": false,
                "corejs": 3,
                "helpers": true,
                "regenerator": true,
                "useESModules": false
            }
        ]
    ]
}

测试 index.js 中的 ES6 代码

js
const sum = (a, b) => a + b;

执行命令 npx babel src/index.js,输出 ES5 语法

js
var sum = function sum(a, b) {
  return a + b;
};

2、babel-polyfill

1)polyfill 意为补丁,比如

js
if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function (Object, max, min) {};
}

通过这种方式实现 polyfill

2)core-js 和 regenerator

core-js 是 ES6+ 转 ES5 标准版,github 地址:https://github.com/zloirock/core-js,但 core-js 无法满足 ES6 中 generator,如

js
// ES6 generator 函数(处理异步),被 async/await 代替
function* tell() {
  console.log('执行 a 处理');
  yield 'a';
  console.log('执行 b 处理');
  yield 'b';
  console.log('执行 c 处理');
  yield 'c';
}
let k = tell();
console.log(k.next());
console.log(k.next());
console.log(k.next());
console.log(k.next());

所以还需要 regenerator 的支持,github 地址:https://github.com/facebook/regenerator

3) babel-polyfill 即是 core-js 和 regenerator 的集合

  • Babel 7.4 之后弃用 babel-polyfill
  • 推荐直接使用 core-js 和 regenerator,但是 babel-polyfill 还是很多人用

babel 只将 ES6+ 语法转 ES5 语法,但不能处理新的 API (新的 API 语法符合 ES5 规范,但浏览器是否兼容,babel 不关心),所以在代码中引入 babel-polyfill

js
import '@babel/polyfill';
// 新的 API
Promise.resolve(100).then((data) => data);
// 新的 API
[10, 20, 30].includes(20);

以上被解析为

require('@babel/polyfill')

// 新的 API

Promise.resolve(100).then(data => data);

// 新的 API

[10, 20, 30].includes(20)

babel 把 import 引入的解析为 require 的模块化,但 babel 不处理模块化,所以还是需要 webpack 配合,然而 babel-polyfill 文件较大,所以应配置 .babelrc 按需引入

注,import '@babel/polyfill' 就不需要手动引入了

js
{
    "presets": [
        [
            "@babel/preset-env",
            {
                "useBuiltIns": "usage",
                "corejs": 3
            }
        ]
    ],
}

3、babel-runtime

babel-polyfill 的问题

js
// 污染全局环境
window.Promise = function () {};
Array.prototype.includes = function () {};
// 使用方
window.Promise = 'abc';
Array.prototype.includes = 100;
  • 污染全局环境
  • 做独立的 web 系统没关系;如果做第三方 lib 就会有问题

那怎么解决勒,可以换一个名字,如

js
window.Promise2 = function () {};
Array.prototype.includes2 = function () {};

使用 babel-runtime 就是解决污染环境问题,安装 @babel/plugin-transform-runtime 和 @babel/runtime,参考最上的 package.json 文件,然后默认配置 .babelrc 即可

js
{
    "plugins": [
        [
            "@babel/plugin-transform-runtime",
            {
                "absoluteRuntime": false,
                "corejs": 3,
                "helpers": true,
                "regenerator": true,
                "useESModules": false
            }
        ]
    ]
}

执行命令 npx babel src/index.js 查看

js
'use strict';
var _interopRequireDefault = require('@babel/runtime-corejs3/helpers/interopRequireDefault');
require('core-js/modules/es.object.to-string.js');
require('core-js/modules/es.promise.js');
var _includes = _interopRequireDefault(
  require('@babel/runtime-corejs3/core-js-stable/instance/includes'),
);
var _promise = _interopRequireDefault(
  require('@babel/runtime-corejs3/core-js-stable/promise'),
);
var _context;
var sum = function sum(a, b) {
  return a + b;
}; // 新的 API
_promise['default'].resolve(100).then(function (data) {
  return data;
}); // 新的 API
(0, _includes['default'])((_context = [10, 20, 30])).call(_context, 20);

以上解析后,不会污染全局环境

基于 MIT 许可发布