前言

本文从通过脚手架搭建vue项目开始,到editorconfig、VSCode配置文件、jsconfig.json、Prettier、ESLint、Git提交规范(husky、lint-staged、conventional-changelog)、StyleLint、多环境配置、browserslist的使用,详细说明了前端项目构建的最佳实践。

源码


通过脚手架搭建vue项目

手动搭建一个完整的vue项目


通过editorconfig抹平编辑器差异

EditorConfig保证不同开发者如果使用不同的编辑器(sublime/vscode)或系统(windows/mac),能够执行统一的代码风格标准。比如:缩进是tab还是space,结尾end_of_line是lf还是crlf。

简而言之,EditorConfig可以覆盖编辑器的默认配置,是为了抹平不同IDE的代码格式差异而产生的。

但是这种方式只能简单的配置一些规范,并不能完全满足需求,所以还需要其它代码检查工具配合使用,比如说:ESLint或StyleLint,统一代码风格。

1. 添加配置文件

定义格式规则,避免常见的代码格式不一致和丑陋的 diffs。

通常在项目根目录下,添加.editorconfig配置文件,贴一份常见的配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 配置项文档:https://editorconfig.org/

# 告知 EditorConfig 插件,当前即是根文件
root = true

# * 表示下面的配置适用全部文件
[*]
## 设置字符集
charset = utf-8
## 缩进风格 space | tab,建议 space
indent_style = space
## 设置每个缩进级别的空格数(修改这里的话需要将 prettier.config.js 和 .vscode -> settings.json 也同步修改)
indent_size = 2
## 换行符类型。可选值为lf(Unix 风格)、cr(Mac 风格)或 crlf(Windows 风格),一般都是设置为 lf
end_of_line = lf
## 是否在文件末尾插入空白行
insert_final_newline = true
## 是否删除一行中的前后空格
trim_trailing_whitespace = true

# 适用 .md 文件
[*.md]
insert_final_newline = false
trim_trailing_whitespace = false

2. 安装插件

某些编辑器已经内置了EditorConfig插件,无需另外安装了,比如 WebStorm、VisualStudio、pyCharm等等。

某些编辑器没有内置,需要自行安装插件,比如vscode,需要安装 EditorConfig for VS Code

安装插件后就可以手动格式化代码(Mac OS:shift+option+f; Windows:shift+alt+f)


VSCode配置文件(Settings.json)

VSCode的setting.json设置分为工作区和用户两个级别,其中用户区会对所有项目生效,而工作区的设置只会对当前项目生效。

1. 用户区settings.json配置

点击VSCode左下角的设置按钮,选择Settings,选择以文本编辑形式打开settings.json,并且在setting.json中加入以下代码。配置完成之后,当我们保存某个文件时,就可以自动对当前文件进行ESLint检查,并且自动对一些错误进行修复。配置如下:

1
2
3
4
5
6
{
// 每次保存的时候自动格式化
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}

2. 工作区settings.json配置

除了配置用户区的settings.json之外,我们也可以配置工作区的settings.json,工作区的配置只会对当前项目生效。首先,我们需要在项目根目录创建.vscode目录,并且在该目录下创建settings.json文件。

接着,在settings.json中加入以下代码,配置完成后,当我们保存该项目中某个文件时,也会自动对该文件进行ESLint检查,并且自动修复一些问题。

1
2
3
4
5
6
7
{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
},
"eslint.validate": ["typescript", "javascript", "vue"]
}

tsconfig

1. tsconfig.json

tsconfig.json 是 TypeScript 编译器的配置文件,一般放在项目根目录。用于指定编译 TypeScript 代码时的编译选项和编译目标等信息。当我们使用 tsc 命令编译项目,且没有指定输入文件时,编译器就会去查找 tsconfig.json 文件。如果在当前目录没找到,就会逐级向父文件夹查找。我们也可以通过在 tsc 命令中加上–project 参数,来指定一个包含 tsconfig.json 文件的目录。如果命令行上指定了输入文件时,tsconfig.json 的配置会被忽略。

通过修改该文件,可以定制 TypeScript 编译器的行为,例如指定编译目标、启用或禁用特定的语言特性、设置代码检查规则等。

2. jsconfig.json

jsconfig.json 源自 tsconfig.json,默认启用了一些与 JavaScript 相关的编译选项,常用于 JavaScript 项目。可以简单理解为设置了 allowJstruetsconfig.json

如果你的项目中有一个 jsconfig.json文件的话,这个文件的配置可以对你的文件所在目录下的所有js代码做出个性化支持。目录中存在此类文件表示该目录是JavaScript项目的根目录,否则会把打开的JavaScript文件被视为独立单元。文件本身可以选择列出属于项目的文件,要从项目中排除的文件,以及编译器选项。

在工作空间中定一个jsconfig.json文件时,JavaScript体验会得到改进。

配置的内容比如:在不使用typescript的时候也可以对js进行ts的类型检查(因为jsconfig.json是tsconfig.json的子集,所以检查是ts的);当我们使用Webpack Alias时,可以往jsconfig.json里添加baseUrlpaths配置以获得路径智能提示,提高开发体验。

1
2
3
4
5
6
7
8
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}

3. 一份基本的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// vscode配置文件: 通过jsconfig.json来设置编译选项,可以帮助我们提高开发效率,避免一些不必要的错误。
{
"compilerOptions": {
// 指定要使用的默认库,值为"es3","es5","es2015"...
"target": "es5",
// 生成代码的模板标准,可选 amd / commonJS / es2015 / es6 / esnext / none / system / umd
"module": "esnext",
"baseUrl": "./",
// 指定如何解析模块以进行导入,可选 node / classic
"moduleResolution": "node",
// 解决别名导致vscode无法跳转文件的问题
"paths": {
"@/*": [
"src/*"
]
},
// TS需要引用的库,即声明文件,es5 默认引用dom、es5、scripthost,
// 如需要使用es的高级版本特性,通常都需要配置,如es8的数组新特性需要引入"ES2019.Array",
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
},
// 指定不需要被编译的目录:与开发无关的文件(非源码)可以让 IDE 全部在编译时排除掉,以提高 IDE 性能
"exclude": [
"node_modules",
"**/node_modules/*", // 在填写路径时 ** 表示任意目录, * 表示任意文件
"dist"
],
// 指定被编译文件所在的目录
"include": [
"src/*.js"
]
}

