likes
comments
collection
share

终极指南:打造一劳永逸的ESLint & Prettier配置库,告别繁琐配置!

作者站长头像
站长
· 阅读数 33

为什么创建自定义配置库?

使用自定义的 ESLint-config 配置库有诸多好处:

  • 统一代码风格:让团队协作更顺畅。
  • 提高开发效率:减少配置上的时间浪费。
  • 避免重复劳动:一次配置,处处使用。
  • 便于维护和升级:集中管理,轻松更新。

如何开发一个这样的 ESLint-config 呢?官方文档在开发指南下介绍了 Shareable Configs 的概念:

配置文件 .eslintrc 是项目的重要部分,可能需要在多个项目或团队之间共享。可分享的配置允许你在 npm 上发布配置,并在其他 ESLint 项目中下载使用。

那么,开始打造属于自己的 Shareable Configs 吧!💪💪

准备工作

在开始创建配置库之前,我们需要安装一些必要的工具和依赖:

// package.json精简如下。
{
  "files": [
    "lib"
  ],
  "exports": {
    ".": "./lib/index.js",
    "./vue": "./lib/configs/vue.js",
    "./vue2": "./lib/configs/vue2.js",
    "./react": "./lib/configs/react.js"
  },
  "scripts": {
    "lint": "eslint . --fix",
    "format": "ras prettier-format",
    "commit": "ras git-commit",
    "cleanup": "ras cleanup",
    "update-pkg": "ras update-pkg",
    "init-git": "ras init-git-hooks",
    "tsx": "tsx",
    "update-version": "bumpp --commit --push --tag",
    "publish-pkg": "pnpm -r publish --access public",
    "release": "pnpm update-version && pnpm publish-pkg"
  },
  "dependencies": {
    "@typescript-eslint/eslint-plugin": "6.8.0",
    "@typescript-eslint/parser": "6.8.0",
    "eslint-config-prettier": "9.0.0",
    "eslint-import-resolver-alias": "1.1.2",
    "eslint-plugin-import": "2.28.1",
    "eslint-plugin-jsonc": "2.10.0",
    "eslint-plugin-n": "16.2.0",
    "eslint-plugin-prettier": "5.0.1",
    "eslint-plugin-promise": "6.1.1",
    "eslint-plugin-react": "7.33.2",
    "eslint-plugin-react-hooks": "4.6.0",
    "eslint-plugin-vue": "9.17.0",
    "prettier": "3.0.3"
  },
  "devDependencies": {
    "@rascaljs/cli": "0.4.0",
    "@types/eslint": "8.44.6",
    "@types/react": "18.2.31",
    "@types/react-dom": "18.2.14",
    "bumpp": "9.2.0",
    "eslint": "8.52.0",
    "eslint-plugin-rascal": "link:",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "simple-git-hooks": "2.9.0",
    "typescript": "5.2.2",
    "vue": "3.3.6"
  },
  "peerDependencies": {
    "eslint": ">=7.4.0",
    "typescript": ">=4.8.0"
  },
  "simple-git-hooks": {
    "commit-msg": "pnpm ras git-commit-verify",
    "pre-commit": "pnpm lint && ras lint-staged"
  }
}

工具列表

  • ESLint:代码质量的守护神。
  • Prettier:代码美化大师。
  • TypeScript 支持:让代码更健壮。
  • 常用插件:如 eslint-plugin-import, eslint-plugin-react, eslint-plugin-vue 等。
npm install eslint prettier @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint-plugin-import eslint-plugin-react eslint-plugin-vue --save-dev

项目结构

一个良好的项目结构能够帮助我们更好地组织和管理配置。推荐的结构如下:

eslint-config-myproject
-- lib
│   │-- configs
│   │   │-- base.js
│   │   │-- js.js
│   │   │-- prettier.js
│   │   │-- react.js
│   │   │-- vue.js
│   │   │-- moreyouneed.js
│   │   │-- ...
│   │-- rules
│   │   │-- all.js
│   │   │-- prettier.js
│   │-- index.js
  • lib/rules:内置规则。
  • lib/config 目录:模块化你的配置。
  • lib/index.js:导出基础配置。
  • lib/configs/react.jslib/configs/vue.jslib/configs/typescript.js:特定框架的配置文件。

核心思想

lib/rules 目录中引入 ESLint 的所有规则(lib/rules/all.js)和 Prettier 规则(lib/rules/prettier.js),并在 lib/configs 目录中通过配置文件将这些规则扩展和覆盖,从而实现自定义的 ESLint 配置。这种方法使我们能够灵活地管理和应用不同的代码规范和格式化规则,满足项目的具体需求。

举个🌰:

lib/configs/js.js

/**
 * @type {import('eslint').ESLint.ConfigData}
 */
