diff --git a/README-ZH.md b/README-ZH.md index 9117143..b952986 100644 --- a/README-ZH.md +++ b/README-ZH.md @@ -9,25 +9,16 @@ ## 安装 -你首先需要安装 [ESLint](https://eslint.org/): +你首先需要安装 [ESLint](https://eslint.org/) 和约定的第三方插件包: ```sh -yarn add eslint - -or - -npm i eslint --save-dev +yarn add eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint-config-prettier eslint-plugin-import eslint-plugin-prettier eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-simple-import-sort eslint-plugin-unicorn prettier typescript eslint-plugin-eslint-plugin --dev ``` 接下来,安装 `@sj-distributor/eslint-plugin-react-native`: ```sh - -yarn add @sj-distributor/eslint-plugin-react-native - -or - -npm install @sj-distributor/eslint-plugin-react-native --save-dev +yarn add @sj-distributor/eslint-plugin-react-native --dev ``` ## 使用 @@ -36,7 +27,7 @@ Add `eslint-plugin-react-native` to the extends section of your `.eslintrc` conf ```json { - "extends": ["plugin:@sj-distributor/eslint-plugin-react-native/recommended"] + "extends": ["plugin:@sj-distributor/react-native/recommended"] } ``` @@ -52,3 +43,5 @@ Add `eslint-plugin-react-native` to the extends section of your `.eslintrc` conf - [eslint-plugin-react-hooks](https://www.npmjs.com/package/eslint-plugin-react-hooks) - [eslint-plugin-react-native](https://github.com/intellicode/eslint-plugin-react-native) - [eslint-plugin-simple-import-sort](https://github.com/lydell/eslint-plugin-simple-import-sort#readme) +- [@typescript-eslint](https://typescript-eslint.io/) +- [eslint-plugin-unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn) diff --git a/README.md b/README.md index 11e4083..252cb81 100644 --- a/README.md +++ b/README.md @@ -11,25 +11,16 @@ ESLint presets for react native ## Installation -You'll first need to install [ESLint](https://eslint.org/): +You'll first need to install [ESLint](https://eslint.org/) and the agreed third-party plug-in package: ```sh -yarn add eslint - -or - -npm i eslint --save-dev +yarn add eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint-config-prettier eslint-plugin-import eslint-plugin-prettier eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-simple-import-sort eslint-plugin-unicorn prettier typescript eslint-plugin-eslint-plugin --dev ``` Next, install `@sj-distributor/eslint-plugin-react-native`: ```sh - -yarn add @sj-distributor/eslint-plugin-react-native - -or - -npm install @sj-distributor/eslint-plugin-react-native --save-dev +yarn add @sj-distributor/eslint-plugin-react-native --dev ``` ## Usage @@ -38,7 +29,7 @@ Add `eslint-plugin-react-native` to the extends section of your `.eslintrc` conf ```json { - "extends": ["plugin:@sj-distributor/eslint-plugin-react-native/recommended"] + "extends": ["plugin:@sj-distributor/react-native/recommended"] } ``` @@ -54,3 +45,5 @@ Add `eslint-plugin-react-native` to the extends section of your `.eslintrc` conf - [eslint-plugin-react-hooks](https://www.npmjs.com/package/eslint-plugin-react-hooks) - [eslint-plugin-react-native](https://github.com/intellicode/eslint-plugin-react-native) - [eslint-plugin-simple-import-sort](https://github.com/lydell/eslint-plugin-simple-import-sort#readme) +- [@typescript-eslint](https://typescript-eslint.io/) +- [eslint-plugin-unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn) diff --git a/configs/.eslintrc.js b/configs/.eslintrc.js index fbd47be..0b1c673 100644 --- a/configs/.eslintrc.js +++ b/configs/.eslintrc.js @@ -4,11 +4,20 @@ module.exports = { "eslint:recommended", "plugin:prettier/recommended", "plugin:react-hooks/recommended", + "plugin:eslint-plugin/recommended", "plugin:@typescript-eslint/recommended", ], parser: "@typescript-eslint/parser", - plugins: ["react", "react-native", "simple-import-sort", "unicorn", "import"], + plugins: [ + "react", + "react-native", + "simple-import-sort", + "unicorn", + "import", + "@sj-distributor/react-native", + ], env: { + node: true, es2022: true, browser: true, "react-native/react-native": true, @@ -34,10 +43,10 @@ module.exports = { "error", { cases: { - kebabCase: true, // 是否支持横杠 (-) 命名 - camelCase: false, // 是否支持小驼峰命名 - snakeCase: false, // 是否支持 (_) 下划线命名 - pascalCase: false, // 是否支持大坨峰命名 + kebabCase: true, // 支持横杠 (-) 命名 + camelCase: false, // 支持小驼峰命名 + snakeCase: false, // 支持 (_) 下划线命名 + pascalCase: false, // 支持大坨峰命名 }, }, ], @@ -54,6 +63,10 @@ module.exports = { next: "*", }, ], + "@typescript-eslint/no-var-requires": 0, // (关闭) 禁止使用 require 语句 + "@sj-distributor/react-native/interface-name-prefix": ["error", "I"], // 默认强制 interface 大写 I 前缀 + "react/display-name": 0, // (关闭) 不允许在 React 组件定义中缺少 displayName + "react/self-closing-comp": 2, // 检测 JSX 中的所有组件和 HTML 元素,如果元素没有子元素,就会自动转换为自闭合形式 }, // 共享配置,提供给每一个将被执行的规则 settings: { diff --git a/lib/index.js b/lib/index.js index bed9e92..b8e2a02 100644 --- a/lib/index.js +++ b/lib/index.js @@ -7,6 +7,7 @@ // Requirements //------------------------------------------------------------------------------ +const path = require("path"); const requireIndex = require("requireindex"); const eslintrc = require("../configs/.eslintrc"); @@ -15,7 +16,7 @@ const eslintrc = require("../configs/.eslintrc"); //------------------------------------------------------------------------------ module.exports = { // 引入所有的自定义的规则 - rules: requireIndex(__dirname + "/rules"), + rules: requireIndex(path.join(__dirname + "/rules")), configs: { recommended: eslintrc, }, diff --git a/lib/rules/interface-name-prefix.js b/lib/rules/interface-name-prefix.js new file mode 100644 index 0000000..5f50695 --- /dev/null +++ b/lib/rules/interface-name-prefix.js @@ -0,0 +1,64 @@ +/** + * @fileoverview Require interface names to begin with a specified prefix + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +/** @type {import('eslint').Rule.RuleModule} */ +module.exports = { + meta: { + type: "suggestion", + docs: { + category: "Naming", + recommended: false, + description: "Require interface names to begin with a specified prefix", + }, + fixable: "code", + schema: [ + { + type: "string", + }, + ], + messages: { + missingPrefix: + "Interface name '{{ name }}' should start with '{{ prefix }}'", + }, + }, + + create(context) { + const [prefix = "I"] = context.options; + + function checkPrefix(node) { + const name = node.id.name; + + if ( + typeof name !== "string" || + name.startsWith(prefix) || + node.parent.type === "TSModuleDeclaration" + ) { + return; + } + + context.report({ + node, + messageId: "missingPrefix", + data: { + name, + prefix, + }, + fix: (fixer) => { + const newName = `${prefix}${name}`; + + return fixer.replaceText(node.id, newName); + }, + }); + } + + return { + TSInterfaceDeclaration: checkPrefix, + }; + }, +}; diff --git a/package.json b/package.json index 20e36e8..52085e3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sj-distributor/eslint-plugin-react-native", - "version": "0.2.1", + "version": "0.2.2", "description": "ESLint presets for react native", "keywords": [ "eslint", @@ -11,7 +11,7 @@ "exports": "./lib/index.js", "scripts": { "lint": "eslint .", - "release": "release-it", + "release": "release-it --no-increment", "test": "mocha tests --recursive" }, "dependencies": {