学习vue-cli文档的时候 初学的小伙伴对于 浏览器兼容性 的Polyfill
应该会有疑惑吧~~(是不是只有我呢?)~~
需要了解Polyfill
就得先来了解Babel
我们写项目搬轮子 在package.json
中看到很多开发依赖的包Babel-xxx
Babel
有什么用? 直白的说 我们写的ES/2015/2016/2017/20xx等JavaScript的代码语法
转成让运行环境(浏览器、node环境)能认识并执行 (只是语法的转换 而不改变原来的API)
现在大部分浏览器都覆盖了ES5的规范 所以说把这些代码语法转成ES5是比较稳妥的
我看不懂法语 用转译工具 给我换成中文 而这个转译工具 也可以理解成是Babel
babel
需要经过三个阶段: 解析、转换、生成,最终要呈现所转换后的代码 都是要通过里面配置好的插件
你可以试试不写任何插件转换,最终的代码是一模一样的
这里安装了转译插件
,在转换这一步把源码转换 在输出,比如我们常用的箭头函数 就是转成function
等
自己手动安装转译插件
不现实 因为es5的规范太多了
所以babel
提供了一些插件的集合预设preset
让开发者更好的使用
(这里顺口一提 vue-cli
也有自己的preset
理解的根本都是一样的)
集合的预设很多 我就只说常用的env
为什么是env
因为是根据我们设置目标的环境在做出对应的转换,只转换必要的
直接上一段代码理解
(以下的Babel语法按着7.x+版本)
presets: [
[
'@babel/preset-env',
{
targets: {
browsers: ["last 2 versions", "safari >= 7"]
}
}
],
'@babel/react'
]
如果某个预设有参数的 那么就是要写错一个数组形式 没有参数就直接字符串传入就可以
这里用到env
预设 7.x+写法需要 完整的@babel/preset-env
带的参数traget
浏览器兼容最新2个版本 和 safari浏览器版本要大于或者等于7的
那么env
预设就会根据这个目标去做出对应的转换
上文说得那么多 是因为要清楚Polyfill
的作用是什么
babel
只是转换语法 不会转换api 也就是说 有些方法不会被转译
也就是说 es5+的一些方法API 不会直接被转译 也没办法在现有的环境上运行
比如Array.from
等 所以就要用到@babel/polyfill
官方对于@babel/polyfill
的使用描述是
Babel includes a polyfill that includes a custom regenerator runtime and core-js. This will emulate a full ES2015+ environment (no < Stage 4 proposals) and is intended to be used in an application rather than a library/tool. (this polyfill is automatically loaded when using babel-node)
这里看到**@babel/polyfill** 用core-js/stable
和 regenerator-runtime/runtime
来直接实现
import 'core-js/stable'
import 'regenerator-runtime/runtime'
// 等同于
import "@babel/polyfill";
但是问题来了: 直接使用polyfill
会污染全局 打包的体积会很大很多很多
我只想按需使用 减少打包的体积 怎么办呢?
看看官方给的解释
When used alongside @babel/preset-env,
- If useBuiltIns: 'usage' is specified in .babelrc then do not include @babel/polyfill in either webpack.config.js entry array nor source. Note, @babel/polyfill still needs to be installed.
- If useBuiltIns: 'entry' is specified in .babelrc then include @babel/polyfill at the top of the entry point to your application via require or import as discussed above.
- If useBuiltIns key is not specified or it is explicitly set with useBuiltIns: false in your .babelrc, add @babel/polyfill directly to the entry array in your webpack.config.js.
可以通过设置useBuiltIns
参数 告诉babel
怎么样去配置@babel/polyfill
看看下面代码
presets: [
[
'@babel/preset-env',
{
targets: {
browsers: ["last 2 versions", "safari >= 7"]
},
useBuiltIns: 'entry',
corejs: 3
}
],
'@babel/react'
]
- corejs 是指定核心版本
- useBuiltIns 按需注入 有三个参数可选
- entry: 根据配置的浏览器兼容 去替换成不兼容的
polyfill
这里要在入口文件手动添加@babel/polyfill
注意 如果是corejs:3
那么要用'core-js/stable'
和'regenerator-runtime/runtime'
来替换引用 - usage: 不需要手动添加
@babel/polyfill
,会根据配置的浏览器兼容,全自动检测 - false: 不对
polyfill
做操作
- entry: 根据配置的浏览器兼容 去替换成不兼容的
好了 现在回到vue-cli
文档 对于useBuiltIns: 'usage'
就能更好的理解了
默认情况下,它会把 useBuiltIns: 'usage' 传递给 @babel/preset-env,这样它会根据源代码中出现的语言特性自动检测需要的 polyfill。这确保了最终包里 polyfill 数量的最小化
(完)