Vue 学习笔记(二十二):Vue CLI 基础

Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统。致力于将 Vue 生态中的工具基础标准化。它确保了各种构建工具能够基于智能的默认配置即可平稳衔接,这样你可以专注在撰写应用上,而不必花好几天去纠结配置的问题。与此同时,它也为每个工具提供了调整配置的灵活性,无需 eject。

Overview

它提供:

  • 通过 @vue/cli 实现的交互式的项目脚手架。
  • 通过 @vue/cli + @vue/cli-service-global 实现的零配置原型开发。
  • 一个运行时依赖 (@vue/cli-service),该依赖:
    • 可升级;
    • 基于 webpack 构建,并带有合理的默认配置;
    • 可以通过项目内的配置文件进行配置;
    • 可以通过插件进行扩展。
  • 一个丰富的官方插件集合,集成了前端生态中最好的工具。
  • 一套完全图形化的创建和管理 Vue.js 项目的用户界面。

Components of the System

CLI

CLI (@vue/cli) 全局安装的 npm 包,提供 vue 命令。
可以通过 vue create 快速搭建一个新项目,
或者通过 vue serve 构建新想法的原型。
也可以通过 vue ui 通过一套图形化界面管理你的所有项目。

CLI 服务 CLI Service

CLI 服务 (@vue/cli-service) 是开发环境依赖。它是一个 npm 包,局部安装在每个 @vue/cli 创建的项目中。

CLI 服务是构建于 webpackwebpack-dev-server 之上的。它包含了:

  • 加载其它 CLI 插件的核心服务;
  • 一个针对绝大部分应用优化过的内部的 webpack 配置;
  • 项目内部的 vue-cli-service 命令,提供 servebuildinspect 命令。

CLI 插件 CLI Plugins

可选的 npm 包,例如 Babel/TypeScript 转译、ESLint 集成、单元测试和 end-to-end 测试等。Vue CLI 插件的名字以 @vue/cli-plugin- (内建插件) 或 vue-cli-plugin- (社区插件) 开头。

项目下运行命令 vue-cli-service ,会自动解析并加载 package.json 中列出的所有 CLI 插件。

插件可以作为项目创建过程的一部分,也可后期加入到项目中。它们也可以被归成一组可复用的 preset。

安装

1
npm install -g @vue/cli

验证安装:

1
vue --version

升级(全局)

1
npm update -g @vue/cli

项目依赖

升级项目中的 Vue CLI 相关模块(以 @vue/cli-plugin- 或 vue-cli-plugin- 开头),请在项目目录下运行 vue upgrade

快速原型开发 Instant Prototyping

可以使用 vue servevue build 命令对单个 *.vue 文件进行快速原型开发,需要先安装安装:

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

vue serve 的缺点就是它需要安装全局依赖,这使得它在不同机器上的一致性不能得到保证。因此只适用于快速原型开发。

vue serve

1
2
3
4
5
6
7
8
9
Usage: serve [options] [entry]
在开发环境模式下零配置为 .js 或 .vue 文件启动一个服务器
Options:
-o, --open 打开浏览器
-c, --copy 将本地 URL 复制到剪切板

你所需要的仅仅是一个 App.vue 文件:

1
2
3
<template>
<h1>Hello!</h1>
</template>

在这个 App.vue 文件所在的目录下运行:

1
vue serve

vue serve 使用了和 vue create 创建的项目相同的默认设置 (webpack、Babel、PostCSS 和 ESLint)。会在当前目录自动推导入口文件——可以是 main.jsindex.jsApp.vueapp.vue 中的一个。也可以显式指定入口文件:

1
vue serve MyComponent.vue

如果需要,还可以提供一个 index.htmlpackage.json、安装并使用本地依赖、甚至通过相应的配置文件配置 Babel、PostCSS 和 ESLint。

vue build

1
2
3
4
5
6
7
8
9
10
Usage: build [options] [entry]
在生产环境模式下零配置构建一个 .js 或 .vue 文件
Options:
-t, --target <target> 构建目标 (app | lib | wc | wc-async, 默认值:app)
-n, --name <name> 库的名字或 Web Components 组件的名字 (默认值:入口文件名)
-d, --dest <dir> 输出目录 (默认值:dist)

