browserslist


  • package.json文件里的browserslint字段(或者一个单独的.browserslistrc 文件),指定了项目的目标浏览器范围。
    • 这个值会被@babel/preset-envAutoprefixer用来确定需要转译的javascript特性和需要添加的CSS浏览器前缀。

Polyfill


useBuiltIns: 'usage'

  • 一个默认的Vue CLI项目会使用@vue/babel-preset-app,它通过@babel/preset-envbrowserslist配置来决定项目需要的polyfill。

  • 默认情况下,它会把 useBuiltIns: 'usage' 传递给 @babel/preset-env,这样它会根据源代码中出现的语言特性自动检测需要的 polyfill。这确保了最终包里 polyfill 数量的最小化。然而,这也意味着如果其中一个依赖需要特殊的 polyfill,默认情况下 Babel 无法将其检测出来

  • 若有依赖需要polyfill,你有几种选择:

    • 1.若该依赖基于一个目标环境不支持的ES版本撰写:将其添加到vue.config.js中的transpileDependencies选项。这会为该依赖同时开启转换和根据使用情况检查polyfill

    • 2.若该依赖交付了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%。在生成环境下,现代版的包通常都会表现出显著的解析速度和运算速度,从而改善应用的加载性能。