在項目開發中,涉及多人開發,在一定程度內統一代碼風格,在編碼過程中及時校驗語法的合法性十分重要。
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