大家都知道js十分依赖浏览器(或Node环境),不同浏览器对js的支持不尽相同。现如今ECMAScrip标准的更新已经到了一年一次的节奏,
Babel 就是为了解决这个问题 ,它可以将使用新标准的JavaScript代码转换为浏览器支持可以运行的JavsScript(ES5)代码。
1 | //例如babel将这段代码 |
在webpack中配置Babel
假设在react项目配置webpack:
一、安装npm包:
1 | npm install --save-dev babel-loader babel-core babel-plugin-transform-runtime babel-preset-es2015 babel-preset-react webpack-preset-babel-stage-0 |
二、在webpack配置文件中添加规则:
1 | module: { |
三、 在项目根目录创建名为.babelrc
的文件,这是Babel的配置文件
在配置文件中安装插件(plugins)或预设(presets,也就是一组插件)来指示 Babel 去做什么事情。在下面配置中:
babel-preset-es2015 打包了 es6 的特性;
babel-preset-stage-0 打包处于 strawman 阶段的语法;
babel-preset-react 打包react全家桶语法;
Babel 几乎可以编译所有时新的 JavaScript 语法,但对于 APIs 来说却并非如此。例如: Promise、Set、Map 等新增对象,Object.assign、Object.entries等静态方法,babel-plugin-transform-runtime为了达成使用这些新API。
1 | //.babelrc内容 |
Babel模块
Babel6.0后将功能划分成了不同的模块,在 Babel packages 仓库看到babel现在有哪些模块:
babel-core
babel-core是作为babel的核心存在,babel的核心api都在这个模块里面。babel-core把 js 代码分析成 ast ,方便各个插件分析语法进行相应的处理。有些新语法在低版本 js 中是不存在的,如箭头函数,rest 参数,函数默认值等,这种语言层面的不兼容只能通过将代码转为 ast,分析其语法后再转为低版本 js。
1 | // npm install babel-core |
其中 options 可以配置多项内容,包括Plugin和Preset配置,SourceMap配置等
babel-cli
Babel 的 CLI 是一种在命令行下使用 Babel 编译文件的简单方法。
1 | //基本使用 (输出到控制台) |
假设script.js长如下这样,直接在命令行执行 babel script.js,发现输出的代码好像没有转译……
1 | //script.js |
这和前面一样需要 配置 presets 和 plugins 信息。
这时候有两种方式一种是和上文一样使用 .babelrc 配置文件
1 | //1. 转换 ES2015+ 的 env preset |
这时候可以使用了
1 | npx babel script.js |
另一种方式是直接在命令中指定presets
1 | //1. 转换 ES2015+ 的 env preset |
babel-runtime / babel-plugin-transform-runtime
Babel 几乎可以编译所有时新的 JavaScript 语法,但对于 APIs 来说却并非如此。例如: Promise、Set、Map 等新增对象,Object.assign、Object.entries等静态方法。
1 | //下列含有箭头函数的需要编译的代码: |
在实现新的API的基础上有两种方式: babel-polyfill和 babel-runtime + babel-plugin-transform-runtime。
这两者虽然都是模拟 es6 环境新增API,但实现方法完全不同。
babel-polyfill 的做法是将全局对象通通污染一遍,比如想在 node 0.10 上用 Promise,调用 babel-polyfill 就会往 global 对象挂上 Promise 对象。
babel-runtime 的做法是自己手动引入 helper 函数, const Promise = require(‘babel-runtime/core-js/promise’) 就可以引入 Promise。为了解决手动引入Helper函数的麻烦,babel 又开发了 babel-plugin-transform-runtime,这个模块会将我们的代码重写,如将 Promise 重写成 _Promise(只是打比方),然后引入_Promise helper 函数。这样就避免了重复打包代码和手动引入模块的痛苦。
@babel/standalone 在浏览器环境/web工程中运行babel
由于 Babel 本身的设计是基于 node.js 环境下运行使用的, 上面的例子都是在 Node.js环境中跑的,但是你头铁 一定要在浏览器环境中跑babel怎么办?
答案就是使用 @babel/standalone
参考 https://github.com/babel/babel/issues/5268 https://babeljs.io/docs/en/next/babel-standalone.html
1 | //npm i @babel/standalone @babel/core @babel/preset-react @babel/preset-env @babel/plugin-transform-runtime |
或者
1 | //npm i @babel/standalone |