上一篇文章《Vue3技术栈:ESLint、TypeScript和Prettier配置》,我们主要拆解了在vue3项目中,如何去配置和使用相关规则。那么,如果我们想要把以上规则整理成团队规范,作为基础npm包使用,这里该如何配置呢…

系列文章:


一、各模块

package 根目录为eslint-config

1.ts相关

文件目录为:eslint-config/ts.js

【TypeScript ESLint 配置规则】详细解释

const strictRules = require('./rules/ts-strict')

// 禁用 strictRules 中定义的所有规则
const targetRules = Object.keys(strictRules.rules).reduce(function (
  acc,
  ruleName
) {
  acc[ruleName] = ['off']
  return acc
},
{})

module.exports = {
  parser: '@typescript-eslint/parser', // 解析 TypeScript 代码
  plugins: ['@typescript-eslint'], // 提供 TypeScript 相关的 ESLint 规则
  extends: [
    require.resolve('./js.js'), // 引入基础 JavaScript 规则
    'plugin:@typescript-eslint/recommended', // 引入 TypeScript 推荐的 ESLint 规则
    'plugin:@typescript-eslint/recommended-requiring-type-checking', // 引入需要类型检查的 TypeScript 推荐规则
    'prettier/@typescript-eslint', // 确保 Prettier 格式化不会被 ESLint 覆盖
  ],
  rules: Object.assign(targetRules, {
    // 默认情况下,禁用此规则可能会导致未处理的Promise错误被忽略。建议开启并在具体情况下使用注释禁用
    '@typescript-eslint/no-floating-promises': ['warn'], // 对未处理的 Promise 发出警告
    // 规则配置非常全面,但建议保留 `extendDefaults: true`,以确保其他默认配置仍然有效
    '@typescript-eslint/ban-types': [
      'error',
      {
        extendDefaults: true, // 保留默认配置
        types: {
          String: {
            message: 'Use string instead',
            fixWith: 'string',
          },
          Boolean: {
            message: 'Use boolean instead',
            fixWith: 'boolean',
          },
          Number: {
            message: 'Use number instead',
            fixWith: 'number',
          },
          Symbol: {
            message: 'Use symbol instead',
            fixWith: 'symbol',
          },
          Function: {
            message: [
              'The `Function` type accepts any function-like value.',
              'It provides no type safety when calling the function, which can be a common source of bugs.',
              'It also accepts things like class declarations, which will throw at runtime as they will not be called with `new`.',
              'If you are expecting the function to accept certain arguments, you should explicitly define the function shape.',
            ].join('\n'),
          },
          Object: {
            message: [
              'The `Object` type actually means "any non-nullish value", so it is marginally better than `unknown`.',
              '- If you want a type meaning "any object", you probably want `Record<string, unknown>` instead.',
              '- If you want a type meaning "any value", you probably want `unknown` instead.',
            ].join('\n'),
          },
          '{}': {
            message: [
              '`{}` actually means "any non-nullish value".',
              '- If you want a type meaning "any object", you probably want `Record<string, unknown>` instead.',
              '- If you want a type meaning "any value", you probably want `unknown` instead.',
            ].join('\n'),
          },
        },
      },
    ],
    // 允许空箭头函数、函数和方法
    '@typescript-eslint/no-empty-function': [
      'error',
      {
        allow: ['arrowFunctions', 'functions', 'methods'],
      },
    ],
    // 允许空箭头函数、函数和方法,警告未使用的变量,但忽略函数参数是一个合理的选择
    '@typescript-eslint/no-unused-vars': ['warn', { args: 'none' }],
    '@typescript-eslint/prefer-regexp-exec': ['off'], // 禁用 prefer-regexp-exec 警告
    // 确保 Promise 的误用被检测,但忽略 void 返回检查
    '@typescript-eslint/no-misused-promises': [
      'error',
      { checksVoidReturn: false },
    ],
    'no-undef': 'off', // 禁用 no-undef 规则,避免在 TypeScript 项目中误报
  }),
}

2.vue3相关

文件目录为:eslint-config/vue3.js

【Vue3 ESLint 配置规则】详细解释

module.exports = {
  // 使用 vue-eslint-parser 解析器,以便解析 .vue 文件
  parser: 'vue-eslint-parser',
  parserOptions: {
    parser: '@typescript-eslint/parser', // 使用 @typescript-eslint/parser 解析 .ts 和 .tsx 类型的 TypeScript 代码文件
    ecmaVersion: 2020, // 支持 ECMAScript 2020 特性
    sourceType: 'module', // 代码使用 ES 模块
    ecmaFeatures: {
      jsx: true, // 支持 JSX
    },
  },
  extends: [
    'plugin:vue/vue3-recommended', // Vue 3 推荐规则
    '@vue/typescript/recommended', // Vue + TypeScript 推荐规则
    'prettier', // 使用 Prettier 格式化代码,确保 Prettier 格式化的代码不被 ESLint 覆盖
  ],
  plugins: ['vue'], // 使用 vue 插件
  rules: {
    'vue/component-definition-name-casing': ['off'], // 关闭组件名大小写规则,防止影响其他地方引用
    'vue/v-on-function-call': ['error', 'never'], // 禁止直接调用 v-on 事件处理函数
    'vue/require-direct-export': 'error', // 强制组件必须直接导出
    'vue/eqeqeq': 'error', // 强制使用全等 === 和不等 !== 比较
    'vue/prop-name-casing': 'off', // 关闭 prop 名大小写规则
    'vue/attribute-hyphenation': 'off', // 关闭属性连字符规则
    'vue/name-property-casing': 'off', // 关闭 name 属性大小写规则
    'vue/custom-event-name-casing': 'off', // 关闭自定义事件名大小写规则
    'vue/multi-word-component-names': 'off', // 关闭多词组件名规则,避免与 HTML 原生元素冲突
    '@typescript-eslint/no-unused-vars': 'off', // 关闭未使用变量规则
    'vue/script-setup-uses-vars': 'error', // 确保 script setup 中声明的变量在 template模板 中被正确识别
  }
};

