组成
@vue/cli
@vue/cli
是一个全局安装的 npm 包,提供了终端里的全局 vue 命令。
安装:
npm install -g @vue/cli
命令:
vue --version
vue ui
vue create
vue serve # 使用该命令需要另外全局安装 `@vue/cli-service-global` 包
vue build # 使用该命令需要另外全局安装 `@vue/cli-service-global` 包
@vue/cli-service-global
@vue/cli-service-global
是一个全局安装的 npm 包,使用 vue serve
和 vue build
命令时需要安装这个包。
安装:
npm install -g @vue/cli-service-global
命令:
vue serve
vue build
@vue/cli-service
@vue/cli-service
是一个局部安装的 npm 包,自动安装在每个 @vue/cli
创建的项目中。
- 提供项目内部的
vue-cli-service
命令 - 构建于 webpack 和 webpack-dev-server 之上,拥有优化过的 webpack 配置
- 加载
package.json
中列出的所有@vue/cli-plugin-
和vue-cli-plugin-
插件
命令:
npx vue-cli-service help
npx vue-cli-service serve
npx vue-cli-service build
npx vue-cli-service inspect
npx vue-cli-service lint
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
}
@vue/cli-plugin- 和 vue-cli-plugin-
@vue/cli-plugin-
开头的是内建插件,vue-cli-plugin-
开头的是社区插件。
插件是局部安装的 npm 包,提供可选功能,例如 Babel/TypeScript 转译、ESLint 集成、单元测试和 end-to-end 测试等。
插件可以修改 webpack 的内部配置,也可以向 vue-cli-service
注入命令,当你在项目内部运行 vue-cli-service
命令时,它会自动解析并加载 package.json 中列出的所有插件。
preset
preset 是一个包含创建新项目所需预定义选项和插件的 JSON 对象,让用户无需在命令提示中选择它们,保存在 ~/.vuerc
,可以直接修改。
命令
vue serve
我用不到
vue build
我用不到
vue create
使用命令行创建一个新项目
vue create hello-world
vue ui
使用图形化界面创建一个项目
vue ui
vue add
在现有的项目中安装插件
vue add @vue/cli-plugin-eslint
vue-cli-service serve
vue-cli-service serve
命令会启动一个基于 webpack-dev-server
的开发服务器。
命令:
npx vue-cli-service serve
配置:
- 使用命令行参数配置 devServer
- 使用
vue.config.js
里的devServer
字段配置 devServer(推荐)
vue-cli-service build
vue-cli-service build
基于 webpack 将应用程序打包。
静态资源
在 .vue 组件中的 template 块、script 块、style 块中都可以引入静态资源。
<template>
<div class="my-component">
<img src="URL">
</div>
</template>
<script>
import 'URL'
</script>
<style>
.my-component {
background: url('URL');
}
</style>
静态资源路径可以是:
- 绝对路径 /images/foo.png
- 相对路径 ./images/foo.png
- 模块路径 ~some_module/images/foo.png
- 别名路径 @/images/foo.png
- 放在 public 目录中
绝对路径
如果 URL 是一个绝对路径,在 <template>
标签中和在 <script>
<style>
标签中的处理方式不同。
在 <template>
标签中,绝对路径会原样保留,对应的资源不会经过 webpack 打包,甚至都不会去查找是否有对应的资源,只是原样复制绝对路径到生成的 index.html 文件中。
<template>
<div id="app">
<img src="/images/foo.png">
</div>
</template>
最后生成的 index.html 文件中,<img src="/images/foo.png">
,这时候服务器的根目录下如果没有 images/foo.png
,就会找不到资源。
这种情况都是配合 public 目录使用的,由于 public 目录中的所有资源都不会被 webpack 处理,只会原封不动地复制到 dist 目录中,因此位于 public/images/foo.png
的图片复制到了 dist/images/foo.png
,只要将 dist 目录上传到服务器作为服务器的根目录,<img src="/images/foo.png">
就能够访问到 dist/images/foo.png
了,也就是 public/images/foo.png
的拷贝。
在 <script>
和 <style>
标签中,绝对路径会以项目目录作为根目录,去查找对应的资源。
<script>
import '/images/foo.png'
</script>
<style>
.container {
background: url('/images/foo.png')
}
</style>
以上会查找 <projectDirectory>/images/foo.png
,如果存在资源,则该资源将会被包含进入 webpack 的依赖图中,通过 webpack 的 Assets Modules 配置,用版本哈希值和正确的公共基础路径来决定最终的文件路径,并将小于 8KiB 的资源内联,以减少 HTTP 请求的数量。
如果找不到该资源,则会报错。
相对路径
如果 URL 以 . 开头,它会作为一个相对模块请求,相对于当前的文件所处的目录。
import './images/foo.png'
<img src="./images/foo.png">
.container {
background: url('./images/foo.png')
}
该资源将会被包含进入 webpack 的依赖图中,通过 webpack 的 Assets Modules 配置,用版本哈希值和正确的公共基础路径来决定最终的文件路径,并将小于 8KiB 的资源内联,以减少 HTTP 请求的数量。
模块路径
如果 URL 以 ~ 开头,其后的任何内容都会作为一个模块请求被解析,这意味着你甚至可以引用 Node 模块中的资源。
import '~some-npm-package/foo.png'
<img src="~some-npm-package/foo.png">
.container {
background: url('~some-npm-package/foo.png')
}
该资源将会被包含进入 webpack 的依赖图中,通过 webpack 的 Assets Modules 配置,用版本哈希值和正确的公共基础路径来决定最终的文件路径,并将小于 8KiB 的资源内联,以减少 HTTP 请求的数量。
别名路径
如果 URL 以 @ 开头,它也会作为一个模块请求被解析。它的用处在于 Vue CLI 默认会设置一个指向 <projectRoot>/src
的别名 @。(仅作用于模版中)。注意在 css 中需要在 @ 前面加上 ~。
import '@/assets/images/1.png'
<img src="@/assets/images/1.png">
.container {
background: url('~@/assets/images/1.png')
}
该资源将会被包含进入 webpack 的依赖图中,通过 webpack 的 Assets Modules 配置,用版本哈希值和正确的公共基础路径来决定最终的文件路径,并将小于 8KiB 的资源内联,以减少 HTTP 请求的数量。
public 目录
任何放置在 public 文件夹的静态资源都会被简单的复制到 dist 目录下,而不经过 webpack。你只能在 <template>
中通过绝对路径来引用它们。推荐将静态资源作为模块的依赖导入,而不是放置到 public 文件夹。
浏览器兼容性
vue 默认配置的 babel-loader 使用 @babel/preset-env 来进行转换语法,并通过配置 @babel/preset-env 的 useBuiltIns: 'usage' 选项来按需补齐 API。
vue 默认不会对 node_modules 目录里的模块使用 babel-loader,只会对我们的项目代码使用 babel-loader。
如果 node_modules 里面某个具体的依赖包需要使用 babel-loader 来转码,那么需要如下配置:
- 如果该依赖包需要语法转换和补齐 API,那么将 vue.config.js 的 transpileDependencies 选项指定具体依赖包,则 babel-loader 会对该依赖包进行语法转换和补齐 API。
// vue.config.js
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: ['jquery', 'lodash']
})
- 如果该依赖包不需要语法转换,只需要补齐 API,分以下两种情况:
- 如果明确知道依赖包需要的 API,那么将 babel.config.js 的 @vue/babel-preset-app 的 polyfills 选项指定需要包含的 polyfills,这样不管源代码中是需要,都会引入该选项指定的 API。
// babel.config.js
module.exports = {
presets: [
[
'@vue/babel-preset-app',
{
polyfills: [
'es.promise',
'es.symbol'
]
}
]
]
}
- 如果不知道依赖包具体需要哪些 API,那么设置 babel.config.js 的 @vue/babel-preset-app 的选项 useBuiltIns: 'entry',然后在项目入口文件开头 import 'core-js/stable'; import 'regenerator-runtime/runtime'; 一次性引入所有的 API,不按需引入了。
// babel.config.js
module.exports = {
presets: [
[
'@vue/babel-preset-app',
{
useBuiltIns: 'entry'
}
]
]
}
// entry
import 'core-js/stable';
import 'regenerator-runtime/runtime';
mode 和环境变量
mode
vue-cli-service build
mode 默认为 production
vue-cli-service serve
mode 默认为 development
vue-cli-service test
mode 默认为 test
可以通过 --mode 来改变 mode 默认值
vue-cli-service build --mode development
NODE_ENV
.env 文件中设置环境变量,可以设置 NODE_ENV 这个变量的值。如果没有 .env 目录中没有设置 NODE_ENV,则 NODE_ENV 默认等于 mode 值。
webpack 配置文件是根据 NODE_ENV 的值来配置的,例如 NODE_ENV 为 production,则 webpack 配置文件采用 splitChunks 配置,webpack 配置文件不是根据 mode 的值来决定配置的。
vue.config.js 和项目文件中都可以访问 process.env.NODE_ENV。vue.config.js 当中使用的 .env 中的 NODE_ENV 的值,而项目文件中使用的是在 vue.config.js 通过 DefinePlugin 定义的 process.env.NODE_ENV 的值,vue 会自动通过 DefinePlugin 定义 process.env.NODE_ENV 的。