Achieving Unified Code Style in Teams with vscode + vetur + eslint + prettier

Brief Idea

  • eslint has the highest priority. Install plugins eslint-config-airbnb-base, eslint-config-prettier, eslint-plugin-vue. It can override prettier settings.
  • eslint mainly handles formatting of vue/js.
  • prettier mainly handles formatting of html/css/less/scss…
  • Vetur also has formatting capabilities; disable it and use more advanced ones.
  • prettier does not support stylus, but Vetur's dependencies include stylusSupremacy, which can solve this.
  • All configurations can be placed in the project repo, with higher priority than the coder's local settings, ensuring consistent code submission across the team.
  • If other formatting plugins are installed, disable them in this project; we don't need them.

Appendix: Configuration Files

EditorConfig


root = true # Indicates the topmost configuration file. When set to true, the search for .editorconfig files stops.

[*] charset = utf-8 # Encoding format, supports latin1, utf-8, utf-8-bom, utf-16be, and utf-16le. Using uft-8-bom is not recommended. indent_style = space # tab for hard-tabs, space for soft-tabs. indent_size = 2 # Sets an integer to specify the number of columns for each indentation level and the width of soft-tabs (number of spaces). If set to tab, it will use the tab_width value (if specified). end_of_line = lf # Defines line endings, supports lf, cr, and crlf. insert_final_newline = # When set to true, ensures the file ends with a blank line; false otherwise. trim_trailing_whitespace = true # When set to true, removes any whitespace characters at the beginning of lines; false otherwise.

[*.md] insert_final_newline = false # When set to true, ensures the file ends with a blank line; false otherwise. trim_trailing_whitespace = false # When set to true, removes any whitespace characters at the beginning of lines; false otherwise.


.eslintrc.js


/**
 *
 * Rule descriptions can be found at https://cn.eslint.org/docs/rules/
 * eslint-plugin-import rules can be found at https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/default.md
 * eslint-plugin-vue rules can be found at https://github.com/vuejs/eslint-plugin-vue
 *
 * "off" or 0 - Turn off the rule
 * "warn" or 1 - Turn on the rule with a warning level (does not cause the program to exit)
 * "error" or 2 - Turn on the rule with an error level (causes the program to exit when triggered)
 *
 */

