From ebc97bf337c004963d2f3faf1fe98cc386c4f1a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=94=AF=E7=84=B6?= Date: Mon, 15 May 2023 10:59:14 +0800 Subject: [PATCH] feat: support eslint.config.js (#95) --- .eslintignore | 7 ---- .eslintrc.js | 2 ++ README.md | 48 +++++++++++++++++++------ configs/recommended-module.js | 17 +++++++++ configs/recommended-script.js | 17 +++++++++ eslint.config.js | 41 +++++++++++++++++++++ lib/index.js | 6 ++++ lib/util/check-unsupported-builtins.js | 2 +- lib/util/get-configured-node-version.js | 2 +- package.json | 9 +++-- scripts/update-lib-index.js | 6 ++++ 11 files changed, 135 insertions(+), 22 deletions(-) delete mode 100644 .eslintignore create mode 100644 configs/recommended-module.js create mode 100644 configs/recommended-script.js create mode 100644 eslint.config.js diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 4ca9f9c6..00000000 --- a/.eslintignore +++ /dev/null @@ -1,7 +0,0 @@ -!.* - -/.nyc_output -/coverage -/docs -/node_modules -/lib/converted-esm \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js index fdc5d9f4..564aca77 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,5 +1,7 @@ /** * @author Toru Nagashima + * @deprecated + * @description the file is no longer used, and will be removed in the future. * See LICENSE file in root directory for full license. */ "use strict" diff --git a/README.md b/README.md index 19c75723..76740fb9 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,9 @@ npm install --save-dev eslint eslint-plugin-n - Requires Node.js `>=16.0.0` - Requires ESLint `>=7.0.0` -**.eslintrc.json** (An example) +**Note:** It recommends a use of [the "engines" field of package.json](https://docs.npmjs.com/files/package.json#engines). The "engines" field is used by `n/no-unsupported-features/*` rules. + +### **[.eslintrc.json](https://eslint.org/docs/latest/use/configure/configuration-files)** (An example) ```jsonc { @@ -24,19 +26,26 @@ npm install --save-dev eslint eslint-plugin-n "ecmaVersion": 2021 }, "rules": { - "n/exports-style": ["error", "module.exports"], - "n/file-extension-in-import": ["error", "always"], - "n/prefer-global/buffer": ["error", "always"], - "n/prefer-global/console": ["error", "always"], - "n/prefer-global/process": ["error", "always"], - "n/prefer-global/url-search-params": ["error", "always"], - "n/prefer-global/url": ["error", "always"], - "n/prefer-promises/dns": "error", - "n/prefer-promises/fs": "error" + "n/exports-style": ["error", "module.exports"] } } ``` +### [`eslint.config.js`](https://eslint.org/docs/latest/use/configure/configuration-files-new) (requires eslint>=v8.23.0) + +```js +const nodeRecommendedScript = require("eslint-plugin-n/configs/recommended-script") + +module.exports = [ + nodeRecommendedScript, + { + rules: { + "n/exports-style": ["error", "module.exports"] + } + } +] +``` + **package.json** (An example) ```json @@ -163,6 +172,25 @@ These preset configs: - Q: The `no-missing-import` / `no-missing-require` rules don't work with nested folders in SublimeLinter-eslint - A: See [context.getFilename() in rule returns relative path](https://github.com/roadhump/SublimeLinter-eslint#contextgetfilename-in-rule-returns-relative-path) in the SublimeLinter-eslint FAQ. +- Q: How to use the new eslint config with mixed commonjs and es modules? +- A: The `recommended` config is no longer exported. You can create a config based on `recommended-script` and `recommended-module`. An example: + +```js +const nodeRecommendedScript = require("eslint-plugin-n/configs/recommended-script"); +const nodeRecommendedModule = require("eslint-plugin-n/configs/recommended-module"); + +module.exports = [ + { + files: ["**/*.js", "**/*.cjs"], + ...nodeRecommendedScript + }, + { + files: ["**/*.mjs"], + ...nodeRecommendedModule + } +] +``` + ## 🚥 Semantic Versioning Policy `eslint-plugin-n` follows [semantic versioning](http://semver.org/) and [ESLint's Semantic Versioning Policy](https://github.com/eslint/eslint#semantic-versioning-policy). diff --git a/configs/recommended-module.js b/configs/recommended-module.js new file mode 100644 index 00000000..8c676422 --- /dev/null +++ b/configs/recommended-module.js @@ -0,0 +1,17 @@ +/** + * @fileoverview the `recommended-module` config for `eslint.config.js` + * @author 唯然 + */ + +"use strict" + +const mod = require("../lib/index.js") + +module.exports = { + plugins: { n: mod }, + languageOptions: { + sourceType: "module", + globals: mod.configs["recommended-module"].globals, + }, + rules: mod.configs["recommended-module"].rules, +} diff --git a/configs/recommended-script.js b/configs/recommended-script.js new file mode 100644 index 00000000..a6df853e --- /dev/null +++ b/configs/recommended-script.js @@ -0,0 +1,17 @@ +/** + * @fileoverview the `recommended-script` config for `eslint.config.js` + * @author 唯然 + */ + +"use strict" + +const mod = require("../lib/index.js") + +module.exports = { + plugins: { n: mod }, + languageOptions: { + sourceType: "commonjs", + globals: mod.configs["recommended-script"].globals, + }, + rules: mod.configs["recommended-script"].rules, +} diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 00000000..7e50e9a2 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,41 @@ +/** + * @author 唯然 + */ +"use strict" + +const js = require("@eslint/js") +const { FlatCompat } = require("@eslint/eslintrc") +const globals = require("globals") +const nodeRecommended = require("eslint-plugin-n/configs/recommended-script") + +const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, +}) + +module.exports = [ + { + languageOptions: { globals: globals.mocha }, + linterOptions: { reportUnusedDisableDirectives: true }, + }, + { + ignores: [ + ".nyc_output/", + "coverage/", + "docs/", + "lib/converted-esm/", + "test/fixtures/", + ], + }, + js.configs.recommended, + nodeRecommended, + ...compat.extends("plugin:eslint-plugin/recommended", "prettier"), + { rules: { "eslint-plugin/require-meta-docs-description": "error" } }, + { + // these messageIds were used outside + files: ["lib/rules/prefer-global/*.js"], + rules: { + "eslint-plugin/no-unused-message-ids": 0, + }, + }, +] diff --git a/lib/index.js b/lib/index.js index b391396f..341c86df 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,7 +1,13 @@ /* DON'T EDIT THIS FILE. This is generated by 'scripts/update-lib-index.js' */ "use strict" +const pkg = require("../package.json") + module.exports = { + meta: { + name: pkg.name, + version: pkg.version, + }, configs: { "recommended-module": require("./configs/recommended-module"), "recommended-script": require("./configs/recommended-script"), diff --git a/lib/util/check-unsupported-builtins.js b/lib/util/check-unsupported-builtins.js index 7e0c0009..79b8f1e4 100644 --- a/lib/util/check-unsupported-builtins.js +++ b/lib/util/check-unsupported-builtins.js @@ -4,7 +4,7 @@ */ "use strict" -const { Range, lt, major } = require("semver") //eslint-disable-line no-unused-vars +const { Range, lt, major } = require("semver") // eslint-disable-line no-unused-vars const { ReferenceTracker } = require("@eslint-community/eslint-utils") const getConfiguredNodeVersion = require("./get-configured-node-version") const getSemverRange = require("./get-semver-range") diff --git a/lib/util/get-configured-node-version.js b/lib/util/get-configured-node-version.js index c1395d7f..ed235fa7 100644 --- a/lib/util/get-configured-node-version.js +++ b/lib/util/get-configured-node-version.js @@ -4,7 +4,7 @@ */ "use strict" -const { Range } = require("semver") //eslint-disable-line no-unused-vars +const { Range } = require("semver") // eslint-disable-line no-unused-vars const getPackageJson = require("./get-package-json") const getSemverRange = require("./get-semver-range") diff --git a/package.json b/package.json index fb6bd395..fcb22b2c 100644 --- a/package.json +++ b/package.json @@ -7,15 +7,16 @@ }, "main": "lib/index.js", "files": [ - "lib" + "lib/", + "configs/" ], "peerDependencies": { "eslint": ">=7.0.0" }, "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", "builtins": "^5.0.1", "eslint-plugin-es-x": "^6.1.0", - "@eslint-community/eslint-utils": "^4.4.0", "ignore": "^5.1.1", "is-core-module": "^2.12.0", "minimatch": "^3.1.2", @@ -23,6 +24,8 @@ "semver": "^7.5.0" }, "devDependencies": { + "@eslint/eslintrc": "^2.0.2", + "@eslint/js": "^8.38.0", "@typescript-eslint/parser": "^5.59.0", "codecov": "^3.3.0", "esbuild": "^0.17.17", @@ -56,7 +59,7 @@ "lint": "npm-run-all \"lint:*\"", "lint:docs": "markdownlint \"**/*.md\"", "lint:eslint-docs": "npm run update:eslint-docs -- --check", - "lint:js": "eslint lib scripts tests/lib .eslintrc.js", + "lint:js": "eslint .", "new": "node scripts/new-rule", "postversion": "git push && git push --tags", "prepare": "npx husky install", diff --git a/scripts/update-lib-index.js b/scripts/update-lib-index.js index aaa7fa07..7dc04003 100644 --- a/scripts/update-lib-index.js +++ b/scripts/update-lib-index.js @@ -13,7 +13,13 @@ const filePath = path.resolve(__dirname, "../lib/index.js") const rawContent = `/* DON'T EDIT THIS FILE. This is generated by 'scripts/update-lib-index.js' */ "use strict" +const pkg = require("../package.json") + module.exports = { + meta: { + name: pkg.name, + version: pkg.version, + }, configs: { "recommended-module": require("./configs/recommended-module"), "recommended-script": require("./configs/recommended-script"),