前端项目构建最佳实践

239 阅读42分钟

前言

本文从通过脚手架搭建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的代码格式差异而产生的。

1. 安装插件

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

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

2. 添加配置文件

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

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

# 配置项文档: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

VSCode配置文件(Settings.json)

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

1. 用户区settings.json配置

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

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

2. 工作区settings.json配置

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

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

{
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true,
  },
  "eslint.validate": ["typescript", "javascript", "vue"]
}

jsconfig.json

如果你的项目中有一个 jsconfig.json文件的话,这个文件的配置可以对你的文件所在目录下的所有js代码做出个性化支持。

目录中存在此类文件表示该目录是JavaScript项目的根目录,否则会把打开的JavaScript文件被视为独立单元。

文件本身可以选择列出属于项目的文件,要从项目中排除的文件,以及编译器选项。

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

在不使用typescript的时候也可以对js进行ts的类型检查(因为jsconfig.json是tsconfig.json的子集,所以检查是ts的)

当我们在项目中使用了webpack的别名的时候,会发现没有办法跳转到对应文件,此时就可以在jsconfig.json中配置。

// 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"
  ]
}

compilerOptions的其他配置如下:

"compilerOptions": {
  "incremental": true, // TS编译器在第一次编译之后会生成一个存储编译信息的文件,第二次编译会在第一次的基础上进行增量编译,可以提高编译的速度
  "tsBuildInfoFile": "./buildFile", // 增量编译文件的存储位置
  "diagnostics": true, // 打印诊断信息 
  "target": "ES5", // 目标语言的版本
  "module": "CommonJS", // 生成代码的模板标准
  "outFile": "./app.js", // 将多个相互依赖的文件生成一个文件,可以用在AMD模块中,即开启时应设置"module": "AMD",
  "lib": ["DOM", "ES2015", "ScriptHost", "ES2019.Array"], // TS需要引用的库,即声明文件,es5 默认引用dom、es5、scripthost,如需要使用es的高级版本特性,通常都需要配置,如es8的数组新特性需要引入"ES2019.Array",
  "allowJS": true, // 允许编译器编译JSJSX文件
  "checkJs": true, // 允许在JS文件中报错,通常与allowJS一起使用
  "outDir": "./dist", // 指定输出目录
  "rootDir": "./", // 指定输出文件目录(用于输出),用于控制输出目录结构
  "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": [], // 加载的声明文件包
  "removeComments":true, // 删除注释 
  "noEmit": true, // 不输出文件,即编译后不会生成任何js文件
  "noEmitOnError": true, // 发送错误时不输出任何文件
  "noEmitHelpers": true, // 不生成helper函数,减小体积,需要额外安装,常配合importHelpers一起使用
  "importHelpers": true, // 通过tslib引入helper函数,文件必须是模块
  "downlevelIteration": true, // 降级遍历器实现,如果目标源是es3/5,那么遍历器会有降级的实现
  "strict": true, // 开启所有严格的类型检查
  "alwaysStrict": true, // 在代码中注入'use strict'
  "noImplicitAny": true, // 不允许隐式的any类型
  "strictNullChecks": true, // 不允许把null、undefined赋值给其他类型的变量
  "strictFunctionTypes": true, // 不允许函数参数双向协变
  "strictPropertyInitialization": true, // 类的实例属性必须初始化
  "strictBindCallApply": true, // 严格的bind/call/apply检查
  "noImplicitThis": true, // 不允许this有隐式的any类型
  "noUnusedLocals": true, // 检查只声明、未使用的局部变量(只提示不报错)
  "noUnusedParameters": true, // 检查未使用的函数参数(只提示不报错)
  "noFallthroughCasesInSwitch": true, // 防止switch语句贯穿(即如果没有break语句后面不会执行)
  "noImplicitReturns": true, //每个分支都会有返回值
  "esModuleInterop": true, // 允许export=导出,由import from 导入
  "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)下载依赖

npm install prettier -D

(2)设置配置文件

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中进行配置。配置完成后我们就可以手动通过命令行来格式化某个文件。

npx prettier main.js --write

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

(3)安装VSCode插件

img

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

{
  // 所有语言
  "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设置,实现保存即格式化。

"editor.formatOnSave": true

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

代码规范性工具(ESLint)

1. 说明

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

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

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

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

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

2. 使用

(1)eslint初始化

npm i -g eslint

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

npx eslint --init

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

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

(2)设置配置文件

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添加如下配置项:

  "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其他依赖介绍

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

ESLint中使用Prettier

1. 安装 eslint + prettier

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

yarn add eslint prettier -D

2. 安装 eslint-config-prettier

yarn add eslint-config-prettier -D

(1)该依赖的作用是:

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

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

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

{
    "extends": ["eslint:recommended", "prettier"]
}

3. 安装 eslint-plugin-prettier

yarn add eslint-plugin-prettier -D

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

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

{
    "rules":{
        "prettier/prettier":"error" // 不符合 prettier 规则的代码,要进行错误提示(红线)
    },

    "plugins": ["prettier"]
}

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

使用

npx eslint --fix main.js

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

Git流程规范配置

Git流程规范配置

样式规范工具(StyleLint)

1. 下载 StyleLint 相关依赖

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:

{
	"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):

// @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. 配置文件

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

.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

# 指定环境
NODE_ENV = 'production'

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

(2)修改启动命令

// 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 中声明

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

(2)通过 browserslistrc 配置

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

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

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

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

(3)特定浏览器版本

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

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

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

(5)以上条件可以组合

"> 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 的版本范围(大小写不敏感):

> 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在任和查询条件前面,表示取反

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

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

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

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

img

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

$ npx browserslist
 
and_chr 95
chrome 95
chrome 94
safari 15
safari 14.1
samsung 15.0
...

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