Babel使用入门,这篇真的讲得很简单

179 阅读4分钟

调试方式

在学习babel的过程中,我们常常要查看源文件和babel转换后的文件,我们可以通过以下方式调试

  • 方式一: @babel/cli,通过命令行来编译文件,具体用法

www.babeljs.cn/docs/babel-…

npx babel index.js --watch -o output.js

@babel/preset-env

作用

将高级语法转换成为低级语法,如箭头函数、模板字符串、const\let等等

编译前:

export const fnB = () => {
    console.log('fnB');
}

编译后:

var fnB = function fnB() {
  console.log('fnB');
};

exports.fnB = fnB;

使用

npm i @babel/preset-env

.babalrc

{
    "presets": ["@babel/preset-env"]
}

@babel/preset-react

作用

jsx最终编译为如React.createElement() 方法

编译前

export const CompA = () => {
    return <>Here is the CompA</>;
}

编译后

export const CompA = () => {
  return /*#__PURE__*/React.createElement(React.Fragment, null, "Here is the CompA");
};

使用

npm i @babel/preset-react

.babelrc

{
    "presets": ["@babel/preset-react"]
}

@babel/preset-typescript

作用

typescript语法转换为javascript

编译前

interface User {
    name: string;
    age: number;
    likes: string[],
};



const user1: User = {
    name: 'Happy',
    age: 12,
    likes: ['apple']
}

编译后

"use strict";



const user1 = {
  name: 'Happy',
  age: 12,
  likes: ['apple']
};

使用

npm i @babel/preset-typescript

.babelrc

{
    "presets": ["@babel/preset-typescript"]
}

polyfill

作用

用来转换ES最新API、静态方法等,如String.includes、Promise、Array.from...

@babel/preset-env默认配置只能转换最新的ES语法,但是像一些和浏览器兼容相关的一些api或者静态方法等等还需要我们去配置polyfill~

编译前

const test = 'test'.includes('t');

编译后

// 如果不使用polyfill

const test = 'test'.includes('t');
// 如果使用polyfill

require("core-js/modules/es6.string.includes.js");

var test = 'test'.includes('t');

其中core-js是JavaScript的模块化标准库,包括了ECMAScript到最近的新api的向后兼容实现

使用

在这里,我们要注意的是polyfill的引入需要配合 @babal/preset-env来完成,需要配置useBuiltIns这个配置项来控制polyfill的引入方式

全局引入polyfill

// index.js
import 'core-js/stable';
import 'regenerator-runtime/runtime';

.babelrc

{
    "presets": [
        [
            "@babel/preset-env",
            {
                "targets": {
                   "chrome": "70",
                   "ie": "11"
                 },
                 "corejs": "3",
                 "useBuiltIns": "entry"
            }
        ]
    ]
}

※注意

@babel/polyfill在Babel7.4.0后,被拆成了两个包,分别是

  • core-js/stable
  • regenerator-runtime/runtime

不要再像这样引入polyfill了:

import '@babel/polyfill';

关于这个变化的更多描述:@babel/polyfill · Babel

按需引入polyfill

.babelrc

{
    "presets": [
        [
            "@babel/preset-env",
            {
                "targets": {
                    "chrome": "70",
                    "ie": "11"
                  },
                  "corejs": "3",
                  "useBuiltIns": "usage"
            }
        ]
    ]
}

注意

在使用@babel/polyfill的时候,它可能会提示

WARNING (@babel/preset-env): We noticed you're using the `useBuiltIns` option without declaring a core-js version. Currently, we assume version 2.x when no version is passed. Since this default version will likely change in future versions of Babel, we recommend explicitly setting the core-js version you are using via the `corejs` option.
You should also be sure that the version you pass to the `corejs` option matches the version specified in your `package.json`'s `dependencies` section. If it doesn't, you need to run one of the following commands:

  npm install --save core-js@2    npm install --save core-js@3
  yarn add core-js@2              yarn add core-js@3

More info about useBuiltIns: https://babeljs.io/docs/en/babel-preset-env#usebuiltins
More info about core-js: https://babeljs.io/docs/en/babel-preset-env#corejs

意思:在使用useBuiltIns这个选项的时候没有声明corejs版本,需要在.babelrc中去配置corejs

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

runtime

在使用 @babel/preset-env提供的语法转换api添加的功能时,会造成文件的体积增加以及api的全局污染。为了解决这类问题,引入了runtime的概念,runtime的核心思想是以引入替换的方式来解决兼容性问题。

作用

使用 @babel/plugin-transform-runtime,它可以做到:

  • 转换ES最新API、静态方法等,如String.includes、Promise、Array.from...

  • 避免重复打包使用的辅助函数

  • 解决api的全局污染

我有a.js和b.js,现在,我把这两个文件都打包了,我们来看看使用@babel/plugin-transform-runtime和不使用它的区别:

不使用@babel/plugin-transform-runtime

编译前

// a.js
class A {}

// b.js
class B {}

编译后

output/a.js

output/b.js

不难发现,里面有很多_defineProperties、_defineProperties、_createClass这些函数,这些并且这些函数都被重复打包进文件中,但是这些函数是preset-env在转换时注入的函数声明,在转换语法的时候需要用到,但对于这些函数,我们全局只需要打包一次就够了,因此我们需要用到 @babel/plugin-transform-runtime 这个包

使用@babel/plugin-transform-runtime

编译前

// a.js
class A {}

// b.js
class B {}

编译后

output/a.js

output/b.js

我们可以看到之前的辅助函数已经变成了引入的形式

使用

npm i @babel/plugin-transform-runtime

注意:@babel/plugin-transform-runtime虽然依赖于@babel/runtime,但是我们不需要额外安装@babel/runtime这个包,因为安装@babel/preset-env的时候,已经配套安装了

.babelrc

{
    "presets": [ "@babel/preset-env"],
    "plugins": [
        [
            "@babel/plugin-transform-runtime",
            {
                "corejs": 3
            }
        ]
    ]
}

官方文档&Demo

非常推荐查阅官方文档,了解最新资讯:

babeljs.io/docs/en/

文中的demo:

github.com/DAHUIAAAAA/…