module.exports = { extends: [ // add more generic rulesets here, such as: // 'eslint:recommended', "airbnb-base", // airbnb lint specification "plugin:vue/essential", // eslint-plugin-vue "plugin:prettier/recommended" // eslint-config-prettier ], // settings: { // 'import/resolver': { // webpack: { // config: 'build/webpack.base.conf.js', // }, // }, // }, // plugins: ['vue'], rules: { "prettier/prettier": 1, "no-undef": 2, // Disallow undeclared variables unless they are mentioned in /*global / comments. e.g. / global Stomp SockJS */ in .vue file's <script> "no-extend-native": 2, // Disallow extending native types "no-return-assign": 2, // Disallow assignment in return statements "import/order": 0, // Enforce a convention in module import order "import/no-extraneous-dependencies": 0, // Forbid importing external modules that are not declared in package.json dependencies, devDependencies, optionalDependencies, or peerDependencies. The nearest parent package.json will be used. "import/no-dynamic-require": 1, // CommonJS require method is used to import modules from different files. Unlike ES6 import syntax, it can be given an expression that will be resolved at runtime. While sometimes necessary and useful, it is often not the case. Using expressions (e.g., concatenated paths and variables) as arguments makes static code analysis by tools more difficult and makes it harder to find usage locations of modules in the codebase. "import/extensions": 0, // Some file resolution algorithms allow you to omit file extensions in import source paths. For example, the Node resolver can interpret ./foo/bar as the absolute path /User/someone/foo/bar.js because the .js extension is automatically resolved by default. Depending on the resolver, you can configure more extensions to resolve automatically. "import/no-unresolved": 0, // Ensure that the imported module can be resolved to a module on the local filesystem, as defined by standard Node require.resolve behavior. "import/prefer-default-export": 1, // When there is only one export in a module, prefer using default export over named export. "vue/no-async-in-computed-properties": 1, // Computed properties should be synchronous. Asynchronous operations may not work as expected and can lead to unexpected behavior, which is why you should avoid them. If you need async computed properties, consider using another plugin [vue-async-computed] "vue/no-side-effects-in-computed-properties": 1, // Introducing side effects in computed properties is considered a very bad practice. It makes code unpredictable and difficult to understand. "vue/no-reserved-keys": 1, // This rule prevents the use of reserved names to avoid conflicts and unexpected behavior. "vue/require-v-for-key": 2, // When v-for is written on a custom component, it requires using v-bind:key. On other elements, v-bind:key is also recommended. "vue/require-valid-default-prop": 1, // This rule checks whether the default value for each prop is valid for the given type. It should report an error when using a default value with a function that does not return an array or object type. "no-unused-vars": 1, // Disallow unused variables "generator-star-spacing": 0, // Enforce consistent spacing around * in generator functions "no-plusplus": 0, // Disallow unary operators ++ and -- "func-names": 0, // Require or disallow named function expressions "no-console": 0, // no-console radix: 0, // Enforce the use of radix parameter in parseInt() "no-control-regex": 0, // Disallow control characters in regular expressions "no-continue": 0, // Disallow continue statements "no-debugger": process.env.NODE_ENV === "production" ? 2 : 0, "no-param-reassign": 1, // Disallow reassigning function parameters "no-underscore-dangle": 1, // Disallow dangling underscores in identifiers "global-require": 1, // Require require() to appear at the top-level module scope "no-var": 1, // Require let or const instead of var "vars-on-top": 1, // Require all var declarations to be at the top of their containing scope "prefer-destructuring": 1, // Prefer destructuring from arrays and objects "no-useless-concat": 1, // Disallow unnecessary string literals or template literals concatenation "no-shadow": 1, // Disallow variable declarations from shadowing variables declared in the outer scope "guard-for-in": 1, // Require an if statement in for-in loops. Aimed at preventing unexpected behavior that can arise when using for in loops without filtering the results in the loop. "no-restricted-syntax": 1, // Disallow specific syntax "global-require": 1, // Require require() to appear at the top-level module scope "consistent-return": 1, // Require return statements to either always or never specify a returned value eqeqeq: 1, // Require === and !== "no-unused-expressions": 1, // Disallow unused expressions camelcase: 1, // Enforce camelcase naming convention "block-scoped-var": 1, // Enforce variables to be used within the scope they are defined in. Aimed at reducing the use of variables outside of the binding context and mimicking traditional block scope from other languages. This helps language newcomers avoid variable hoisting pitfalls. "no-redeclare": 1, // Disallow redeclaring the same variable multiple times "prefer-arrow-callback": 1, // Require arrow functions as callbacks "array-callback-return": 1, // Enforce return statements in callbacks of array methods. Arrays have several methods for filtering, mapping, and folding. If we forget to write a return statement in these callbacks, it may be a mistake. "default-case": 1, // Require default case in switch statements "no-loop-func": 1, // Disallow function declarations and expressions inside loops "no-fallthrough": 1, // Disallow fallthrough of case statements "no-multi-assign": 1, // Disallow chain assignment "no-lonely-if": 1, // Disallow if as the only statement in an else block. If an if statement is the only statement in an else block, using an else if form is usually clearer. "no-irregular-whitespace": 1, // Disallow irregular whitespace outside of strings and comments "prefer-const": 1, // Require const declarations for variables that are never reassigned. If a variable is never reassigned, declaring it with const is better. const declaration tells the reader "this variable will never be reassigned," reducing cognitive load and improving maintainability. "no-use-before-define": 1, // Disallow using variables before they are defined "no-useless-escape": 1, // Disallow unnecessary escape characters "no-array-constructor": 1, // Disallow Array constructors. Due to the defect of single argument and the possibility of Array being redefined globally, using the constructor to construct new Array arrays is generally discouraged, preferring array literal notation. An exception is when the Array constructor is used to intentionally create a sparse array of a specific size by giving it a numeric argument. "object-shorthand": 1, // Require or disallow shorthand syntax for methods and properties in object literals "no-prototype-builtins": 1, // Disallow direct calls to Object.prototype builtins. Assuming an object will have properties from Object.prototype can lead to errors. This rule prevents calling methods from Object.prototype directly on objects. "no-nested-ternary": 1, // Disallow nested ternary expressions. Nested ternary expressions make code harder to understand. "no-new-wrappers": 1, // Disallow using new on String, Number, and Boolean. There is no reason to use these primitive wrappers as constructors. "prefer-promise-reject-errors": 1, // Require using Error objects as rejection reasons for promises "no-labels": 1 // Disallow label statements } };


.prettierrc

module.exports = {
  printWidth: 80, // Number of characters per line. If exceeded, it will wrap. Default is 80.
  tabWidth: 2, // Number of spaces per indentation level. Default is 80.
  useTabs: false, // Whether to use tabs for indentation. Default is false (spaces).
  singleQuote: true, // Whether to use single quotes for strings. Default is false (double quotes).
  semi: true, // Whether to use semicolons at the end of lines. Default is true.
  trailingComma: "es5", // Whether to use trailing commas. Three options: "<none|es5|all>"
  bracketSpacing: true // Whether to have a space between the curly braces in object literals. Default is true, e.g., { foo: bar }
  // parser: 'babylon', // Code parser engine. Default is babylon, same as babel.
};

.vscode/setting.json

{
  // Use 2 spaces as tab, and set the alignment baseline to 2 characters.
  "editor.tabSize": 2,
  // Automatically format on save, mainly for html/css/less/scss and other file formats not covered by eslint.
  // "editor.formatOnSave": true,
  // On save, automatically process vue/js/jsx/ts/json file format according to eslint configuration.
  // "eslint.autoFixOnSave": true,
  // Enable lint for vue and auto-fix.
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    {
      "language": "vue",
      "autoFix": true
    }
  ],
  // For .vue files, disable prettier and let eslint fix.
  "vetur.format.defaultFormatter.css": "none",
  "vetur.format.defaultFormatter.html": "none",
  "vetur.format.defaultFormatter.js": "none",
  "vetur.format.defaultFormatter.less": "none",
  "vetur.format.defaultFormatter.postcss": "none",
  "vetur.format.defaultFormatter.scss": "none",
  "vetur.format.defaultFormatter.stylus": "stylus-supremacy",
  "vetur.format.defaultFormatter.ts": "none",

/* stylus configuration start / // Whether to insert colons "stylusSupremacy.insertColons": false, // Whether to insert semicolons "stylusSupremacy.insertSemicolons": false, // Whether to insert braces "stylusSupremacy.insertBraces": false, // Whether to insert a new line after imports "stylusSupremacy.insertNewLineAroundImports": false, // Whether to insert a new line between selectors "stylusSupremacy.insertNewLineAroundBlocks": false / stylus configuration end */ }

评论

暂无评论。

登录后可发表评论。