也可以使用 vue build 将目标文件构建成一个生产环境的包并用来部署:

1
vue build MyComponent.vue

vue build 也提供了将组件构建成为一个库或一个 Web Components 组件的能力。

创建一个项目

vue create

例:

1
vue create hello-world

会被提示选取一个 preset。可以选默认的包含了基本的 Babel + ESLint 设置的 preset,也可以选“手动选择”(面向生产的项目更加需要的)。

如果手动选择特性,在操作提示的最后可以选择将已选项保存为一个将来可复用的 preset。

tip ~/.vuerc
被保存的 preset 将会存在用户的 home 目录下一个名为 .vuerc 的 JSON 文件里。如果你想要修改被保存的 preset / 选项,可以编辑这个文件。

在项目创建的过程中,会被提示选择喜欢的包管理器或使用淘宝 npm 镜像源以更快地安装依赖。这些选择也将会存入 ~/.vuerc

vue create 命令有一些可选项,具体查看帮助:

1
vue create --help
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
用法:create [options] <app-name>
创建一个由 `vue-cli-service` 提供支持的新项目
选项:
-p, --preset <presetName> 忽略提示符并使用已保存的或远程的预设选项
-d, --default 忽略提示符并使用默认预设选项
-i, --inlinePreset <json> 忽略提示符并使用内联的 JSON 字符串预设选项
-m, --packageManager <command> 在安装依赖时使用指定的 npm 客户端
-r, --registry <url> 在安装依赖时使用指定的 npm registry
-g, --git [message] 强制 / 跳过 git 初始化,并可选的指定初始化提交信息
-n, --no-git 跳过 git 初始化
-f, --force 覆写目标目录可能存在的配置
-c, --clone 使用 git clone 获取远程预设选项
-x, --proxy 使用指定的代理创建项目
-b, --bare 创建项目时省略默认组件中的新手指导信息
-h, --help 输出使用帮助信息

使用图形化界面

vue ui 命令以图形化界面创建和管理项目,会打开一个浏览器窗口,并以图形化界面引导项目创建的流程。

插件和 Preset

插件

Vue CLI 使用基于插件的架构。查看新创建项目的 package.json,你就会发现依赖都是以 @vue/cli-plugin- 开头的。插件可以修改 webpack 的内部配置,也可以向 vue-cli-service 注入命令。在项目创建的过程中,绝大部分列出的特性都是通过插件来实现的。

基于插件的架构使得 Vue CLI 灵活且可扩展。

vue ui:GUI 安装和管理插件。

在现有的项目中安装插件

每个 CLI 插件都会包含一个 (用来创建文件的) 生成器和一个 (用来调整 webpack 核心配置和注入命令的) 运行时插件。

vue add 命令:

1
vue add eslint

vue add 是为了安装和调用 Vue CLI 插件。这不意味着替换掉普通的 npm 包。对于普通的 npm 包,仍然需要选用包管理器。

警告 在运行 vue add 之前将项目的最新状态提交,因为该命令可能调用插件的文件生成器并很有可能更改现有的文件。

vue add@vue/eslint 解析为完整的包名 @vue/cli-plugin-eslint,然后从 npm 安装它,调用它的生成器。

1
2
# 这个和之前的用法等价
vue add cli-plugin-eslint

如果不带 @vue 前缀,该命令会换作解析一个 unscoped 的包。例如安装第三方插件 vue-cli-plugin-apollo

1
2
# 安装并调用 vue-cli-plugin-apollo
vue add apollo

也可以基于一个指定的 scope 使用第三方插件。例如添加一个插件名为 @foo/vue-cli-plugin-bar

1
vue add @foo/bar

可以向被安装的插件传递生成器选项 (会跳过命令提示):

1
vue add eslint --config airbnb --lintOn save

如果一个插件已经被安装,可使用 vue invoke 命令跳过安装过程,只调用它的生成器。vue invoke 接受和 vue add 相同的参数。

如果出于一些原因,插件列在了该项目之外的其它 package.json 文件里,可以在自己项目的 package.json 里设置 vuePlugins.resolveFrom 选项指向包含其它 package.json 的文件夹。