4. compilerOptions的其他配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
"compilerOptions": {
"target": "ES5", // 目标语言的版本
"module": "CommonJS", // 生成代码的模板标准
"lib": ["DOM", "ES2015", "ScriptHost", "ES2019.Array"], // TS需要引用的库,即声明文件,es5 默认引用dom、es5、scripthost,如需要使用es的高级版本特性,通常都需要配置,如es8的数组新特性需要引入"ES2019.Array",
"outDir": "./dist", // 指定输出目录
"rootDir": "./", // 指定输出文件目录(用于输出),用于控制输出目录结构
"allowJS": true, // 允许编译器编译JS,JSX文件
"checkJs": true, // 允许在JS文件中报错,通常与allowJS一起使用
"removeComments":true, // 删除注释
"esModuleInterop": true, // 允许export=导出,由import from 导入

/* 严格检查选项 */
"strict": true, // 开启所有严格的类型检查
"alwaysStrict": true, // 在代码中注入'use strict'
"noImplicitAny": true, // 不允许隐式的any类型
"noImplicitThis": true, // 不允许this有隐式的any类型
"strictNullChecks": true, // 不允许把null、undefined赋值给其他类型的变量
"strictBindCallApply": true, // 严格的bind/call/apply检查
"strictFunctionTypes": true, // 不允许函数参数双向协变
"strictPropertyInitialization": true, // 类的实例属性必须初始化

/* 额外检查 */
"noUnusedLocals": true, // 检查只声明、未使用的局部变量(只提示不报错)
"noUnusedParameters": true, // 检查未使用的函数参数(只提示不报错)
"noImplicitReturns": true, // 每个分支都会有返回值
"noImplicitOverride": true,// 是否检查子类继承自基类时,其重载的函数命名与基类的函数不同步问题
"noFallthroughCasesInSwitch": true, // 防止switch语句贯穿(即如果没有break语句后面不会执行)
"noUncheckedIndexedAccess": true, / /是否通过索引签名来描述对象上有未知键但已知值的对象
"noPropertyAccessFromIndexSignature": true, // 是否通过" . “(obj.key) 语法访问字段和"索引”( obj[“key”]), 以及在类型中声明属性的方式之间的一致性

/* 实验选项 */
"experimentalDecorators": true, // 是否启用对装饰器的实验性支持,装饰器是一种语言特性,还没有完全被 JavaScript 规范批准
"emitDecoratorMetadata": true, // 为装饰器启用对发出类型元数据的实验性支持

/* 高级选项 */
"forceConsistentCasingInFileNames": true, // 是否区分文件系统大小写规则
"extendedDiagnostics": false, // 是否查看 TS 在编译时花费的时间
"noEmit": true, // 不输出文件,即编译后不会生成任何js文件
"noEmitOnError": true, // 有错误时不进行编译
"noEmitHelpers": true, // 不生成helper函数,减小体积,需要额外安装,常配合importHelpers一起使用
"resolveJsonModule": true, // 是否解析 JSON 模块

/* 其他 */
"incremental": true, // TS编译器在第一次编译之后会生成一个存储编译信息的文件,第二次编译会在第一次的基础上进行增量编译,可以提高编译的速度
"tsBuildInfoFile": "./buildFile", // 增量编译文件的存储位置
"diagnostics": true, // 打印诊断信息
"outFile": "./app.js", // 将多个相互依赖的文件生成一个文件,可以用在AMD模块中,即开启时应设置"module": "AMD",
"declaration": true, // 生成声明文件,开启后会自动生成声明文件
"declarationDir": "./file", // 指定生成声明文件存放目录
"emitDeclarationOnly": true, // 只生成声明文件,而不会生成js文件
"sourceMap": true, // 生成目标文件的sourceMap文件
"inlineSourceMap": true, // 生成目标文件的inline SourceMap,inline SourceMap会包含在生成的js文件中
"declarationMap": true, // 为声明文件生成sourceMap
"typeRoots": [], // 声明文件目录,默认时node_modules/@types
"types": [], // 加载的声明文件包
"importHelpers": true, // 通过tslib引入helper函数,文件必须是模块
"downlevelIteration": true, // 降级遍历器实现,如果目标源是es3/5,那么遍历器会有降级的实现
"allowUmdGlobalAccess": true, // 允许在模块中全局变量的方式访问umd模块
"moduleResolution": "node", // 模块解析策略,ts默认用node的解析策略,即相对的方式导入
"baseUrl": "./", // 解析非相对模块的基地址,默认是当前目录
"paths": { // 路径映射,相对于baseUrl
// 如使用jq时不想使用默认版本,而需要手动指定版本,可进行如下配置
"jquery": ["node_modules/jquery/dist/jquery.min.js"]
},
"rootDirs": ["src","out"], // 将多个目录放在一个虚拟目录下,用于运行时,即编译后引入文件的位置可能发生变化,这也设置可以虚拟src和out在同一个目录下,不用再去改变路径也不会报错
"listEmittedFiles": true, // 打印输出文件
"listFiles": true// 打印编译的文件(包括引用的声明文件)
}

代码格式化工具(Prettier)

1. 说明

在保存/粘贴代码或者使用格式化快捷键时,可以自动按照我们制定的Prettier规范格式化代码。

Prettier只关注代码格式,它即可单独使用,也可以配合编辑器使用,或和eslint一起使用。

这里有人可能会有疑问,eslint不也关注代码格式,做格式校验吗? 为啥还要用Prettier?这是因为一是在之前eslint不支持autoFix,二是两个的规则并不完全相同。

而且,ESLint 有一个局限性,它执行 eslint index.js --fix 只能处理 js 文件,处理不了其他格式的文件,例如html css 文件,但是 prettier 就能处理其他类型的文件 。

2. 使用

(1)下载依赖

1
npm install prettier -D

