日常工作中 @vue/cli 需要关注的一些配置

为了让人容易理解,且不踩坑,官方文档会写的很详细

我们在熟练使用之后,需要提炼属于自己的知识点和关注点,总结以便后续快速查阅

官网文档地址https://cli.vuejs.org/zh/guide/

一、介绍

注意最新版是 @vue/cli 不是 vue-cli

  • @vue/cli

    • 项目脚手架
    • 包含运行时依赖 @vue/cli-service,可升级,同步升级其他如 webpack 等工具
    • 包含丰富的官方插件集合,如 @vue/cli-plugin-babel@vue/cli-plugin-eslint
    • 支持图形化创建、管理项目
  • @vue/cli-service 作为 devDependencies 局部安装在项目中,提供 vue-cli-service 命令


二、安装

Node.js 版本最好在 10 以上


若存在旧版 vue-cli 需要提前卸载

npm uninstall vue-cli -g
# OR
yarn global remove vue-cli

安装

npm install -g @vue/cli
#  OR
yarn global add @vue/cli

安装完成之后,可以全局使用 vue 命令

安装各种插件和扩展后, vue 可以使用的命令有:

vue serve // 启动开发原型项目
vue build // 构建项目
vue config // 审查或修改全局的 CLI 配置
vue ui // 启动图形化界面创建或者管理项目
vue create // 创建项目
vue inspect // 查看当前项目 webpack 配置

升级

npm update -g @vue/cli
# 或者
yarn global upgrade --latest @vue/cli

三、基础知识

原型开发(单纯以一个 js / vue 文件启动)

1、需要安装全局扩展

npm install -g @vue/cli-service-global

2、开发一个页面

vue serve 
    -o, --open  打开浏览器
    -c, --copy  将本地 URL 复制到剪切板
    -h, --help  输出用法信息
    [entry], mycomponent.vue/app.vue/index.js/或其他 .js / .vue 类型入口文件

例子:

vue serve mycomponent.vue

3、构建一个生产包

vue build 
    -t, --target <target> 构建目标 (app | lib | wc | wc-async, 默认值:app)
    -n, --name <name> 库的名字或 Web Components 组件的名字 (默认值:入口文件名)
    -d, --dest <dir> 输出目录 (默认值:dist)
    -h, --help 输出用法信息
    [entry], mycomponent.vue/app.vue/index.js/或其他 .js / .vue 类型入口文件

例子:

vue build -t app mycomponent.vue

创建项目

1、使用 cli 创建: vue create 创建项目

根据命令行交互,选择配置

默认的 preset 包含了基本的 Babel + ESLint

vue create myapp

2、使用图形界面创建

vue ui 启动一个图形界面来创建和管理项目

vue ui

CLI 服务

1、启动项目服务

初始项目中,存在命令

// package.json
{
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build"
  }
}

2、启动项目命令

npm run serve
# OR
yarn serve

3、命令详解

vue-cli-service serve

基于 webpack-dev-server 启动一个开发服务器

开箱即用的模块热重载

vue-cli-service serve
    --open    在服务器启动时打开浏览器
    --copy    在服务器启动时将 URL 复制到剪切版
    --mode    指定环境模式 (默认值:development)
    --host    指定 host (默认值:0.0.0.0)
    --port    指定 port (默认值:8080)
    --https   使用 https (默认值:false)

vue-cli-service build

构建项目

vue-cli-service build
    --mode        指定环境模式 (默认值:production)
    --dest        指定输出目录 (默认值:dist)
    --modern      面向现代浏览器带自动回退地构建应用
    --target      app | lib | wc | wc-async (默认值:app)
    --name        库或 Web Components 模式下的名字 (默认值:package.json 中的 "name" 字段或入口文件名)
    --no-clean    在构建项目之前不清除目标目录
    --report      生成 report.html 以帮助分析包内容
    --report-json 生成 report.json 以帮助分析包内容
    --watch       监听文件变化

vue-cli-service inspect

查看项目的 webpack config

vue-cli-service inspect
    --mode    指定环境模式 (默认值:development)

4、缓存和并行

cache-loader

  • 缓存编译结果,下次编译复用
  • 默认为 Vue/Babel/TypeScript 编译开启缓存。文件缓存在 node_modules/.cache
  • 遇到编译问题,可以删除缓存试试

thread-loader

  • 多线程转译代码,加快转译速度
  • 会在多核 CPU 上为 Babel/TypeScript 转译开启

5、Git Hook

@vue/cli-service 会安装 yorkie

在 package.json 中配置 git hook

// 在 pre-commit 阶段,执行 lint-staged
// lint-staged 时候若提交有 js、vue文件,执行
// "vue-cli-service lint",
// "git add"
// 进行校验
{
  "gitHooks": {
    "pre-commit": "lint-staged"
  },
   "lint-staged": {
    "*.{js,vue}": [
      "vue-cli-service lint",
      "git add"
    ]
  }
}

四、开发

兼容性

1、browserlist

根据 package.json 中的 browserlist 字段或者 .browserlistrc 文件,指定需要支持的浏览器范围

该值会被 @babel/preset-env 和 Autoprefixer 来确定需要转译的
javascript 特性和需要添加的浏览器前缀

2、polyfill

useBuiltIns:

  • usage
    • 根据 browserlist 目标,检测源代码中需要转化的语言特性,自动加载对应的 polyfill
  • entry
    • 在入口文件添加 import 'core-js/stable'; import 'regenerator-runtime/runtime';
    • 会根据 browserslist 目标导入所有 polyfill
  • false
    • 构建一个库或者 Web Component
    • 确保你的库或是组件不包含不必要的 polyfills。打包 polyfills 应当是最终使用你的库的应用的责任
// babel.config.js
{
  "presets": [
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "entry"
      }
    ]
  ]
}

3、现代模式

产生两个应用的版本:一个现代版的包,面向支持 ES modules 的现代浏览器,另一个旧版的包,面向不支持的旧浏览器

vue-cli-service build --modern

现代版的包会通过 <script type="module"> 在被支持的浏览器中加载;

它们还会使用 <link rel="modulepreload"> 进行预加载:

  • <script type="module"> 需要配合始终开启的 CORS 进行加载
  • 服务器必须返回诸如 Access-Control-Allow-Origin: * 的有效的 CORS 头
  • 旧版的包会通过 <script nomodule> 加载,并会被支持 ES modules 的浏览器忽略

HTML 与静态资源

1、HTML

  • html-webpack-plugin
    • 使用 public/index.html 作为页面模板
    • 生成的资源链接会被自动注入该页面
    • 自动注入资源提示(预加载preload/空闲时获取prefetch)

2、插值

  • html-webpack-plugin 本身暴露的变量
  • 客户端的环境变量
    • .env.env.local 等等