例如,.config/package.json 文件:

1
2
3
4
5
{
"vuePlugins": {
"resolveFrom": ".config"
}
}

项目本地的插件

如果需要在项目里直接访问插件 API 而不需要创建一个完整的插件,可以在 package.json 文件中使用 vuePlugins.service 选项:

1
2
3
4
5
{
"vuePlugins": {
"service": ["my-commands.js"]
}
}

每个文件都需要暴露一个函数,接受插件 API 作为第一个参数。

也可以通过 vuePlugins.ui 选项添加像 UI 插件一样工作的文件:

1
2
3
4
5
{
"vuePlugins": {
"ui": ["my-ui.js"]
}
}

Preset

一个 Vue CLI preset 是一个包含创建新项目所需预定义选项和插件的 JSON 对象,让用户无需在命令提示中选择它们。

vue create 过程中保存的 preset 会被放在你的 home 目录下的一个配置文件中 (~/.vuerc)。可以通过直接编辑这个文件来调整、添加、删除保存好的 preset。

preset 示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"useConfigFiles": true,
"cssPreprocessor": "sass",
"plugins": {
"@vue/cli-plugin-babel": {},
"@vue/cli-plugin-eslint": {
"config": "airbnb",
"lintOn": ["save", "commit"]
},
"@vue/cli-plugin-router": {},
"@vue/cli-plugin-vuex": {}
}
}

Preset 的数据会被插件生成器用来生成相应的项目文件。除了上述字段,也可以为集成工具添加配置:

1
2
3
4
5
6
7
8
9
10
{
"useConfigFiles": true,
"plugins": {...},
"configs": {
"vue": {...},
"postcss": {...},
"eslintConfig": {...},
"jest": {...}
}
}

这些额外的配置将会根据 useConfigFiles 的值被合并到 package.json 或相应的配置文件中。例如,当 "useConfigFiles": true 的时候,configs 的值将会被合并到 vue.config.js 中。

Preset 插件的版本管理

可显式地指定用到的插件的版本:

1
2
3
4
5
6
7
8
{
"plugins": {
"@vue/cli-plugin-eslint": {
"version": "^3.0.0",
// ... 该插件的其它选项
}
}
}

对于官方插件来说这不是必须的——当被忽略时,CLI 会自动使用 registry 中最新的版本。不过推荐为 preset 列出的所有第三方插件提供显式的版本范围

允许插件的命令提示

插件选项中指定 "prompts": true 来允许注入命令提示:

1
2
3
4
5
6
7
8
{
"plugins": {
"@vue/cli-plugin-eslint": {
// 让用户选取他们自己的 ESLint config
"prompts": true
}
}
}

每个插件在项目创建的过程中都可以注入它自己的命令提示,不过当你使用了一个 preset,这些命令提示就会被跳过,因为 Vue CLI 假设所有的插件选项都已经在 preset 中声明过了。

在有些情况下你可能希望 preset 只声明需要的插件,同时让用户通过插件注入的命令提示来保留一些灵活性。

远程 Preset

通过 git repo 将一个 preset 分享给其他开发者。这个 repo 应该包含以下文件:

  • preset.json: 包含 preset 数据的主要文件(必需)。
  • generator.js: 一个可以注入或是修改项目中文件的 Generator
  • prompts.js 一个可以通过命令行对话为 generator 收集选项的 prompts 文件

发布 repo 后,就可以在创建项目的时候通过 --preset 选项使用这个远程的 preset 了:

1
2
# 从 GitHub repo 使用 preset
vue create --preset username/repo my-project

GitLab 和 BitBucket 也是支持的。如果要从私有 repo 获取,需要使用 --clone 选项:

1
2
vue create --preset gitlab:username/repo --clone my-project
vue create --preset bitbucket:username/repo --clone my-project

加载文件系统中的 Preset

当开发一个远程 preset 的时候,你必须不厌其烦的向远程 repo 发出 push 进行反复测试。为了简化这个流程,你也可以直接在本地测试 preset。

如果 --preset 选项的值是一个相对或绝对文件路径,或是以 .json 结尾,则 Vue CLI 会加载本地的 preset:

