⚠️ Vue CLI 处于维护模式!

对于新项目,现在建议使用 create-vue 来搭建基于 Vite 的项目。还可以参考 Vue 3 工具指南 获取最新的建议。

浏览器兼容性

browserslist

您会在 package.json(或单独的 .browserslistrc 文件)中注意到一个 browserslist 字段,它指定了项目所针对的浏览器范围。此值将被 @babel/preset-envautoprefixer 用于自动确定需要转译的 JavaScript 功能和所需的 CSS 供应商前缀。

请参阅 此处,了解如何指定浏览器范围。

Polyfills

默认的 Vue CLI 项目使用 @vue/babel-preset-app,它使用 @babel/preset-envbrowserslist 配置来确定项目所需的 Polyfills。

useBuiltIns: 'usage'

默认情况下,它将 useBuiltIns: 'usage' 传递给 @babel/preset-env,它会根据源代码中使用的语言功能自动检测所需的 polyfills。这确保了最终捆绑包中只包含最少的 polyfills。但是,这也意味着 **如果您的某个依赖项对 polyfills 有特定要求,默认情况下 Babel 将无法检测到它。**

如果您的某个依赖项需要 polyfills,您有以下几种选择

  1. **如果依赖项是用您的目标环境不支持的 ES 版本编写的:** 将该依赖项添加到 vue.config.js 中的 transpileDependencies 选项中。这将为该依赖项启用语法转换和基于用法的 polyfill 检测。

  2. **如果依赖项提供 ES5 代码并明确列出所需的 polyfills:** 您可以使用 polyfills 选项为 @vue/babel-preset-app 预先包含所需的 polyfills。**请注意,es.promise 默认包含在内,因为它非常常见,库依赖于 Promises。**

    // babel.config.js
    module.exports = {
      presets: [
        ['@vue/app', {
          polyfills: [
            'es.promise',
            'es.symbol'
          ]
        }]
      ]
    }
    

    提示

    建议以这种方式添加 polyfills,而不是直接在源代码中导入它们,因为如果您的 browserslist 目标不需要这些 polyfills,这里列出的 polyfills 可以自动排除。

  3. **如果依赖项提供 ES5 代码,但使用 ES6+ 功能而没有明确列出 polyfill 要求(例如 Vuetify):** 使用 useBuiltIns: 'entry',然后将 import 'core-js/stable'; import 'regenerator-runtime/runtime'; 添加到您的入口文件。这将根据您的 browserslist 目标导入 **所有** polyfills,这样您就不必再担心依赖项的 polyfills 了,但可能会增加最终捆绑包的大小,其中包含一些未使用的 polyfills。

请参阅 @babel/preset-env 文档,了解更多详细信息。

构建库或 Web 组件时的 Polyfills

当使用 Vue CLI 构建库或 Web 组件 时,建议将 useBuiltIns: false 传递给 @vue/babel-preset-app,以禁用自动 polyfill 注入。这确保了您不会在代码中包含不必要的 polyfills,因为这应该是使用应用程序的责任来包含 polyfills。

现代模式

借助 Babel,我们能够利用 ES2015+ 中的所有最新语言功能,但这同时也意味着我们必须提供转译和 polyfill 的捆绑包,以支持旧版浏览器。这些转译后的捆绑包通常比原始的原生 ES2015+ 代码更冗长,解析和运行速度也更慢。鉴于今天大多数现代浏览器对原生 ES2015 的支持都很好,我们必须为这些浏览器提供更重、效率更低的代码,仅仅因为我们必须支持旧版浏览器,这是一种浪费。

Vue CLI 提供了“现代模式”来帮助您解决这个问题。当使用以下命令构建生产环境时

vue-cli-service build --modern

Vue CLI 将生成您的应用程序的两个版本:一个现代捆绑包,针对支持 ES 模块 的现代浏览器,以及一个传统捆绑包,针对不支持 ES 模块的旧版浏览器。

不过,最棒的是,没有特殊的部署要求。生成的 HTML 文件会自动采用 Phillip Walton 的优秀文章 中讨论的技术。

  • 现代捆绑包使用 <script type="module"> 加载,在支持它的浏览器中;它们还使用 <link rel="modulepreload"> 预加载。

  • 传统捆绑包使用 <script nomodule> 加载,它会被支持 ES 模块的浏览器忽略。

  • 还会自动注入 Safari 10 中 <script nomodule> 的修复程序。

对于 Hello World 应用程序,现代捆绑包已经缩小了 16%。在生产环境中,现代捆绑包通常会导致更快的解析和评估,从而提高应用程序的加载性能。

提示

<script type="module">始终启用 CORS 加载的。这意味着您的服务器必须返回有效的 CORS 标头,例如 Access-Control-Allow-Origin: *。如果您想使用凭据获取脚本,请将 crossorigin 选项设置为 use-credentials

在配置中检测当前模式

有时您可能需要仅针对传统构建或仅针对现代构建更改 webpack 配置。

Vue CLI 使用两个环境变量来传达这一点

  • VUE_CLI_MODERN_MODE:构建是使用 --modern 标志启动的
  • VUE_CLI_MODERN_BUILD:如果为 true,则当前配置用于现代构建。否则,它用于传统构建。

**重要:** 这些变量仅在 chainWebpack()configureWebpack() 函数评估时/之后才能访问(因此不在 vue.config.js 模块的根作用域中)。这意味着它也可以在 postcss 配置文件中使用。

注意事项:调整 webpack 插件

一些插件,例如 html-webpack-pluginpreload-plugin 等,仅在现代模式的配置中包含。尝试在传统配置中访问它们的选项可能会抛出错误,因为这些插件不存在。

使用上面关于“检测当前模式”的提示,仅在正确的模式下操作插件,或者在尝试访问它们的选项之前检查插件是否确实存在于当前模式的配置中。