(2)设置配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
module.exports = {
// 每行最大字符数,超过会换行,默认80
printWidth: 130,
// 缩进字节数
tabWidth: 2,
// 使用制表符而不是空格缩进行
useTabs: true,
// 结尾不用分号(true有,false没有)
semi: false,
// 使用单引号(true单双引号,false双引号)
singleQuote: true,
// 更改引用对象属性的时间 可选值"<as-needed|consistent|preserve>"
quoteProps: "as-needed",
// 在对象,数组括号与文字之间加空格 "{ foo: bar }"
bracketSpacing: true,
// 是否使用尾逗号 可选值"<none|es5|all>",默认none
trailingComma: "none",
// 在JSX中使用单引号而不是双引号
jsxSingleQuote: true,
// (x) => {} 箭头函数参数只有一个时是否要有小括号。avoid:省略括号 ,always:不省略括号
arrowParens: "avoid",
// 如果文件顶部已经有一个 doclock,这个选项将新建一行注释,并打上@format标记。
insertPragma: false,
// 指定要使用的解析器,不需要写文件开头的 @prettier
requirePragma: false,
// 默认值。因为使用了一些折行敏感型的渲染器(如GitHub comment)而按照markdown文本样式进行折行
proseWrap: "preserve",
// 在html中空格是否是敏感的 "css" - 遵守CSS显示属性的默认值, "strict" - 空格被认为是敏感的 ,"ignore" - 空格被认为是不敏感的
htmlWhitespaceSensitivity: "css",
// 换行符使用 lf 结尾是 可选值"<auto|lf|crlf|cr>"
endOfLine: "auto",
// 这两个选项可用于格式化以给定字符偏移量(分别包括和不包括)开始和结束的代码
rangeStart: 0,
rangeEnd: Infinity,
// Vue文件脚本和样式标签缩进
vueIndentScriptAndStyle: false
}

在项目根目录下手动创建一个 .prettierrc.js ,进行如上配置。或者也可以在VSCode的settings.json中进行配置。配置完成后我们就可以手动通过命令行来格式化某个文件。

1
npx prettier main.js --write

prettier 先会去项目文件中找是否有 .prettierrc.js 或 .prettierrc 的文件,如果有就使用 .prettierrc.js 或 .prettierrc 文件中的格式化规则,如果没有则查找是否有.editorconfig,还是没有就使用 settings.json 的规则。

(3)安装VSCode插件

img

安装插件后,调出系统设置 settings.json 并将 prettier 设置为默认格式化工具,可以为所有语言或特定语言设置此项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
// 所有语言
"editor.defaultFormatter": "esbenp.prettier-vscode",
// 特定语言
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[vue]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[css]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
···
}

这样,我们就可以使用shift + Alt + F(VSCode默认快捷键)来格式化代码。还可以通过修改VSCode设置,实现保存即格式化。

1
"editor.formatOnSave": true

更多Prettier的使用,请移步 Prettier官网


代码规范性工具(ESLint)

1. 说明

eslint的关注点是代码质量和代码格式。

何为代码质量?如未使用变量、三等号、全局变量声明等问题

何为代码格式?如单行代码太长、tab的长度、空格、逗号,单双引号等问题

对于质量和格式问题,eslint可以给出错误或警告提示,也可以自动修复,autofix eslint的原则是一切皆可配,没有什么必须要禁止,或必须要使用的规则,如果有,这些规则应该从语言本身就限制掉。

灵活是有代价的,虽然每个规则都可配,但要配置那么多规则也是极其繁琐的,因此有人提供了一些preset,也就是预设规则,通常由一些最佳实践集成而来。

2. 使用

(1)eslint初始化

1
npm i -g eslint

在项目根目录执行以下命令初始化eslint:

1
npx eslint --init

回答几个问题后,比如配置文件格式、是否使用react,vue,是否支持typescript等,则会自动在根目录下生成对应的配置文件.eslintrc.js。

用vue脚手架创建项目时,这步已经在脚手架完成。可以跳过当前步骤直接进入下一步,设置配置文件。

(2)设置配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
module.exports = {
// 表示当前目录即为根目录,ESLint规则被现在到该目录下
root: true,
// env 表示启用 ESLint 检查的环境
env: {
// 在 node 环境下启动ESLint检测
node: true
},
// ESLint 中基础配置需要继承的配置,这里不知道怎么配置需要看文档
extends: [
'plugin:vue/essential',
'@vue/standard'
],
// 解析器
parserOptions: {
parser: '@babel/eslint-parser' // 是一个解析器,允许您使用ESLint对所有有效的Babel代码进行检查。
},
// 需要修改的启用规则及其各自的错误级别
/**
* 错误级别分为三种:
* "off" 或 0 - 关闭规则
* "warn" 或 1 - 开启规则,使用警告级别的错误:warn(不会导致程序退出)
* "error" 或 2 - 开启规则,使用错误级别的错误:error(当被触发的时候,程序会)
*/
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
}
}

