写在前面
日常通常使用脚手架工具开发,但是有很多情况会希望自己配置一些东西,而网上各种配置都没有整明白个所以然,所以痛定思痛决定写一篇一步一步的教你的Babel教程,也就是本文。这里每一个字都是我一点点输入并试验的。如果有不对的地方,请指出~
初始化安装
mkdir learn_babel && cd learn_babel
npm init -y
mkdir src && cd src && touch app.js
npm install --save-dev @babel/core @babel/cli
编测试代码
const abc = () => {
console.log(`this is abc`);
}
** 这行代码里面包含了 const
、 箭头函数 、模版字符串三个es6
的高级语法
接下来运行 npx babel src/app.js
,你会发现babel
并没有帮我们做转换呀~,默认情况下babel
不会帮我们做任何事情,我们需要安装一系列插件模块,来针对不同的高级语法特性做支持。
learn_babel git:(master) ✗ npx babel src/app.js
const abc = () => {
console.log(`this is abc`);
};
安装插件
上面说到我们使用了三个高级语法,好吧,那我们依次安装三个插件试试。
npm install --save-dev @babel/plugin-transform-block-scoping @babel/plugin-transform-template-literals @babel/plugin-transform-arrow-functions
然后再次执行 npx babel src/app.js
你会发现还是没有变化,这个时候你需要配置一下,让上面三个插件生效。
在根目录下创建一个.babelrc
文件,然后再次运行编译,你会惊奇发现代码都变成你想要的那种了
{
"presets": [],
"plugins": [
"@babel/plugin-transform-arrow-functions",
"@babel/plugin-transform-template-literals",
"@babel/plugin-transform-block-scoping"
]
}
预设
上面看似已经达到了目的,但是啊但是,简单的几行代码,就需要安装这么多插件来支持,试想一下ES6+新特性那么多,如果一个个安装那是不是要累死了。是的,babel
为我们提供了一个超值套餐,就好比你去移动办理业务,如果一个个的办理耗时又费力,还不如直接上个套餐来的爽呀~
npm install --save-dev @babel/preset-env
更改.babelrc
配置文件如下:
{
"presets": ["@babel/preset-env"],
"plugins": []
}
现在套餐给你准备好了,但是有时候你可能根据自己的实际情况来做一些额外的配置,这样就能避免一些无用的编译损耗性能了,比如你就只需要支持谷歌浏览器,那么就可以完全不需要转换ie低版本那些无用功。所以@babel/preset-env
能指定浏览器支持配置。你可以在根目录再创建一个.browserslistrc
来配置你的浏览器支持:
defaults
not IE 11
maintained node versions
然后执行 npx browserslist
,你会发现不支持ie11,再次运行npx babel src/app.js
你就发现了,他不会编译了,因为ie外的其他高版本浏览器都支持这个基本语法了。如果你希望支持ie,你可以把配置改成:
defaults
ie > 10
maintained node versions
再次执行上述命令,你会发现他给你编译成了低版本语法。
垫片 or 补丁
上面已经解决了关于高级语法转低级的问题,但是ES6+不光是增加了一些语法,它还增加了很多高级api,例如:Array.prototype.includes
,改一下src/app.js
的代码:
const arr = [1,2,3,4,5];
console.log(arr.includes(1));
然后再次执行编译,你发现 const
被编译了,但是includes
原样输出,这样一来在ie浏览器还是无法运行。此时就需要一个垫片来帮助我们兼容这些浏览器自身不支持的高级api扩展。这个包实际上是core-js
®enerator-runtime/runtime
的结合。
npm install --save @babel/polyfill
然后再更改一些src/app.js
代码,
import "@babel/polyfill";
const arr = [1,2,3,4,5];
console.log(arr.includes(1));
再执行编译,虽然目前来说 import
语法并没有被完全转换成一些你期望的函数定义,但是它却被转换成如下代码
"use strict";
require("@babel/polyfill");
var arr = [1, 2, 3, 4, 5];
console.log(arr.includes(1));
这又是为什么呢?因为babel
默认只做代码转换,它可不会帮你做模块打包,所以如果你想看到结果的话,那么你可能需要使用rollup
或者webpack
来结合babel
做模块打包。我之前有写过一个关于rollup
的简单示例:
记录一下rollup结合babel做代码打包
当然,上面的配置可能会一股脑将所有垫片都导入进来,那么我们可以通过改一下.babelrc
配置,实现按需加载:
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": 2
}
]
],
"plugins": []
}
这样再编译,你会发现require
的不再是@babel/polyfill
全部,而是core-js/modules/es7.array.includes.js
transform-runtime & runtime
上面由于看不到打包后的结果,这里先说明一下,实际上垫片会直接更改一些内置对象的原型,这样在某些时候好像也没有什么问题,但是如果是开发一些类库文件,直接修改对象原型,肯定不好,因为将来别人使用你的类库也会修改了用户的对象原型,污染了全局。所以我们希望是以一种私有的方式来定义这些高级api.
npm install --save-dev @babel/plugin-transform-runtime
npm install --save @babel/runtime
然后修改.babelrc
配置
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": 3
}
]
],
"plugins": [
"@babel/plugin-transform-runtime"
]
}
然后修改 src/app.js
class Person {
constructor(name){
this.name = name
}
}
let p = new Person('tom')
let arr = [1,2,3];
console.log(arr.includes(1));
你可以对比一下不配置 @babel/plugin-transform-runtime
来看一下编译的过程
- 不配置的情况
"use strict";
require("core-js/modules/es7.array.includes.js");
require("core-js/modules/es6.function.name.js");
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Person = function Person(name) {
_classCallCheck(this, Person);
this.name = name;
};
var p = new Person('tom');
var arr = [1, 2, 3];
console.log(arr.includes(1));
- 配置的情况
"use strict";
var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");
var _includes = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/includes"));
require("core-js/modules/es6.function.name.js");
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/classCallCheck"));
var Person = function Person(name) {
(0, _classCallCheck2.default)(this, Person);
this.name = name;
};
var p = new Person('tom');
var arr = [1, 2, 3];
console.log((0, _includes.default)(arr).call(arr, 1));
你会发现 _classCallCheck
和 _classCallCheck2
一个是直接生成,一个是从runtime导入的;而配置runtime
后也生成了一个_includes
函数,而不是直接使用 core-js/modules/es7.array.includes.js
,由此可见已经解决了我们的一系列问题了。
最后
babel
的一系列教程就这么多,当然你有兴趣也可以看一些关于打包工具结合babel
来构建开发环境的资料,比如我上面自己写的关于rollup
的.最后,如果有什么不对,请大家指出!代码地址我放到这里了:
gitee.com/hellohere/l…
参考
Babel官网
browserslist
记录一下rollup结合babel做代码打包
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!