browserslist
- package.json文件里的browserslint字段(或者一个单独的.browserslistrc 文件),指定了项目的目标浏览器范围。
- 这个值会被
@babel/preset-env
和Autoprefixer
用来确定需要转译的javascript特性和需要添加的CSS浏览器前缀。
- 这个值会被
Polyfill
useBuiltIns: 'usage'
一个默认的Vue CLI项目会使用
@vue/babel-preset-app
,它通过@babel/preset-env
和browserslist
配置来决定项目需要的polyfill。默认情况下,它会把
useBuiltIns: 'usage'
传递给@babel/preset-env
,这样它会根据源代码中出现的语言特性自动检测需要的polyfill
。这确保了最终包里 polyfill 数量的最小化。然而,这也意味着如果其中一个依赖需要特殊的polyfill
,默认情况下Babel
无法将其检测出来若有依赖需要polyfill,你有几种选择:
1.若该依赖基于一个目标环境不支持的ES版本撰写:将其添加到vue.config.js中的
transpileDependencies
选项。这会为该依赖同时开启转换和根据使用情况检查polyfill2.若该依赖交付了ES5代码并显式地列出了需要的polyfill:则需要使用
@vue/babel-preset-app
的 polyfills 选项预包含所需要的 polyfill。注意es.promise
将被默认包含,因为现在的库依赖 Promise 是非常普遍的.
// babel.config.js module.exports = { preset: [ ['@vue/app', { polyfills: [ 'es.promise', 'es.symbol' ] }] ] }
提示
我们推荐以这种方式添加 polyfill 而不是在源代码中直接导入它们,因为如果这里列出的 polyfill 在 browserslist 的目标中不需要,则它会被自动排除。
- 3.若该依赖交付ES5代码,单使用了ES6+特性没有显式地列出需要的polyfill:请使用
useBuiltIns: 'entry'
然后在入口文件添加import 'core-js/stable'; import 'regenerator-runtime/runtime';
。这会根据browserslist
目标导入所有 polyfill,这样你就不用再担心依赖的 polyfill 问题了,但是因为包含了一些没有用到的 polyfill 所以最终的包大小可能会增加。
构建库或是Web Component时的Polyfills
- 当使用Vue CLI来构建一个库或是Web Component时,推荐给
@vue/babel-preset-app
传入useBuiltIns: false
选项。这能确保你的库或是组件不包含不必要的polyfills。通常来说,打包 polyfills 应当是最终使用你的库的应用的责任
现代模式
Babel的存在,使得我们可以兼顾所有最新的ES2015+语言特性,也意味着我们需要交付转译和polyfill后的包以支持旧的浏览器。
Babel转译后的代码或包通常比原生的ES2015+代码更冗长,允许更慢。
Vue CLI提供了一个“现代模式”来解决这个问题。以下面命令为生产环境构建:
vue-cli-service build --modern
Vue CLI会产生2哥应用版本:
- 一个现代版本的包,面向支持
ES modules
的现代浏览器 另一个旧版的包,面向不支持的旧浏览器
- 一个现代版本的包,面向支持
最酷的是
这里没有特殊的部署要求。其生成的HTML文件会自动使用Phillp Walton
精彩博文中讨论的技术:- 现代版本的包会通过
<script type="module">
在被支持的浏览器中加载;它们还会使用<link rel="modulereload">
进行预加载。 - 旧版的包会通过
<script nomodule>
加载,并会被支持ES modules的浏览器忽略。 - 一个针对Safari 10中
<script nomodule>
的修复会被自动注入。
- 现代版本的包会通过
对于最简单的HelloWorld应用来说,现代版的包已经小了16%。在生成环境下,现代版的包通常都会表现出显著的解析速度和运算速度,从而改善应用的加载性能。