设置完成后,我们就可以使用命令eslint index.js来检测index.js文件,并且可以使用eslint index.js --fix 指令,对这个文件的错误语法进行自动修正。

【注意】eslint 的 auto-fix,能够修复的规范问题比较有限。

比如,ESLint 对于 console.log 是不会帮你移除的,还要就是声明的变量未使用到,同样不会帮你移除,它只会帮你添加分号与替换双引号。其他需要较大变动才能修复的规范问题,eslint 无法自动修复。如:单行不能超过 80 个字符。

(3)下载VSCode插件

img

像上面这样每次想知道文件中是否错误都要执行一次 eslint xxx.js 指令 ,很麻烦的,如果我们想一边写代码时候就一边发现错误,就及时更改,我们就需要安装 vscode 的 ESLint 插件。安装完成 ESLint 插件后,插件会根据项目根目录下的配置文件,校验代码格式。我们就会发现 鼠标指向代码时就能看到了警告与错误提示 ,那么我们怎么做到保存时自动校验并修正代码呢,我们需要给setting.json添加如下配置项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
"editor.formatOnType": true, // 控制编辑器在键入一行后是否自动格式化该行
"editor.formatOnSave": true, // 在保存时格式化文档
"eslint.codeAction.showDocumentation": {
"enable": true
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
},
"eslint.validate": [ // 检测语言
"javascript",
"javascriptreact",
"html",
"vue",
"typescript",
"typescriptreact",
"markdown"
]

这样,对于可自动修复的格式错误,在保存文件时,eslint会自动帮我们修复。

此外,如果项目对格式强制要求,还可加载husky和lint-staged在commit前对更改的代码做lint校验(前者用来给git流程添加钩子,后者用来给只更改的代码而不是整个项目做lint),lint不通过则不予commit。防止部分团队成员在eslint不通过时仍然提交代码。

3. ESLint其他依赖介绍

依赖 作用描述
eslint ESLint 核心库
eslint-config-prettier 关掉所有和 Prettier 冲突的 ESLint 的配置
eslint-plugin-prettier 将 Prettier 的 rules 以插件的形式加入到 ESLint 里面
eslint-plugin-vue 为 Vue 使用 ESlint 的插件
@typescript-eslint/eslint-plugin ESLint 插件,包含了各类定义好的检测 TypeScript 代码的规范
@typescript-eslint/parser ESLint 的解析器,用于解析 TypeScript,从而检查和规范 TypeScript 代码

ESLint中使用Prettier

1. 安装 eslint + prettier

(如果已安装请跳过直接进入下一步)

1
yarn add eslint prettier -D

2. 安装 eslint-config-prettier

1
yarn add eslint-config-prettier -D

(1)该依赖的作用是:

让所有可能会与 prettier 规则存在冲突的 eslint rule失效,并使用 prettier 的规则进行代码检查。

相当于,用 prettier 的规则,覆盖掉 eslint:recommended 的部分规则。

(2)使用:修改.eslintrc.js

1
2
3
{
"extends": ["eslint:recommended", "prettier"]
}

3. 安装 eslint-plugin-prettier

1
yarn add eslint-plugin-prettier -D

(1)作用是将 prettier 的能力集成到 eslint 中。按照 prettier 的规则检查代码规范性,并进行修复。

(2)使用:修改.eslintrc.js

1
2
3
4
5
6
7
8
9
10
11
12
{
"rules":{
"prettier/prettier":"error" // 不符合 prettier 规则的代码,要进行错误提示(红线)
},

"plugins": ["prettier"]
}

// 或者
{
"extends": ["eslint:recommended","plugin:prettier/recommended"]
}

使用

1
npx eslint --fix main.js

至此,eslint 会拥有和 prettier 一样的修复能力。像 prettier 一样,格式化所有不符合规范的代码。