3、preload (<link rel="preload">

  • 页面加载的过程中,我们希望在浏览器开始主体渲染之前尽早 preload
  • 默认情况下 Vue CLI 会为所有初始化渲染需要的文件自动生成 preload 提示
  • preload 标记由 @vue/preload-webpack-plugin 注入,可通过修改 chainWebpack 删除
    • config.plugin('preload')

4、prefetch (<link rel="prefetch">

  • 在页面加载完成后,利用空闲时间提前获取用户未来可能会访问的内容
  • 默认情况下,Vue CLI 会为所有作为 async chunk 生成的 JavaScript 文件 (通过动态 import() 按需 code splitting 的产物) 自动生成 prefetch 提示。
  • prefetch 标记由 @vue/preload-webpack-plugin 注入,可通过修改 chainWebpack 删除
    • config.plugin('prefetch')

5、构建多页面应用

  • 配置 vue.config.js 中的 pages 选项可以构建一个多页面的应用
  • 构建好的应用将会在不同的入口之间高效共享通用的 chunk 以获得最佳的加载性能

6、资源路径处理规则

  • 以 . 开头

    • 当做相对路径处理,根据当前项目的目录结构解析
  • 以 ~ 开头

    • 其后的任何内容都会作为一个模块请求被解析。这意味着你甚至可以引用 Node 模块中的资源
    • 例如:<img src="~some-npm-package/foo.png">
  • 以 @ 开头

    • Vue CLI 默认设置一个指向 <projectRoot>/src 的别名 @
    • 解析时候将 @ 替换
  • 以 / 开头

    • 按照绝对路径解析
  • public

    • 任何放置在 public 文件夹的静态资源都会被简单的复制,而不经过 webpack。你需要通过绝对路径来引用它们

CSS 相关

1、基础

  • 天生支持 PostCSS、CSS Modules、Sass、Less、Stylus 预处理器
  • 所有编译后的 css 通过 css-loader 处理 url() 中的资源引用
  • 想要引用 npm 依赖或者使用 webpack 别名,需要在前面加载 ~ 作为前缀,避免歧义

2、PostCSS 配置

  • postcss-loader
    • .postcssrc
    • postcss-config.js
    • vue.config.js 中的 css.loaderOptions.postcss

3、向预处理器 Loader 传递选项

// vue.config.js
module.exports = {
  css: {
    loaderOptions: {
      // 给 sass-loader 传递选项
      sass: {
        // @/ 是 src/ 的别名
        // 所以这里假设你有 `src/variables.sass` 这个文件
        // 注意:在 sass-loader v8 中,这个选项名是 "prependData"
        additionalData: `@import "~@/variables.sass"`
      },
      // 默认情况下 `sass` 选项会同时对 `sass` 和 `scss` 语法同时生效
      // 因为 `scss` 语法在内部也是由 sass-loader 处理的
      // 但是在配置 `prependData` 选项的时候
      // `scss` 语法会要求语句结尾必须有分号,`sass` 则要求必须没有分号
      // 在这种情况下,我们可以使用 `scss` 选项,对 `scss` 语法进行单独配置
      scss: {
        additionalData: `@import "~@/variables.scss";`
      },
      // 给 less-loader 传递 Less.js 相关选项
      less:{
        // http://lesscss.org/usage/#less-options-strict-units `Global Variables`
        // `primary` is global variables fields name
        globalVars: {
          primary: '#fff'
        }
      }
    }
  }
}

webpack

1、简单配置

  • 该对象将会被 webpack-merge 合并入最终的 webpack 配置
// vue.config.js
module.exports = {
  configureWebpack: {
    plugins: [
      new MyAwesomeWebpackPlugin()
    ]
  }
}

注意:有些 webpack 选项是基于 vue.config.js 中的值设置的,所以不能直接修改

  • 修改 vue.config.js 中的 outputDir,而不是 output.path
  • 修改 vue.config.js 中的 publicPath ,而不是 output.publicPath
  • 这样做是因为 vue.config.js 中的值会被用在配置里的多个地方,以确保所有的部分都能正常工作在一起

基于环境有条件的配置或者直接修改配置

// vue.config.js
module.exports = {
  configureWebpack: config => {
    // config: 已经解析好的配置
    // 可以直接修改 config 配置,或者返回一个将会被合并的对象
    if (process.env.NODE_ENV === 'production') {
      // 为生产环境修改配置...
    } else {
      // 为开发环境修改配置...
    }
  }
}

2、链式操作 (高级)

通过 webpack-chain 维护

这个库提供了一个 webpack 原始配置的上层抽象,使其可以定义具名的 loader 规则和具名插件,并有机会在后期进入这些规则并对它们的选项进行修改

可以使用 vue inspect 查看 webpack 配置

// vue.config.js
module.exports = {
  chainWebpack: config => {
    config.module
      .rule('vue')
      .use('vue-loader')
        .tap(options => {
          // 修改它的选项...
          return options
        })
  }
}
  • 实例操作

添加loader

// vue.config.js
module.exports = {
  chainWebpack: config => {
    // GraphQL Loader
    config.module
      .rule('graphql')
      .test(/\.graphql$/)
      .use('graphql-tag/loader')
        .loader('graphql-tag/loader')
        .end()
      // 你还可以再添加一个 loader
      .use('other-loader')
        .loader('other-loader')
        .end()
  }
}

替换loader

// vue.config.js
module.exports = {
  chainWebpack: config => {
    const svgRule = config.module.rule('svg')

    // 清除已有的所有 loader。
    // 如果你不这样做,接下来的 loader 会附加在该规则现有的 loader 之后。
    svgRule.uses.clear()

    // 添加要替换的 loader
    svgRule
      .use('vue-svg-loader')
        .loader('vue-svg-loader')
  }
}

修改插件

// vue.config.js
module.exports = {
  chainWebpack: config => {
    config
      .plugin('html')
      .tap(args => {
        // 1、返回新的配置参数
        return [/* 传递给 html-webpack-plugin's 构造函数的新参数 */]
        
        // 2、修改现有参数
        // args[0].template = '/Users/username/proj/app/templates/index.html'
        // return args
      })
  }
}
  • 审查 webpack 配置

将配置导出到 output.js 进行查阅

vue inspect > output.js

指定一个路径来审查配置的一小部分

# 只审查第一条规则
vue inspect module.rules.0

指向一个规则或插件的名字

vue inspect --rule vue
vue inspect --plugin html

列出所有规则和插件的名字

vue inspect --rule
vue inspect --plugin

模式和环境变量

1、模式---根据 mode 参数不一样, Vuc CLI 会解析出不同的 webpack 配置

  • vue-cli-service build --mode development
    • 该配置启用热更新,不会对资源进行 hash 也不会打出 vendor bundles
  • vue-cli-service build --mode production
    • 压缩、混淆、提取公共代码等等
  • vue-cli-service build --mode test
    • 不会处理图片以及一些对单元测试非必需的其他资源

2、环境变量

  • 项目根目录中放置下列文件来指定环境变量:
.env                # 在所有的环境中被载入
.env.local          # 在所有的环境中被载入,但会被 git 忽略
.env.[mode]         # 只在指定的模式中被载入
.env.[mode].local   # 只在指定的模式中被载入,但会被 git 忽略

3、环境文件

  • 格式:键=值
  • 只有 NODE_ENV,BASE_URL 和以 VUE_APP_ 开头的变量将通过 webpack.DefinePlugin 静态地嵌入到客户端侧的代码中
NODE_ENV=production
VUE_APP_TITLE=My App
FOO=foo
BAR=bar
CONCAT=$FOO$BAR # CONCAT=foobar

4、环境文件加载优先级

  • 为一个特定模式准备的环境文件 (例如 .env.production) 将会比一般的环境文件 (例如 .env) 拥有更高的优先级
  • Vue CLI 启动时已经存在的环境变量拥有最高优先级,并不会被 .env 文件覆写
  • .env 环境文件是通过运行 vue-cli-service 命令载入的,因此环境文件发生变化,需要重启服务

构建目标

1、应用模式(默认模式)

vue-cli-service build 

2、库模式

# Vue 是外置的
vue-cli-service build --target lib

# Vue 是内联的
vue-cli-service build --target lib --inline-vue

# 指定名字
vue-cli-service build --target lib --name myLib [entry]

3、Vue vs. JS/TS 入口文件

  • 使用一个 .vue 文件作为入口时,库会直接暴露这个 Vue 组件本身
  • 使用一个 .js 或 .ts 文件作为入口时,它可能会包含具名导出,所以库会暴露为一个模块
    • UMD:window.yourLib.default
    • CommonJS:const myLib = require('mylib').default
  • 若没有任何具名导出并希望直接暴露默认导出
// vue.config.js
module.exports = {
    configureWebpack: {
        output: {
            libraryExport: 'default'
        }
    }
}

4、Web Components 组件(不支持 IE11)

  • Vue 以外置形式处理
vue-cli-service build --target wc --name my-element [entry]

# 注册多个 Web Components 组件的包
vue-cli-service build --target wc --name foo 'src/components/*.vue'

# 异步 Web Components 组件
vue-cli-service build --target wc-async --name foo 'src/components/*.vue'
posted @ 2021-03-02 16:46  青S衫%  阅读(1122)  评论(0编辑  收藏  举报