在项目开发中,涉及多人开发,在一定程度内统一代码风格,在编码过程中及时校验语法的合法性十分重要。
vetur
vetur是vscode下的辅助Vue开发的一款插件,它有如下功能:
1. 语法高亮:
支持.vue文件的语法高亮,除了支持template模板以外,还支持大多数主流前端开发脚本,比如sass、less、TypeScript等:
2.你可以使用一些snippet来编写不同的脚本,比如在script中申明 lang="ts" 来开发TypeScript;
<script lang="ts">
// Use TS snippets here
</script>
3.错误检测、格式检查
Vetur 错误检测支持以下脚本:
- template: html
- style: css, scss, less
- script: js, ts
可以在设置中的 settings.json 文件关闭 检测,修改 vetur.validation.template/style/script 为false即可。
Vetur通过eslint-plugin-vue
来做模版检查,默认情况下通过vue/essential
给vue2项目设置规则,通过vue3-essential
给vue3项目设置规则.
如果你想配置ESLint规则,请执行以下步骤:
- 使用Vetur.validate.template: false关闭Vetur的模板验证
- 确保你有ESLint插件。错误提示将来自ESLint插件,而不是Vetur。
- 在你的工作区根目录中添加-D
eslint
eslint-plugin-vue
- 在.eslintrc中设置ESLint规则。例如:
.vscode
vscode
可以配置代码格式规则,可以在设置中全局配置;但是有时候面对不同的项目要求不同的规则,又或者是能让项目里的开发成员能统一一套规则而不需要再去配置,这时候就需要一个可配置的文件在项目里面,相关vscode
的setting可以跟着项目走,我们可以在项目根目录下创建.vscode
文件夹,里面创建一个setting.json
文件,下面是本人项目的配置,项目中用了eslint-plugin-prettier
prettier
:
eslint-plugin-prettier作用:会调用prettier对代码风格进行检查。
- 先使用prettier对代码格式化
- 然后与格式化之前的代码进行对比,如果不一致,这个地方就会被prettier进行标记
{
"liveServer.settings.port": 5501,
"editor.tabSize": 2, // tab锁进
"editor.tabCompletion": "on", // 用来在出现推荐值时,按下Tab键是否自动填入最佳推荐值
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true, // 在保存时,修复eslint提示
"source.organizeImports": true, // 在保存时,让import语句按照字母顺序进行排列
},
// 让vue中的js按"prettier"格式进行格式化
"vetur.format.options.tabSize": 2,
"vetur.format.options.useTabs": false,
"vetur.validation.template": true,
"vetur.format.defaultFormatter.html": "prettier",
"vetur.format.defaultFormatter.pug": "prettier",
"vetur.format.defaultFormatter.css": "prettier",
"vetur.format.defaultFormatter.postcss": "prettier",
"vetur.format.defaultFormatter.scss": "prettier",
"vetur.format.defaultFormatter.less": "prettier",
"vetur.format.defaultFormatter.stylus": "stylus-supremacy",
"vetur.format.defaultFormatter.js": "vscode-typescript",
"vetur.format.defaultFormatter.ts": "vscode-typescript",
"vetur.format.defaultFormatter.sass": "sass-formatter",
"typescript.preferences.quoteStyle": "single",
"typescript.format.insertSpaceBeforeFunctionParenthesis": true, // 函数圆括号前面要空格
"typescript.format.insertSpaceAfterConstructor": true, // 构造函数名后面需要空格 ?
"javascript.preferences.quoteStyle": "single",
"javascript.format.insertSpaceBeforeFunctionParenthesis": true,
"javascript.format.insertSpaceAfterConstructor": true,
"less.lint.duplicateProperties": "warning",
"less.lint.float": "warning",
"less.lint.idSelector": "warning",
"less.lint.important": "warning",
"less.lint.universalSelector": "warning",
"scss.lint.duplicateProperties": "warning",
"scss.lint.float": "warning",
"scss.lint.idSelector": "warning",
"scss.lint.important": "warning",
"scss.lint.universalSelector": "warning",
}
Eslint
下面是本人项目中的eslint配置,在安装好相关依赖之后,在项目根目录下创建eslint.rc文件,配置如下:
/**
* 参考文档
* 【eslint英文文档】https://eslint.org/docs/user-guide/configuring
* 【eslint中文文档】http://eslint.cn/docs/rules/
*/
module.exports = {
root: true, // 标识当前配置文件为eslint的根配置文件,让其停止在父级目录中继续寻找。
env: {
/**
* 运行环境
* 一个环境定义了一组预定义的全局变量
* 获得了特定环境的全局定义,就不会认为是开发者定义的,跳过对其的定义检测。否则会被认为改变量未定义
*/
browser: true,
es2020: true,
node: true
},
parserOptions: {
ecmaVersion: 11, // 支持的ES语法版本
/**
* 这里出现 parser 的原因
* 官方说明中,parserOptions的配置参数是不包括 parser 的
* 这里的写 parser 是 eslint-plugin-vue 的要求,是 eslint-plugin-vue 的自定义参数
* 根据官方文档,eslint-plugin-vue 插件依赖 「vue-eslint-parser」解析器。「vue-eslint-parser」解析器,只解析 .vue 中html部分的内容,不会检测<script>中的JS内容。
* 由于解析器只有一个,用了「vue-eslint-parser」就不能用「babel-eslint」。所以「vue-eslint-parser」的做法是,在解析器选项中,再传入一个解析器选项parser。从而在内部处理「babel-eslint」,检测<script>中的js代码
* 所以这里出现了 parser
*/
parser: 'babel-eslint', // 一个对Babel解析器的包装,babel本身也是js解析器的一种,如果代码需要babel转化,则使用这个解析器。解析器必须是本地安装的一个模块,所以必须在本地node_modules中
sourceType: 'module', // 指定JS代码来源的类型,script(script标签引入?) | module(es6的module模块),此处采用module
},
/**
* 插件
* http://eslint.cn/docs/user-guide/configuring#configuring-plugins
* 插件同样需要在node_module中下载
* 注意插件名忽略了「eslint-plugin-」前缀,所以在package.json中,对应的项目名是「eslint-plugin-vue」
* 插件的作用类似于解析器,用以扩展解析器的功能,用于检测非常规的js代码。也可能会新增一些特定的规则。
* 如 eslint-plugin-vue,是为了帮助我们检测.vue文件中 <template> 和 <script> 中的js代码
*/
plugins: ['vue'],
/**
* 规则继承
* http://eslint.cn/docs/user-guide/configuring#extending-configuration-files
* 可继承的方式有以下几种
* 1、eslint内置推荐规则,就只有一个,即「eslint:recommended」
* 2、可共享的配置,是一个 npm 包,它输出一个配置对象。即通过npm安装到node_module中,可共享的配置可以省略包名的前缀 eslint-config-
* 3、从插件中获取的规则,书写规则为 「plugin:插件包名/配置名」,其中插件报名也是可以忽略「eslint-plugin-」前缀。如'plugin:vue/essential'
* 4、从配置文件中继承,即继承另外的一个配置文件,如'./node_modules/coding-standard/eslintDefaults.js'
*/
extends: [
"eslint:recommended",
/**
* vue 的额外添加的规则是 v-if, v-else 等指令检测
* 额外添加的规则可查看 https://vuejs.github.io/eslint-plugin-vue/rules/
*/
"plugin:vue/essential"
],
rules: {
/**
* 自定义规则
* http://eslint.cn/docs/user-guide/configuring#configuring-rules
* "off" or 0 - turn the rule off
* "warn" or 1 - turn the rule on as a warning (doesn't affect exit code)
* "error" or 2 - turn the rule on as an error (exit code will be 1)
* 如果某项规则,有额外的选项,可以通过数组进行传递,而数组的第一位必须是错误级别。如0,1,2
* 如 'semi': ['error', 'never'], never就是额外的配置项
*/
'eol-last': ['warn', 'always'], // 要求或禁止文件末尾保留一行空行
'semi': ['error', 'never'], // 强制禁用分号
'quotes': ['warn', 'single'], // 强制使用一致的单引号
'indent': ['warn', 2, { SwitchCase: 1 }], // 强制使用一致的缩进
'eqeqeq': ['warn', 'smart'], // 要求使用 === 和 !==
'linebreak-style': [2, 'unix'], // 强制使用一致的换行符风格,用\n,不用\r\n
'space-before-function-paren': ['warn', 'always'], // 函数圆括号之前有一个空格
'comma-dangle': ['warn', 'always-multiline'], // 要求或禁止使用拖尾逗号
'comma-spacing': ['warn'], // 强制在逗号周围使用空格
'comma-style': ['warn', 'last'], // 逗号风格,要求逗号放在数组元素、对象属性或变量声明之后,且在同一行
'array-bracket-newline': ['warn', 'consistent'], // 在数组开括号后和闭括号前强制换行
'array-bracket-spacing': ['warn', 'never'], // 禁止在括号内前后使用空格
'array-element-newline': ['warn', 'consistent'], // 要求在数组元素之间使用一致的换行符
'object-curly-newline': ['warn', { consistent: true }], // 要求强制在花括号内使用一致的换行符
'object-curly-spacing': ['warn', 'always'], // 强制在花括号中使用一致的空格
'object-property-newline': ['warn', { allowAllPropertiesOnSameLine: true }], // 强制将对象的属性放在不同的行上,但所有属性都在同一行上会被允许
'block-spacing': ['warn', 'always'], // 强制在代码块中开括号前和闭括号后有空格
'brace-style': ['warn', '1tbs', { allowSingleLine: true }],
'computed-property-spacing': ['warn', 'never'], // 禁止在计算属性中使用空格
'func-call-spacing': ['warn', 'never'], // 禁止在函数标识符和其调用之间有空格
'operator-linebreak': ['warn', 'before'], // 强制操作符使用一致的换行符风格
'space-in-parens': ['warn', 'never'], // 禁止或强制圆括号内的空格
'camelcase': ['warn', { properties: 'always', ignoreDestructuring: true, ignoreImports: true }],
'no-unused-vars': ['error', { args: 'none' }],
'no-duplicate-imports': 'error',
'no-var': 'error',
'no-undef': 'error',
'no-undef-init': 'error',
'no-trailing-spaces': ['warn'],
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
"no-use-before-define": ["error", { "functions": false, "classes": false, "variables": true }],
'arrow-spacing': ['warn', { before: true, after: true }],
'key-spacing': ['warn', { 'afterColon': true }],
'block-spacing': ['warn', 'always'],
'rest-spread-spacing': ['warn', 'never'],
'space-infix-ops': ['warn', { 'int32Hint': false }], // 要求中缀操作符周围有空格
'no-multi-spaces': ['error', {}], // 禁止出现多个空格
'keyword-spacing': ['warn'],
'spaced-comment': ['warn', 'always', { exceptions: ['-', '+'] }], // 要求在注释前有空白
'semi-spacing': ['warn'], // 禁止分号前后有空格
/**
* https://eslint.vuejs.org/rules
*/
// 'vue/no-deprecated-html-element-is': ['error'],
// 'vue/no-deprecated-filter': ['error'],
// 'vue/no-deprecated-inline-template': ['error'],
// 'vue/no-deprecated-functional-template': ['error'],
// 'vue/no-deprecated-props-default-this': ['error'],
// 'vue/no-deprecated-data-object-declaration': ['error'],
'vue/no-deprecated-scope-attribute': ['error'], // 不允许使用已弃用的 scope 属性(中Vue.js版2.5.0+)
'vue/no-deprecated-slot-attribute': ['error'], // 不允许不推荐使用的 slot 属性(在Vue.js版2.6.0+)
'vue/no-deprecated-slot-scope-attribute': ['error'], // 不允许不推荐使用的 slot-scope 属性(在Vue.js版2.6.0+)
'vue/max-len': ['warn', { template: 135, code: 150, ignoreComments: true, ignoreUrls: true, ignoreRegExpLiterals: true }],
'vue/max-attributes-per-line': ['warn', { singleline: 7 }],
'vue/name-property-casing': ['warn', 'kebab-case'],
"vue/component-name-in-template-casing": ["warn", 'kebab-case'],
'vue/singleline-html-element-content-newline': 'off',
'vue/require-default-prop': 'off',
'vue/no-v-html': 'off',
'vue/arrow-spacing': ['warn', { before: true, after: true }],
'vue/block-spacing': ['warn', 'always'],
'vue/space-infix-ops': ['warn', { 'int32Hint': false }], // 要求中缀操作符周围有空格
'vue/object-curly-spacing': ['warn', 'always'],
'vue/no-multi-spaces': ['warn', {}],
'vue/html-self-closing': ['warn', { // 要求用单标签
html: {
void: 'always',
normal: 'never',
component: 'always'
},
svg: 'always',
math: 'always'
}]
},
/**
* 针对特定文件的配置
* 可以通过overrides对特定文件进行特定的eslint检测
* 特定文件的路径书写使用Glob格式,一个类似正则的路径规则,可以匹配不同的文件
* 配置几乎与 ESLint 的其他配置相同。覆盖块可以包含常规配置中的除了 extends、overrides 和 root 之外的其他任何有效配置选项,
*/
overrides: [
{
files: [
'**/__tests__/*.{j,t}s?(x)',
'**/tests/unit/**/*.spec.{j,t}s?(x)'
],
env: {
jest: true
}
}
]
};
涉及到的依赖:install --save-dev @vue/cli-plugin-eslint
@vue/eslint-config-prettier
babel-eslint eslint
eslint-import-resolver-node
eslint-plugin-prettier
eslint-plugin-vue
prettier