4. 小结

  • eslint、prettier、VSCode相关插件(ESLint、Prettier - Code formatter)的关系?
    prettier主要关注代码格式,比如单双引号、单行代码长度等。eslint同时关注代码质量(如声明变量未使用)和代码格式,但是对于代码格式,eslint只能处理js文件。所以一般情况下prettier和eslint合起来使用。当配置后两者的配置文件后,便可以通过命令行对某个文件进行格式化。
    当安装VSCode插件后,可以直接通过快捷键shift + Alt + F来进行格式化。
    当进一步配置了VSCode的Settings.json中的"editor.formatOnSave": true后,保存代码后自动进行格式化。

Git流程规范配置

Git流程规范配置


样式规范工具(StyleLint)

1. 下载 StyleLint 相关依赖

1
npm i stylelint stylelint-config-html stylelint-config-recommended-scss stylelint-config-recommended-vue stylelint-config-standard stylelint-config-standard-scss stylelint-config-recess-order postcss postcss-html stylelint-config-prettier -D

img

2. 安装 Vscode 插件(StyleLint):

img

3. 在目录的 .vscode 文件夹下新建 settings.json:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"editor.formatOnSave": true,
"stylelint.enable": true,
"editor.codeActionsOnSave": {
"source.fixAll.stylelint": true
},
"stylelint.validate": [
"css",
"less",
"postcss",
"scss",
"vue",
"sass",
"html"
],
"files.eol": "\n"
}

4. 配置 StyleLint(.stylelintrc.js):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// @see: https://stylelint.io

module.exports = {
/* 继承某些已有的规则 */
extends: [
"stylelint-config-standard", // 配置stylelint拓展插件
"stylelint-config-html/vue", // 配置 vue 中 template 样式格式化
"stylelint-config-standard-scss", // 配置stylelint scss插件
"stylelint-config-recommended-vue/scss", // 配置 vue 中 scss 样式格式化
"stylelint-config-recess-order", // 配置stylelint css属性书写顺序插件,
"stylelint-config-prettier", // 配置stylelint和prettier兼容
],
overrides: [
// 扫描 .vue/html 文件中的<style>标签内的样式
{
files: ["**/*.{vue,html}"],
customSyntax: "postcss-html",
},
],
/**
* null => 关闭该规则
*/
rules: {
"value-keyword-case": null, // 在 css 中使用 v-bind,不报错
"no-descending-specificity": null, // 禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器
"function-url-quotes": "always", // 要求或禁止 URL 的引号 "always(必须加上引号)"|"never(没有引号)"
"string-quotes": "double", // 指定字符串使用单引号或双引号
"unit-case": null, // 指定单位的大小写 "lower(全小写)"|"upper(全大写)"
"color-hex-case": "lower", // 指定 16 进制颜色的大小写 "lower(全小写)"|"upper(全大写)"
"color-hex-length": "long", // 指定 16 进制颜色的简写或扩写 "short(16进制简写)"|"long(16进制扩写)"
"rule-empty-line-before": "never", // 要求或禁止在规则之前的空行 "always(规则之前必须始终有一个空行)"|"never(规则前绝不能有空行)"|"always-multi-line(多行规则之前必须始终有一个空行)"|"never-multi-line(多行规则之前绝不能有空行。)"
"font-family-no-missing-generic-family-keyword": null, // 禁止在字体族名称列表中缺少通用字体族关键字
"block-opening-brace-space-before": "always", // 要求在块的开大括号之前必须有一个空格或不能有空白符 "always(大括号前必须始终有一个空格)"|"never(左大括号之前绝不能有空格)"|"always-single-line(在单行块中的左大括号之前必须始终有一个空格)"|"never-single-line(在单行块中的左大括号之前绝不能有空格)"|"always-multi-line(在多行块中,左大括号之前必须始终有一个空格)"|"never-multi-line(多行块中的左大括号之前绝不能有空格)"
"property-no-unknown": null, // 禁止未知的属性(true 为不允许)
"no-empty-source": null, // 禁止空源码
"declaration-block-trailing-semicolon": null, // 要求或不允许在声明块中使用尾随分号 string:"always(必须始终有一个尾随分号)"|"never(不得有尾随分号)"
"selector-class-pattern": null, // 强制选择器类名的格式
"scss/at-import-partial-extension": null, // 解决不能引入scss文件
"value-no-vendor-prefix": null, // 关闭 vendor-prefix(为了解决多行省略 -webkit-box)
"selector-pseudo-class-no-unknown": [
true,
{
ignorePseudoClasses: ["global", "v-deep", "deep"],
},
],
},
};

项目多环境配置

vue2项目的环境默认一共有三种: development(开发环境)、test(测试环境)、production(生产环境)

1. 配置文件

你可以在你的项目根目录中放置下列文件来指定环境变量:

1
2
3
4
.env                # 在所有的环境中被载入
.env.local # 在所有的环境中被载入,但会被 git 忽略
.env.[mode] # 只在指定的模式中被载入 mode: development\test\production
.env.[mode].local # 只在指定的模式中被载入,但会被 git 忽略

在Vue项目中,通常配置文件有:

(1)env 全局默认配置文件,无论什么环境都会加载合并

(2).env.development 开发环境下的配置文件

(3).env.production 生产环境下的配置文件

2. 属性名规则

请注意,只有 NODE_ENV,BASE_URL 和以 VUE_APP_ 开头的变量将通过 webpack.DefinePlugin 静态地嵌入到客户端侧的代码中。

除了 VUE_APP_* 变量之外,在你的应用代码中始终可用的两个特殊的变量:

● NODE_ENV :会是 “development”、”production” 或 “test” 中的一个。具体的值默认取决于应用运行的模式。这也就是为什么在package.json中配置”serve”: “vue-cli-service serve”而不是”serve”: “vue-cli-service serve –mode development”,但本地npm run serve时仍然是正确加载.env.development配置文件的原因。

● BASE_URL:会和 vue.config.js 中的 publicPath 选项相同,即你的应用会部署到的基础路径。

所以NODE_ENV和BASE_URL不用在.env.*中定义也可以直接通过process.env获取到,而想要定义其他变量,属性名必须以VUE_APP_开头,否则外部获取不到值。

3. 使用

直接调用process.env属性(全局属性,任何地方无论js还是vue中都可以使用)

img

4. 自定义配置文件

(1)创建文件:.env.prod

1
2
3
4
5
# 指定环境
NODE_ENV = 'production'

# 配置变量
VUE_APP_BASE_API = '/prod-api'

(2)修改启动命令

1
2
3
4
5
6
// package.json
"scripts": {
"serve": "vue-cli-service serve",
"serve-prod": "vue-cli-service serve --mode prod",
"build": "vue-cli-service build",
},

browserslist

Browserslist 帮助我们在浏览器兼容性和包大小之间保持适当的平衡。使用 Browserslist,可以做到覆盖更广泛的受众(浏览器),同时包的体积也会保持最小化。Browserslist包在安装 webpack 的时候自动下载。

1. 配置方式

在工程中使用 Browserslist 有两种常见方式:① 在 package.json 相应字段中增加;② 独立的 browserslistrc 文件

(1)在 package.json 中声明

1
2
3
4
5
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]

(2)通过 browserslistrc 配置

1
2
3
4
# Browsers that we support
> 1%
last 2 versions
not ie <= 8

两种方式没有差异,大家根据自己习惯或者各自团队规范进行管理即可。(我们采用的是单独文件方式)

2. 受众浏览器选择

如果你所负责的工程受众是固定的,或者说你们可以自由做主支撑哪些浏览器,那太幸运了,你可以跳过这节,直接根据特定浏览器配置即可。

但往往我们很难决定应该支持哪些浏览器?只最新 Chrome 版本?还是要都兼容包括 IE11?caniuse-liteCan I Use 可以提供相应的数据支撑,Browserslist 也是依据此数据。

img

市场占用了大于 0.3% 且持续维护的具体浏览器及版本。

img

我们可以发现了,>0.3%, and not dead 的浏览器占据了整个的 89.5%。

当然,你也可以根据地区来选择,如中国地区使用率大于 0.3%的。

img

由于中国移动端普及率比较高,所以整体上面的整体覆盖率只有 79.5%,剩余的有众多各种 for Android 的浏览器版本。

3. 如何配置

通过上述方式,我们可以圈定我们也支持哪些浏览器及版本,接下来就是如何通过 browserslist 进行配置?

(1)可以通过 https://browsersl.ist/ 这个网站来查看,你配置的内容具体支持的浏览器情况可以选择在全球、某个地区或某个国家/地区拥有超过或低于一定规模观众的版本

1
2
"> 5%":  代表着兼容全球超过5%人使用的浏览器  
">= 5% in US": 代表兼容美国使用率大于等于5% 的浏览器