module.exports = {
  root: true,
  env: {
    browser: true,
    node: true,
    commonjs: true,
    es2022: true,
  },
  parserOptions: {
    ecmaVersion: 2022,
    ecmaFeatures: {
      jsx: true,
    },
    sourceType: 'module',
  },
  ignorePatterns: [
    'node_modules',
    '*.min.*',
    'CHANGELOG.md',
    'dist',
    'LICENSE*',
    'output',
    'coverage',
    'public',
    'temp',
    'package-lock.json',
    'pnpm-lock.yaml',
    'yarn.lock',
    '__snapshots__',
    '!.github',
    '!.vitepress',
    '!.vscode',
  ],
  plugins: ['n', 'promise'],
  extends: [
    require.resolve('../rules/all.js'),
    'plugin:import/recommended',
    'plugin:jsonc/recommended-with-jsonc',
  ],
  settings: {
    'import/resolver': {
      alias: {
        map: [
          ['~', '.'],
          ['@', './src'],
        ],
        extensions: ['.js', '.jsx', '.mjs', 'cjs'],
      },
    },
  },
  overrides: [
    {
      files: ['*.json', '*.json5', '*.jsonc'],
      parser: 'jsonc-eslint-parser',
      rules: {
        'no-unused-expressions': 'off',
        'no-template-curly-in-string': 'off',
      },
    },
    {
      files: ['package.json'],
      parser: 'jsonc-eslint-parser',
      rules: {
        'jsonc/sort-keys': [
          'error',
          {
            pathPattern: '^$',
            order: [
              'publisher',
              'name',
              'displayName',
              'type',
              'version',
              'private',
              'packageManager',
              'description',
              'author',
              'license',
              'funding',
              'homepage',
              'repository',
              'bugs',
              'keywords',
              'categories',
              'sideEffects',
              'exports',
              'main',
              'module',
              'unpkg',
              'jsdelivr',
              'types',
              'typesVersions',
              'bin',
              'icon',
              'files',
              'engines',
              'activationEvents',
              'contributes',
              'scripts',
              'dependencies',
              'peerDependencies',
              'peerDependenciesMeta',
              'optionalDependencies',
              'devDependencies',
              'pnpm',
              'overrides',
              'resolutions',
              'husky',
              'simple-git-hooks',
              'lint-staged',
              'eslintConfig',
            ],
          },
          {
            pathPattern: '^(?:dev|peer|optional|bundled)?[Dd]ependencies$',
            order: { type: 'asc' },
          },
          {
            pathPattern: '^exports.*$',
            order: ['types', 'require', 'import'],
          },
        ],
      },
    },
  ],
  rules: {
    // import
    'import/no-mutable-exports': 'error',
    'import/no-named-as-default': 'off',
  },
};

其中包含了以下配置项:

  • env:让 ESLint 知道那些是原本就存在项目中的全局变量(global variable),否则当你在项目中直接使用了这些全局变量却又没有定义的话,ESLint 就会认为这个变量不存在而报错`
  • globals:可以定义全局中的变量的权限(只读,可读可写)
  • parserOptions:告诉 ESLint 项目中所使用的 JavaScript 语法版本。
  • rules:经过这个字段设置,可以让 ESLint 知道当不同的规则触发时,ESLint 要用什么类型的方式给予提示,是要当成是 error、warning、或是不用理会。 例如,在这里可以设定,假如代码尾不加分号,要当成是严重的错误(error),出现警告的提示(warning)就好,或是可以完全不用理会这个情况(off)。
  • plugins:是一系列由其他开发者撰写好的规则,让使用的人可以把这些规则加载到 ESLint 中使用,但要留意的是:「它只是定义好的规则,并没有说明要如何使用这些规则」,也就是说,plugin 只会载入规则,但不会说明这些规则发生时到底要被 ESLint 判断成是 error、warning、还是可以不用理会
  • ignorePatterns:告诉 ESLint 忽略对这些配置的文件进行代码检查,这也是为什么我们可以不用额外创建.eslintignore的原因
  • overrides: 可以为某个文件或者某组文件进行覆盖配置

如何发布和使用配置库

将配置库发布到 npm:

npm publish

在新项目中,安装并使用配置库:

npm install eslint-config-myproject --save-dev

.eslintrc.js 文件中:

module.exports = {
  extends: ["myproject"], //"myproject/vue", "myproject/react"
};

更多细节

欲了解更多细节,请访问 Rascal-Coder/eslint-config (GitHub)

参考资料

希望这份指南能帮助你打造一个高效、统一的开发环境!如有任何问题或建议,欢迎在评论区留言讨论。📢

转载自:https://juejin.cn/post/7398045554921865228
评论
请登录