You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
比如写react的同学比较熟悉的decorators目前就处于stage-2阶段,我们要用这些处于草案阶段的新属性,可以安装npm i -D @babel/preset-stage-2,然后在presets里写上stage-2,babel就会通过那些处于草案阶段的新属性的插件将我们代码中的用到的新属性转译成为es5
"use strict";function_classCallCheck(instance,Constructor){if(!(instanceinstanceofConstructor)){thrownewTypeError("Cannot call a class as a function");}}varPerson=functionPerson(){_classCallCheck(this,Person);};
在前端的发展过程中,javascript的兼容性,一直是前端头痛的问题,在以前的一些有些项目中,为解决浏览器兼容而花费的时间甚至还要多余实际的业务逻辑开发时间,babel就是其中处理兼容的转译工具(或者叫平台)。
babel是什么
javascript在不断发展,新的提案标准每年都会有,在得到广泛普及之前,Babel 把用最新标准编写的 JavaScript 代码向下编译成可以在今天随处可用的版本
babel的编译过程分为3步,解析(parse),转换(transform),生成(generate),对应的三个插件分别是
Babylon
、babel-traverse
、babel-generator
。babylon将源码转换为抽象语法树(AST);babel-traverse通过AST生成一个便于操作、转换的path对象,供我们的babel插件处理;babel-generator读取AST并将其转换为代码和源码映射。这些过程不是本文的关注点,我们关注的是结果,哪些插件与我们的生产息息相关,我们如何去使用babel的插件。
通过vue中的babel配置来了解babel
vue脚手架生成的项目在
.babelrc
文件中的配置:plugin配置项
babel插件推崇的是功能的单一性,就是每个插件的功能尽可能的单一,比如我要使用es6的箭头函数,那就可以装一个转换插件
npm i -D @babel/plugin-transform-arrow-functions
,将其写进.babelrc
文件里就行了:详情这样,我们写的:
会被该插件转换为:
这个插件也只解决箭头函数的转换,就算函数内部用了其它新语法也不管,这个好处是很明显的,就跟咱写项目推崇组件的细腻度一个道理
presets配置项
然而呢,js发展有点快,想一下那个es2015(es6)一下加了多少东西,我们要使用还得一个一个的
npm i -D xxx
,这个有点小麻烦,所以就可以采用presets
配置项。npm i -D babel-preset-es2015
,然后配置.babelrc
。详情这样我们就可以使用包括箭头函数在内的es6的新
语法
而不用去担心兼容问题。这下这两个的关系也就清晰了,presets
里面配置的是一些plugins
集合在
babel 7.3.0
里面,presets
--对应插件
有这些:@babel/preset-env
@babel/preset-stage-0
@babel/preset-stage-1
@babel/preset-stage-2
@babel/preset-stage-3
@babel/preset-flow
@babel/preset-react
babel-preset-minify
@babel/preset-typescript
env
在presets配置里面,我们看到了:
这个env是
@babel/preset-env
这个集合插件配置项,这里的配置项:modules
:"amd" | "umd" | "systemjs" | "commonjs" | "cjs" | "auto" | false, defaults to "auto".target
:就是告诉babel你的js要兼容哪些环境,它会帮你将你写的js转译成目标环境兼容的js语法,这个具体配置可以看browserslist那就是说,js无论用什么新玩意,
@babel/preset-env
都能跟我兼容到我想要的环境?带着问题,我们再看看官网的介绍,What is Babel:再看看通过env转换的几个demo:
比较明显,上面的都属于
转换语法
,所以应该说“js无论用什么新语法
,@babel/preset-env
都能帮你兼容到目标环境”。@babel/preset-env
具体可以帮我们转化哪些呢?看这儿JavaScript新特性和Babel插件的映射关系,这个是@babel/preset-env集合插件所包含的插件列表,每个插件对应转换一个新特性,至于没有的,比如promise、Array.from等,请往下看。stage-2
在上面的配置中,我们看到env下面有个stage-2。stage-x,这里面包含的都是当年最新规范的草案,每年更新。细分为如下几步
官网里有一句话
It is important to note that @babel/preset-env does not support stage-x plugins.
,就是说@babel/preset-env中不包含在草案阶段的新属性的转换插件比如写react的同学比较熟悉的decorators目前就处于stage-2阶段,我们要用这些处于草案阶段的新属性,可以安装
npm i -D @babel/preset-stage-2
,然后在presets里写上stage-2,babel就会通过那些处于草案阶段的新属性的插件将我们代码中的用到的新属性转译成为es5此外,低一级的 stage 会包含所有高级 stage 的内容,例如 stage-2 会包含 stage-2, stage-3 的所有内容。
babel-ployfill
Babel 几乎可以编译所有时新的 JavaScript 语法,但对于 APIs 来说却并非如此。比如说:
Promise
、WeakMap
、Array.from
、Object.assign
、Array.prototype.includes
、generator
等。为了解决这个问题,我们使用一种叫做 Polyfill(代码填充,也可译作兼容性补丁) 的技术。能让你提前使用还不可用的 APIs。引入它很简单,我们
npm i -S @babel/polyfill
,两者任选其一
上面这两种方式是将整个polyfill都引入了,很多代码其实对我们是没有用的,比如,我们的env配置的是不需要兼容ie9以下的浏览器,这种引入方式把所有兼容ie的代码都引入了,包含ie8以下,所以,一般我们会在
.babelrc
文件里的env里配置下useBuiltIns
参数,这样babel在引入的时候会根据我们env环境去加载相应的polyfill:详细有如下三种方式
@babel/plugin-transform-runtime
我们看到上面的配置中有个
transform-runtime
,这个是配置@babel/plugin-transform-runtime,它是做什么的呢?官网说:一个插件,通过重复使用babel注入的助手(helper)代码,来减少代码体积
,我们看看它是如何工作的。比如这个es6的class类:
在没有使用transform-runtime时,每个使用
class
函数处,Babel 会生成class
的helper函数放置在文件顶部,就是说在多个文件里使用了class
, babel就会在每个文件里面都生成相同的helper:这样不必要的重复会使我们的代码体积非常雍肿,transform-runtime就是来解决这个重复生成helper的问题的,它会将这个es6的
class
语法的helper
函数放在babel-runtime/helpers
里,然后在使用处通过require引入,这样就没必要在每个使用处重复定义helper
了,达到了减少代码体积的效果。@babel/runtime 对比 babel-polyfill
@babel/runtime和@babel/polyfill这两个模块功能几乎相同,就是转码新增 api
根据它们两的特点,@babel/polyfil一般用于前端项目,@babel/runtime一般用来写插件
几个常用的babel插件
babel-cil
Babel 的 CLI 是一种在命令行下使用 Babel 编译文件的简单方法。有时候我们只是写一个插件,需要用babel转一下我们代码中的高阶语法,因为项目可能不太大,用不到构建工具,就可以用babel-cil。转换依据我们的
.babelrc
文件或者package.json
中babel选项babel-loader
babel-loader是什么呢?前面说了,我们可以通过babel-cil在命令行里告诉babel转译哪些js,也可以通过babel-register,在代码里通过require来转,但是,现在前端开发是一个工程化过程,依赖关系比较复杂,在一个稍微大点儿的项目中还真没法手动告诉babel要处理哪些文件,比如一个
.vue
文件,里面还包含html、css,还有一些不是js的鬼语法,这时候就要借助其它插件先提前处理下,所以,webpack根据依赖关系,加载文件的时候遇到js文件后,会将文件内容的js字符串根据loader配置的先后顺序,挨个儿传递给它们处理,babel-loader就是其中之一总结
什么是babel
babel就是将目标环境(浏览器)通过打补丁升级成支持最新javascript语法的环境的工具。
用vue脚手架生成的项目,js怎么兼容到ie9
插件快照
参考:
The text was updated successfully, but these errors were encountered: