foreword
Hello everyone, I'm Lin Sanxin. The most difficult knowledge point is my motto in the most easy-to-understand words . The foundation is the premise of advanced is my original intention
background
In the previous two articles, I have taken you to do these two things:
- Basic construction of Vuecli
- Optimize the scaffolding after construction
Eslint
what is
Eslint
It is used to standardize JavaScript
the specification, and it focuses more on 语法方面
the specification of the specification, which is very important for the development of a team.
For example, development A uses a double equal sign ==
, while development B uses a triple equal sign ===
, which will make it difficult to troubleshoot errors after merging the code, so it should be unified ===
, this is Eslint
the main role
configure
I have already done it with you before 开发环境(development)
, 生产环境(production)
so Eslint
in which environment should it be configured? In fact, this should depend on the specifications of your team. Here I only configure it 开发环境(development)
in , because I think the grammar will only be standardized during development.
First let's install these packages
eslint
: Eslint dependencieseslint-config-airbnb-base
: Out-of-the-box solutions for Eslinteslint-plugin-import
: Supports Eslint extension configurationeslint-webpack-plugin
: A plugin that configures Eslint in webpack
npm i
eslint eslint-config-airbnb-base
eslint-plugin-import eslint-webpack-plugin
复制代码
After installation, we need to create two files in the root directory.eslintrc.js、.eslintignore
.eslintrc.js
: Eslint configuration is written here
// .eslintrc.js
module.exports = {
// 不往父级查找
root: true,
// 环境配置
env: {
node: true,
browser: true,
es6: true,
},
// 拓展规则
extends: 'airbnb-base',
// 自定义规则,会覆盖一部分拓展规则
// 具体这些参数代表什么规则,可以去eslint官网看
rules: {
'no-console': 'warn',
semi: 'off',
'eol-last': 'off',
'no-new': 'off',
'arrow-parens': 'off',
'import/no-extraneous-dependencies': 'off',
'comma-danger': 'off',
'no-useless-escape': 'off'
},
// 语言风格
parserOptions: {
// 支持import
sourceType: 'module'
}
}
复制代码
.eslintignore
: Which files to ignore Eslint detection, write here
*.sh
node_modules
*.md
*.woff
*.ttf
.vscode
.idea
dist
/public
/docs
.husky
.local
/bin
复制代码
We have only completed our Eslint
own configuration now, but our purpose is to prompt syntax errors in the terminal when developing and building, so we need to configure the Eslint
configuration webpack.dev.js
in
// webpack.dev.js
// 之前的代码...
const ESLintPlugin = require('eslint-webpack-plugin')
module.exports = merge(base, {
// 之前的代码...
plugins: [
// 之前的代码...
new ESLintPlugin({
// 运行的时候自动帮你修复错误
fix: true,
})
]
})
复制代码
In this way, you will be able npm run serve
to prompt your grammar errors in the ~~~ For example, I am now randomly making an error code
const nn = 2
nn = 1
复制代码
At this point, the terminal will report an error
vscode plugin
But we found a problem, the terminal is reporting an error, but how can the editor report an error directly when developing? like this
其实很简单,我们只需要安装一个vsCode的插件Eslint
就行了,这个插件安装完成后,它会去自动读取我们刚刚的Eslint配置
,然后进行错误提醒~~~
配置命令
我们也可以在package.json
中自己配置命令来进行代码的Eslint
检测
"scripts": {
"eslint": "eslint ./src"
}
复制代码
现在你在终端npm run eslint
就可以手动进行Eslint
检测
Prettier
是什么
Prettier
也是规范你JavaScript
的一个东西,它跟Eslint
的差别在于:
Eslint
:更侧重于规范JS语法Prettier
:更侧重于规范JS的编写规范
我举个简单的例子吧:代码加不加分号。这就是归Prettier
管的,而Prettier
是归Eslint
管的,所以说Prettier
的配置需要配置在.eslintrc
中
配置
那么配置Prettier
之前我们需要安装这些插件
prettier
:Prettier规范的依赖eslint-plugin-prettier
:能让Eslint
配置Prettier
插件
npm i prettier eslint-plugin-prettier -D
复制代码
然后我们到.eslintrc
中去配置
// .eslintrc
module.exports = {
// 刚才的代码...
// 拓展插件
plugins: ['prettier'],
// 自定义规则,会覆盖一部分拓展规则
rules: {
// 刚才的代码...
// prettier提示报错
'prettier/prettier': 'error'
},
// 刚才的代码...
}
复制代码
vscode插件
然后如果想开发中提示的话,可以给vscode安装个Prettier
这个插件
Stylelint
是什么
Stylelint
就是规定样式的规范的,包括规则、顺序、样式用法等等
配置
我们需要安装下面的插件
stylelint
:Stylelint的依赖stylelint-config-prettier
:拓展Stylelint的规则stylelint-config-standard
:拓展Stylelint的规则stylelint-order
:拓展Stylelint样式顺序的插件stylelint-webpack-plugin
:将Stylelint配置到webpack 的插件
npm i
stylelint
stylelint-config-prettier
stylelint-config-standard
stylelint-order
stylelint-webpack-plugin
-D
复制代码
然后我们在根目录下新建一个stylelint.config.js
的文件,用来配置Stylelint
// stylelint.config.js
module.exports = {
root: true,
// 拓展插件
plugins: ['stylelint-order'],
// 拓展stylelint的规则
extends: ['stylelint-config-standard', 'stylelint-config-prettier'],
// 自定义规则
rules: {
'selector-pseudo-class-no-unknown': [
true,
{
ignorePseudoClasses: ['global'],
},
],
'selector-pseudo-element-no-unknown': [
true,
{
ignorePseudoElements: ['v-deep'],
},
],
'at-rule-no-unknown': [
true,
{
ignoreAtRules: [
'tailwind',
'apply',
'variants',
'responsive',
'screen',
'function',
'if',
'each',
'include',
'mixin',
],
},
],
'no-empty-source': null,
'named-grid-areas-no-invalid': null,
'unicode-bom': 'never',
'no-descending-specificity': null,
'font-family-no-missing-generic-family-keyword': null,
'declaration-colon-space-after': 'always-single-line',
'declaration-colon-space-before': 'never',
// 'declaration-block-trailing-semicolon': 'always',
'rule-empty-line-before': [
'always',
{
ignore: ['after-comment', 'first-nested'],
},
],
'unit-no-unknown': [
true,
{
ignoreUnits: ['rpx'],
},
],
// 自定义顺序
'order/order': [
[
'dollar-variables',
'custom-properties',
'at-rules',
'declarations',
{
type: 'at-rule',
name: 'supports',
},
{
type: 'at-rule',
name: 'media',
},
'rules',
],
{
severity: 'warning',
},
],
// 按照指定顺序排列样式
'order/properties-order': [
'position',
'content',
'top',
'right',
'bottom',
'left',
'z-index',
'display',
'float',
'width',
'height',
'max-width',
'max-height',
'min-width',
'min-height',
'padding',
'padding-top',
'padding-right',
'padding-bottom',
'padding-left',
'margin',
'margin-top',
'margin-right',
'margin-bottom',
'margin-left',
'margin-collapse',
'margin-top-collapse',
'margin-right-collapse',
'margin-bottom-collapse',
'margin-left-collapse',
'overflow',
'overflow-x',
'overflow-y',
'clip',
'clear',
'font',
'font-family',
'font-size',
'font-smoothing',
'osx-font-smoothing',
'font-style',
'font-weight',
'hyphens',
'src',
'line-height',
'letter-spacing',
'word-spacing',
'color',
'text-align',
'text-decoration',
'text-indent',
'text-overflow',
'text-rendering',
'text-size-adjust',
'text-shadow',
'text-transform',
'word-break',
'word-wrap',
'white-space',
'vertical-align',
'list-style',
'list-style-type',
'list-style-position',
'list-style-image',
'pointer-events',
'cursor',
'background',
'background-attachment',
'background-color',
'background-image',
'background-position',
'background-repeat',
'background-size',
'border',
'border-collapse',
'border-top',
'border-right',
'border-bottom',
'border-left',
'border-color',
'border-image',
'border-top-color',
'border-right-color',
'border-bottom-color',
'border-left-color',
'border-spacing',
'border-style',
'border-top-style',
'border-right-style',
'border-bottom-style',
'border-left-style',
'border-width',
'border-top-width',
'border-right-width',
'border-bottom-width',
'border-left-width',
'border-radius',
'border-top-right-radius',
'border-bottom-right-radius',
'border-bottom-left-radius',
'border-top-left-radius',
'border-radius-topright',
'border-radius-bottomright',
'border-radius-bottomleft',
'border-radius-topleft',
'quotes',
'outline',
'outline-offset',
'opacity',
'filter',
'visibility',
'size',
'zoom',
'transform',
'box-align',
'box-flex',
'box-orient',
'box-pack',
'box-shadow',
'box-sizing',
'table-layout',
'animation',
'animation-delay',
'animation-duration',
'animation-iteration-count',
'animation-name',
'animation-play-state',
'animation-timing-function',
'animation-fill-mode',
'transition',
'transition-delay',
'transition-duration',
'transition-property',
'transition-timing-function',
'background-clip',
'backface-visibility',
'resize',
'appearance',
'user-select',
'interpolation-mode',
'direction',
'marks',
'page',
'set-link-source',
'unicode-bidi',
'speak',
],
},
// 忽视文件
ignoreFiles: ['**/*.js', '**/*.jsx', '**/*.tsx', '**/*.ts'],
}
复制代码
之后我们需要把Stylelint
配置到webpack.dev.js
中去
// webpack.dev.js
// 之前的代码...
const path = require('path')
const StylelintWebpackPlugin = require('stylelint-webpack-plugin')
module.exports = merge(base, {
// 之前的代码...
plugins: [
// 之前的代码...
new StylelintWebpackPlugin({
context: 'src',
// Stylelint的配置文件读取
configFile: path.resolve(__dirname, '../stylelint.config.js'),
// 检查的文件范围
files: ['**/*.scss'],
}),
]
})
复制代码
现在scss
文件出现错误,或者顺序错误,都会报错了
vscode插件
跟之前两个插件一样,Stylelint
也可以安装一下vscode的插件Stylelint
配置命令
我们也可以在package.json
中自己配置命令来进行代码的Stylelint
检测,加上--fix
,可以自动帮你修复一些样式错误。
"scripts": {
"lint:style": "stylelint src/**/*.scss --fix"
},
复制代码
现在运行npm run lint:style
就可以检测样式错误,并自动修复部分错误了
husky
是什么
husky
就是用来规范你的git提交
的规则的,常用的是对于提交代码commit
前的Eslint、Stylelint
检测,确保提交的代码是无错误的。husky
是利用了git
的hook
配置
配置husky
需要安装下面这些包
husky
:husky所需的依赖lint-staged
:用来检测提交缓存区的代码的规范,如果不符合规范就阻止git commit@commitlint/cli
:规定git commit文本规范的依赖@commitlint/config-conventional
:规定git commit文本规范的拓展规则
npm i
husky
lint-staged
@commitlint/cli
@commitlint/config-conventional
-D
复制代码
然后我们需要在package.json
中配置命令
"scripts": {
"prepare": "husky install"
},
复制代码
这个命令的作用就是:当你项目初始npm i
之后,他会自动运行这个husky install
的命令,然后你的项目中就会出现.husky文件夹
我们在.husky文件夹
新建以下两个文件
pre-commit
:commit前所要做的事commit-msg
:commit文本检验的触发文件
接下来我们就讲讲这两个文件所有关的事情~~~
pre-commit
这个文件是用来执行代码git commit
前所做的事,那commit之前我们应该做什么事呢?我们需要对提交缓存区里的代码进行Eslint、Stylelint
的检验,如果检验到代码有语法错误,则阻止git commit
所以我们需要用到lint-staged
,先在package.json
中配置命令
"scripts": {
"lint-staged": "lint-staged"
},
复制代码
然后在根目录下创建文件.lintstagedrc
,这个文件配置的是你执行npm run lint-staged
时会做哪些事
// .lintstagedrc
{
"*.js": "eslint --fix",
"*.scss": "stylelint --fix"
}
复制代码
然后我们只需要在pre-commit
中执行这个npm run lint-staged
就行了
// .husky/pre-commit
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npm run lint-staged
复制代码
现在我们在代码中添加一段错误代码
我们提交代码
git add .
git commit -m 'msg'
复制代码
此时会报错,并且阻止git commit
commit-msg
这是校验git commit文本的文件
我们需要先在根目录下新建一个commitlint.config.js
,用来配置git commit的文本规范
// commitlint.config.js
module.exports = {
// ↓忽略包含init的提交消息
ignores: [(commit) => commit.includes('init')],
// ↓按照传统消息格式来验证
extends: ['@commitlint/config-conventional'],
// 自定义解析器
parserPreset: {
// 解析器配置
parserOpts: {
// commit 提交头的规则限制
headerPattern: /^(\w*|[\u4e00-\u9fa5]*)(?:[\(\(](.*)[\)\)])?[\:\:] (.*)/,
// 匹配分组
headerCorrespondence: ['type', 'scope', 'subject'],
// 引用
referenceActions: [
'close',
'closes',
'closed',
'fix',
'fixes',
'fixed',
'resolve',
'resolves',
'resolved',
],
// 对应issue要携带#符号
issuePrefixes: ['#'],
// 不兼容变更
noteKeywords: ['BREAKING CHANGE'],
fieldPattern: /^-(.*?)-$/,
revertPattern: /^Revert\s"([\s\S]*)"\s*This reverts commit (\w*)\./,
revertCorrespondence: ['header', 'hash'],
// warn () { },
mergePattern: null,
mergeCorrespondence: null,
},
},
// ↓自定义提交消息规则
rules: {
// ↓body以空白行开头
'body-leading-blank': [2, 'always'],
// ↓footer以空白行开头
'footer-leading-blank': [1, 'always'],
// ↓header的最大长度
'header-max-length': [2, 'always', 108],
// ↓subject为空
'subject-empty': [2, 'never'],
// ↓type为空
'type-empty': [2, 'never'],
// ↓type的类型
'type-enum': [
2,
'always',
[
'feat',
'fix',
'perf',
'style',
'docs',
'test',
'refactor',
'build',
'ci',
'chore',
'revert',
'wip',
'workflow',
'types',
'release',
'update',
],
],
},
}
复制代码
然后我们只需要在commit-msg
文件中取读取这个规范,并对提交文本进行相对应的规范就行
// commit-msg
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx --no-install commitlint --edit "$1"
复制代码
现在试一下
git add .
git commit -m 'sdsdsdsd'
复制代码
这个提交文本是不符合规范的所以会报错
只有符合规范的文本才能完成提交
git add .
git commit -m 'fix: 修改bug'
复制代码
.gitignore
.gitignore
的作用是可以忽略git
提交的文件夹,比如node_modules
所以我们需要在根目录下新建一个.gitignore
文件
// .gitignore
node_modules
复制代码
vscode设置
最后分享一下我的vscode
设置,只需要在根目录下新建.vscode
文件夹,然后在此文件夹中新建setting.json
,这个文件夹就是本项目工作区间的vscode设置
// .vscode/setting.json
{
//========================================
//============== 编辑器 ===================
//========================================
// 光标的动画样式
"editor.cursorBlinking": "phase",
// 光标是否启用平滑插入的动画
"editor.cursorSmoothCaretAnimation": true,
// vscode重命名文件或移动文件自动更新导入路径
"typescript.updateImportsOnFileMove.enabled": "always",
// 自动替换为当前项目的内置的typescript版本
"typescript.tsdk": "./node_modeles/typescript/lib",
// 一个制表符占的空格数(可能会被覆盖)
"editor.tabSize": 2,
// 定义一个默认和的格式程序 (prettier)
"editor.defaultFormatter": "esbenp.prettier-vscode",
// 取消差异编辑器忽略前空格和尾随空格的更改
"diffEditor.ignoreTrimWhitespace": false,
// 定义函数参数括号前的处理方式
"javascript.format.insertSpaceBeforeFunctionParenthesis": true,
// 在键入的时候是否启动快速建议
"editor.quickSuggestions": {
"other": true,
"comments": true,
"strings": true
},
//========================================
//============== Other ===================
//========================================
// 启用导航路径
"breadcrumbs.enabled": true,
//========================================
//============== Other ===================
//========================================
// 按下Tab键展开缩写 (例如Html的div,在键入的时候按Tab,快捷生成出来)
"emmet.triggerExpansionOnTab": true,
// 建议是否缩写 (如Html的<div />)
"emmet.showAbbreviationSuggestions": true,
// 建议是否展开 (如Html的 <div></div>)
"emmet.showExpandedAbbreviation": "always",
// 为制定语法文件定义当前的语法规则
"emmet.syntaxProfiles": {
"vue-html": "html",
"vue": "html",
"xml": {
"arrt_quotes": "single"
}
},
// 在不受支持的语言中添加规则映射
"emmet.includeLanguages": {
"jsx-sublime-babel-tags": "javascriptreact"
},
//========================================
//============== Files ==================
//========================================
// 删除行位空格
"files.trimTrailingWhitespace": true,
// 末尾插入一个新的空格
"files.insertFinalNewline": true,
// 删除新行后面的所有新行
"files.trimFinalNewlines": true,
// 默认行尾的字符
"files.eol": "\n",
// 在查找搜索的时候集成的文件
"search.exclude": {
"**/node_modules": true,
"**/*.log": true,
"**/*.log*": true,
"**/bower_components": true,
"**/dist": true,
"**/elehukouben": true,
"**/.git": true,
"**/.gitignore": true,
"**/.svn": true,
"**/.DS_Store": true,
"**/.idea": true,
"**/.vscode": false,
"**/yarn.lock": true,
"**/tmp": true,
"out": true,
"dist": true,
"node_modules": true,
"CHANGELOG.md": true,
"examples": true,
"res": true,
"screenshots": true
},
// 搜索文件夹时候排外的文件夹
"files.exclude": {
"**/bower_components": true,
"**/.idea": true,
"**/tmp": true,
"**/.git": true,
"**/.svn": true,
"**/.hg": true,
"**/CVS": true,
"**/.DS_Store": true,
"**/node_modules": false
},
// 文件监视器排外的文件 可减少初始化打开项目的占用大量cpu
"files.watcherExclude": {
"**/.git/objects/**": true,
"**/.git/subtree-cache/**": true,
"**/.vscode/**": true,
"**/node_modules/**": true,
"**/tmp/**": true,
"**/bower_components/**": true,
"**/dist/**": true,
"**/yarn.lock": true
},
"stylelint.enable": true,
"stylelint.packageManager": "yarn",
//========================================
//============== Eslint ==================
//========================================
// 状态栏显示Eslint的开启状态
"eslint.alwaysShowStatus": true,
// Eslint的选项
"eslint.options": {
// 要检查的文件拓展名数组
"extensions": [".js", ".jsx", ".ts", ".tsx", ".vue"]
},
// Eslint校验的
"eslint.validate": [
"javascript",
"typescript",
"reacttypescript",
"reactjavascript",
"html",
"vue"
],
//========================================
//============== Prettier ================
//========================================
// 使用当前项目的prettier配置文件,如果没有则使用默认的配置
"prettier.requireConfig": true,
"editor.formatOnSave": true,
// 以下程序使用prettier默认进行格式化
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[css]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[less]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[scss]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[markdown]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
// 保存文件的时候的配置
"editor.codeActionsOnSave": {
// 使用Eslint格式化代码
"source.fixAll.eslint": true,
// 使用stylelint格式化代码
"source.fixAll.stylelint": true
},
"[vue]": {
"editor.codeActionsOnSave": {
// 使用Eslint格式化代码
"source.fixAll.eslint": true,
// 使用stylelint格式化代码
"source.fixAll.stylelint": true
},
"editor.defaultFormatter": "johnsoncodehk.volar"
},
"compile-hero.disable-compile-files-on-did-save-code": true,
"i18n-ally.localesPaths": ["src/locales", "src/locales/lang"]
}
复制代码
整体结构
到这里我们就完成我们的脚手架三件套了
- 基本搭建
- 基本优化
- 基本规范
结语
我是林三心,一个热心的前端菜鸟程序员。如果你上进,喜欢前端,想学习前端,那咱们可以交朋友,一起摸鱼哈哈,摸鱼群,点这个 --> 摸鱼沸点