Babel

Babel是Web Developer工具集中的出色条目。 这是一个了不起的工具,已经存在了一段时间,但是如今几乎每个JavaScript开发人员都依赖它,并且这种情况将继续下去,因为Babel现在不可或缺,并且已经解决了每个人的大难题。

哪个问题?

每个Web开发人员肯定都有的问题:JavaScript的功能在最新版本的浏览器中可用,但在较早的版本中不可用。 也许Chrome或Firefox可以实现它,但Safari iOS和Edge却不能。

例如,ES6引入了箭头函数:

[1, 2, 3].map((n) => n + 1)

现在所有现代浏览器都支持该功能。 IE11不支持它,也不支持Opera Mini(我怎么知道?通过检查ES6兼容性表)。

那么您应该如何处理这个问题呢? 您应该继续前进,让那些使用较旧/不兼容浏览器的客户留下来,还是应该编写较旧的JavaScript代码使所有用户满意?

输入Babel。 Babel是一个编译器:它采用一种标准编写的代码,然后将其转换为另一种标准编写的代码。

您可以配置Babel将现代ES2017 JavaScript转换为JavaScript ES5语法:

[1, 2, 3].map(function(n) {
    return n + 1
})

这必须在构建时发生,因此您必须设置一个工作流程来为您处理。

Webpack是常见的解决方案。

(请注意,如果您对这些ES事情都感到困惑,请参阅ECMAScript指南中有关ES版本的更多信息)

一、安装Babel

使用npm可以很容易地在项目本地安装Babel:

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

过去,我建议在全局范围内安装babel-cli,但是现在Babel维护人员不建议这样做,因为通过在本地使用babel,您可以在每个项目中使用不同版本的Babel,而且在存储库中检入babel对于团队合作更有利

由于npm现在随npx一起提供,因此可以通过在项目文件夹中键入命令来运行本地安装的CLI软件包:

npx babel script.js

二、Babel配置示例

Babel开箱即用并没有做任何有用的事情,您需要对其进行配置并添加插件。

这是Babel插件的列表

为了解决我们在简介中讨论的问题(在每个浏览器中使用箭头功能),我们可以运行

npm install --save-dev @babel/plugin-transform-es2015-arrow-functions

将该包下载到我们应用程序的node_modules文件夹中,那么我们需要添加

{
    "plugins": ["transform-es2015-arrow-functions"]
}

到应用程序根文件夹中存在的.babelrc文件。 如果还没有该文件,则只需创建一个空白文件,然后将其内容放入其中。

提示:如果您从未见过点文件(以点开头的文件),乍一看可能很奇怪,因为该文件可能不会出现在文件管理器中,因为它是隐藏文件。

现在,如果我们有一个包含以下内容的script.js文件:

var a = () => {};
var a = (b) => b;
const double = [1,2,3].map((num) => num * 2);

console.log(double); // [2,4,6]

var bob = {
    _name: "Bob",
    _friends: ["Sally", "Tom"],
    printFriends() {
    this._friends.forEach(f =>
        console.log(this._name + " knows " + f));
    }
};

console.log(bob.printFriends());

运行babel script.js将输出以下代码:

var a = function () {};var a = function (b) {
        return b;
    };

const double = [1, 2, 3].map(function (num) {
        return num * 2;
    });console.log(double); // [2,4,6]

var bob = {
    _name: "Bob",
    _friends: ["Sally", "Tom"],
    printFriends() {
        var _this = this;
        this._friends.forEach(function (f) {
            return console.log(_this._name + " knows " + f);
        });
    }
};
console.log(bob.printFriends());

如您所见,箭头函数已全部转换为JavaScript ES5函数。

三、Babel预设

我们刚刚在上一篇文章中看到了如何配置Babel来转换特定的JavaScript函数。

您可以添加更多的插件,但是不能一一添加到配置功能中,这是不实际的。

这就是Babel提供预设的原因。

最受欢迎的预设是env和react。

提示:Babel 7已弃用(并删除了)每年的预设(例如preset-es2017和舞台预设)。 请改用@babel/preset-env。

env预设非常好:您告诉它要支持哪些环境,它确实为您提供所有功能,并支持所有现代JavaScript功能。

例如。 “支持每个浏览器的最后2个版本,但对于Safari,支持Safari 7之后的所有版本。

{
    "presets": [
        ["env", {
            "targets": {
                "browsers": ["last 2 versions", "safari >= 7"]
            }
        }]
    ]
}

或“不需要浏览器支持,只需使用Node.js 6.10”

{
    "presets": [
        ["env", {
            "targets": {
                "node": "6.10"
            }
        }]
    ]
}

在编写React应用程序时,react预设非常方便:添加预设preset-flow,syntaxjsx,transform-react-jsx,transform-react-display-name。

通过包含它,您已经准备好使用JSX转换和Flow支持来开发React应用程序。

有关预设的更多信息
https://babeljs.io/docs/plugins/

四、将Babel与Webpack一起使用

如果您想在浏览器中运行现代JavaScript,单凭Babel是不够的,您还需要bundle捆绑代码。 Webpack是实现此目的的完美工具。

提示:如果您不熟悉webpack,请阅读webpack指南

现代JS需要两个不同的阶段:编译阶段和运行时阶段。 这是因为某些ES6 +功能需要polyfill或runtime帮助程序。

要安装Babel polyfill和runtime助手,请运行

npm install @babel/polyfill @babel/runtime @babel/plugin-transform-runtime

现在在您的webpack.config.js文件中添加:

entry: [
    'babel-polyfill',
    // your app scripts should be here
],
module: {
    loaders: [
        // Babel loader compiles ES2015 into ES5 for
        // complete cross-browser support
        {
            loader: 'babel-loader',
            test: /\.js$/,
            // only include files present in the `src` subdirectory
            include: [path.resolve(__dirname, "src")],
            // exclude node_modules, equivalent to the above line
            exclude: /node_modules/,
            query: {
                // Use the default ES2015 preset
                // to include all ES2015 features
                presets: ['es2015'],
                plugins: ['transform-runtime']
            }
        }
    ]
}

通过将预设和插件信息保留在webpack.config.js文件中,我们可以避免使用.babelrc文件。

五、Babel 的缺陷

转码当然会损耗性能,如果追求极致性能,可排除。