(2)选择最近的浏览器版本

1
2
"last 2 versions": 表示所有浏览器兼容到最后两个版本
"last 2 Chrome versions chrome": 表示兼容Chrome浏览器最新2个版本

(3)特定浏览器版本

1
2
3
4
"Chrome > 100 chrome": 浏览器版本大于100
"not Firefox ESR": 排除 Firefox ESR
"not ie <=8" : 表示兼容IE浏览器版本大于8(实则用npx browserslist 跑出来不包含IE9 )
"safari >=7": 表示兼容safari浏览器版本大于等于7

(4)选择支持特定功能的浏览器版本

1
2
"supports es6-module": 支持 es6-module 的浏览器
"supports css-grid": 支持 css-grid 的浏览器

(5)以上条件可以组合

1
2
3
"> 0.5%, last 2 versions": 使用率大于0.5% 或者 所有浏览器最新2个版本(等价于 > 0.5% or last 2 versions)
"> 0.5% and last 2 versions": 使用率大于0.5% 的浏览器最新2个版本
"defaults": 等价于 > 0.5%, last 2 versions, Firefox ESR, not dead

你可以用如下查询条件来限定浏览器和 node 的版本范围(大小写不敏感):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
> 5%: 基于全球使用率统计而选择的浏览器版本范围。>=,<,<=同样适用。
> 5% in US : 同上,只是使用地区变为美国。支持两个字母的国家码来指定地区。
> 5% in alt-AS : 同上,只是使用地区变为亚洲所有国家。这里列举了所有的地区码。
> 5% in my stats : 使用定制的浏览器统计数据。
cover 99.5% : 使用率总和为99.5%的浏览器版本,前提是浏览器提供了使用覆盖率。
cover 99.5% in US : 同上,只是限制了地域,支持两个字母的国家码。
cover 99.5% in my stats :使用定制的浏览器统计数据。
maintained node versions :所有还被 node 基金会维护的 node 版本。
node 10 and node 10.4 : 最新的 node 10.x.x 或者10.4.x 版本。
current node :当前被 browserslist 使用的 node 版本。
extends browserslist-config-mycompany :来自browserslist-config-mycompany包的查询设置
ie 6-8 : 选择一个浏览器的版本范围。
Firefox > 20 : 版本高于20的所有火狐浏览器版本。>=,<,<=同样适用。
ios 7 :ios 7自带的浏览器。
Firefox ESR :最新的火狐 ESR(长期支持版) 版本的浏览器。
unreleased versions or unreleased Chrome versions : alpha 和 beta 版本。
last 2 major versions or last 2 ios major versions :最近的两个发行版,包括所有的次版本号和补丁版本号变更的浏览器版本。
since 2015 or last 2 years :自某个时间以来更新的版本(也可以写的更具体since 2015-03或者since 2015-03-10)
dead :通过last 2 versions筛选的浏览器版本中,全球使用率低于0.5%并且官方声明不在维护或者事实上已经两年没有再更新的版本。目前符合条件的有 IE10,IE_Mob 10,BlackBerry 10,BlackBerry 7,OperaMobile 12.1。
last 2 versions :每个浏览器最近的两个版本。
last 2 Chrome versions :chrome 浏览器最近的两个版本。
defaults :默认配置> 0.5%, last 2 versions, Firefox ESR, not dead。
not ie <= 8 : 浏览器范围的取反。
#可以添加not在任和查询条件前面,表示取反

了解了上述配置语法,配置完成后,你可以上述提到的 https://browsersl.ist/ 进行实时查看。除此,你也可以通过下述工具,来检测配置是否正确和支撑的具体浏览器版本。

4. 如何检查配置是否正确?

1
2
3
$ npx browserslist-lint
missedNotDead The not dead query skipped when using last N versions query
✖ 1 problems

需要追加 not dead,但谨慎使用,其会过滤到不再支持的浏览器,如IE11

img

5. 如何查看配置的内容,支撑哪些浏览器?

1
2
3
4
5
6
7
8
9
$ npx browserslist

and_chr 95
chrome 95
chrome 94
safari 15
safari 14.1
samsung 15.0
...

至此,你就可以通过简单的几行命令,来控制要支持的浏览器情况,剩下的就交给 browserslist 即可。