二、整合及使用

项目结构如下:

lianpf@lianpf-PC:~/xxx/eslint-config$ tree -I 'node_modules'
.
├── rules
│   └── ...
├── js.js
├── ts.js
├── vue3.js
├── ts-vue3.js
├── index.js
├── package.json
├── README.md
├── CHANGELOG.md
└── yarn.lock

1.整合: ts-vue3package.json

i.整合ts-vue3

文件目录为:eslint-config/ts-vue3.js

【Vue 3 和 TypeScript 的 ESLint 配置规则】详细解释

module.exports = {
  extends: ['./ts.js', './vue3.js'], // 整合继承 TypeScript 和 Vue 3 的 ESLint 规则,避免重复配置
  parserOptions: {
    parser: '@typescript-eslint/parser', // 指定使用 TypeScript ESLint 解析器
    extraFileExtensions: ['.vue'], // 确保解析 `.vue` 文件(针对Vue 项目)
  },
  rules: {
    '@typescript-eslint/unbound-method': ['off'], // 禁用 unbound-method 规则,避免 this 丢失的问题。特别是在使用 `.vue` 文件和 mixins 的情况下。
  },
  overrides: [
    {
      files: ['*.vue'], // 对 `.vue` 文件应用特定的规则
      rules: {
        'vue/require-direct-export': ['off'], // 禁用 require-direct-export 规则,因为在 Vue 项目中直接导出组件不是强制要求的
      },
    },
  ],
}

ii.整合package.json

文件目录为:eslint-config/package.json

配置如下:

{
  "name": "@lianof/eslint-config",
  "version": "0.1.0",
  // ...
  "peerDependencies": {
    "eslint": "^8.56.0",
    "eslint-plugin-import": "^2.22.1"
  },
  "dependencies": {
    "babel-eslint": "^10.1.0",
    "confusing-browser-globals": "^1.0.10",
    "eslint-config-airbnb-base": "15.0.0",
    "eslint-config-prettier": "9.1.0",
    "eslint-plugin-import": "^2.22.1",
    "vue-eslint-parser": "^7.1.1"
  },
  "devDependencies": {
    "@commitlint/cli": "^8.1.0",
    "@commitlint/config-conventional": "^8.0.0",
    "@release-it/conventional-changelog": "^1.1.0",
    "@typescript-eslint/eslint-plugin": "7.14.1",
    "@typescript-eslint/parser": "7.14.1",
    "@vue/eslint-config-standard": "8.0.1",
    "@vue/eslint-config-typescript": "13.0.0",
    "commitizen": "^3.1.1",
    "cz-conventional-changelog": "^2.1.0",
    "eslint": "8.56.0",
    "eslint-plugin-vue": "9.26.0",
    "eslint-plugin-prettier": "5.1.3",
    "husky": "^3.0.0",
    "lint-staged": "^9.1.0",
    "prettier": "3.3.2",
    "typescript": "5.5.2",
    "release-it": "^12.3.3"
  },
  // ...
}

2.在其他项目中如何使用?

示例项目A目录结构:

.
├── ...
├── .eslintrc.js
├── tsconfig.json
├── package.json
├── yarn.lock
└── README.md

A/package.json:

{
  "name": "A",
  "version": "1.0.0",
  "description": "",
  "scripts": {
    // ...
    "lint": "eslint --ext .js,.vue,.ts src",
    "lint:fix": "eslint --ext .js,.vue,.ts src --fix"
  },
  "dependencies": {
    // ...
    "@lianof/eslint-config": "1.0.0"
  },
  // ...
}

A/.eslintrc.js:

module.exports = {
  // ...
  extends: [
    '@lianpf/eslint-config/ts-vue3' // 注意:路径要指到eslint-config包的【具体路径】。如这里的 `ts-vue3`
  ],
  ignorePatterns: ['.eslintrc.js'],
  rules: {
    'prettier/prettier': ['warn'],
    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
    'no-console': 'off',
    'import/no-extraneous-dependencies': 'off',
    // ------------------ 自定义 ------------------
    '@typescript-eslint/no-explicit-any': 'off'
  },
  parser: 'vue-eslint-parser',
  parserOptions: {
    parser: '@typescript-eslint/parser',
    sourceType: 'module',
    project: './tsconfig.json'
  },
  overrides: [
    {
      extends: ['plugin:@typescript-eslint/disable-type-checked'],
      files: ['./**/*.js'],
    }
  ]
}

参考


最后, 希望大家早日实现:成为编程高手的伟大梦想!
欢迎交流~

微信公众号

本文版权归原作者曜灵所有!未经允许,严禁转载!对非法转载者, 原作者保留采用法律手段追究的权利!
若需转载,请联系微信公众号:连先生有猫病,可获取作者联系方式!