1
2
3
4
5
# ./my-preset 应当是一个包含 preset.json 的文件夹
vue create --preset ./my-preset my-project
# 或者,直接使用当前工作目录下的 json 文件:
vue create --preset my-preset.json my-project

CLI 服务

使用命令

npm scripts 中以 vue-cli-service、或者从终端中以 ./node_modules/.bin/vue-cli-service 访问命令。

默认 preset 的项目的 package.json

1
2
3
4
5
6
{
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
}
}

可以通过 npm 或 Yarn 调用这些 script:

1
2
3
npm run serve
# OR
yarn serve

如果使用 npx (最新版的 npm 应该已经自带),也可以直接这样调用命令:

1
npx vue-cli-service serve

可以通过 vue ui 命令使用 GUI 运行更多的特性脚本。

vue-cli-service serve

1
2
3
4
5
6
7
8
9
10
用法:vue-cli-service serve [options] [entry]
选项:
--open 在服务器启动时打开浏览器
--copy 在服务器启动时将 URL 复制到剪切版
--mode 指定环境模式 (默认值:development)
--host 指定 host (默认值:0.0.0.0)
--port 指定 port (默认值:8080)
--https 使用 https (默认值:false)

vue-cli-service serve 命令会启动一个开发服务器 (基于 webpack-dev-server) 并附带开箱即用的模块热重载 (Hot-Module-Replacement)。

除了通过命令行参数,也可以使用 vue.config.js 里的 devServer 字段配置开发服务器。

命令行参数 [entry] 被指定为唯一入口,而非额外的追加入口。使用 [entry] 覆盖 config.pages 中的 entry 将可能引发错误。

vue-cli-service build

1
2
3
4
5
6
7
8
9
10
11
12
13
用法:vue-cli-service build [options] [entry|pattern]
选项:
--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 build 会在 dist/ 目录产生一个可用于生产环境的包,带有 JS/CSS/HTML 的压缩,和为更好的缓存而做的自动的 vendor chunk splitting。它的 chunk manifest 会内联在 HTML 里。

这里还有一些有用的命令参数:

  • --modern 使用 现代模式 构建应用,为现代浏览器交付原生支持的 ES2015 代码,并生成一个兼容老浏览器的包用来自动回退。

  • --target 允许你将项目中的任何组件以一个库或 Web Components 组件的方式进行构建。

  • --report--report-json 会根据构建统计生成报告,它会帮助你分析包中包含的模块们的大小。

vue-cli-service inspect

1
2
3
4
5
用法:vue-cli-service inspect [options] [...paths]
选项:
--mode 指定环境模式 (默认值:development)

可以使用 vue-cli-service inspect 来审查一个 Vue CLI 项目的 webpack config。

查看所有的可用命令

有些 CLI 插件会向 vue-cli-service 注入额外的命令。例如 @vue/cli-plugin-eslint 会注入 vue-cli-service lint 命令。查看所有注入的命令:

1
npx vue-cli-service help

也可以这样学习每个命令帮助:

1
npx vue-cli-service help [command]

缓存和并行处理

  • cache-loader 会默认为 Vue/Babel/TypeScript 编译开启。文件会缓存在 node_modules/.cache 中——如果你遇到了编译方面的问题,记得先删掉缓存目录之后再试试看。

  • thread-loader 会在多核 CPU 的机器上为 Babel/TypeScript 转译开启。

Git Hook

在安装之后,@vue/cli-service 也会安装 yorkie,可以在 package.jsongitHooks 字段中方便地指定 Git hook:

1
2
3
4
5
6
7
8
9
10
11
{
"gitHooks": {
"pre-commit": "lint-staged"
},
"lint-staged": {
"*.{js,vue}": [
"vue-cli-service lint",
"git add"
]
}
}

yorkie fork 自 husky 并且与后者不兼容。

配置时无需 Eject

通过 vue create 创建的项目无需额外的配置就已经可以跑起来了。插件的设计也是可以相互共存的,所以绝大多数情况下,你只需要在交互式命令提示中选取需要的功能即可。

不过满足每一个需求是不太可能的,而且一个项目的需求也会不断改变。通过 Vue CLI 创建的项目让你无需 eject 就能够配置工具的几乎每个角落。