From f22eaa9eebcc47242288b06d5c15bf8c162b329b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 3 Dec 2024 15:29:39 +0800 Subject: [PATCH] chore: release eslint-plugin-import-x (#190) Co-authored-by: github-actions[bot] --- .changeset/cuddly-ligers-wonder.md | 5 - .changeset/fluffy-dolls-pump.md | 5 - .changeset/nice-schools-drive.md | 5 - .changeset/nine-wolves-repeat.md | 5 - .changeset/orange-nails-attack.md | 188 --------------------------- CHANGELOG.md | 199 +++++++++++++++++++++++++++++ package.json | 2 +- 7 files changed, 200 insertions(+), 209 deletions(-) delete mode 100644 .changeset/cuddly-ligers-wonder.md delete mode 100644 .changeset/fluffy-dolls-pump.md delete mode 100644 .changeset/nice-schools-drive.md delete mode 100644 .changeset/nine-wolves-repeat.md delete mode 100644 .changeset/orange-nails-attack.md diff --git a/.changeset/cuddly-ligers-wonder.md b/.changeset/cuddly-ligers-wonder.md deleted file mode 100644 index 17c5f4740..000000000 --- a/.changeset/cuddly-ligers-wonder.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"eslint-plugin-import-x": patch ---- - -fix(no-cycle): improves the type declaration of the rule `no-cycle`’s `maxDepth` option diff --git a/.changeset/fluffy-dolls-pump.md b/.changeset/fluffy-dolls-pump.md deleted file mode 100644 index 960f91979..000000000 --- a/.changeset/fluffy-dolls-pump.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"eslint-plugin-import-x": patch ---- - -fix(first): improves the type declaration of the rule `first`'s option diff --git a/.changeset/nice-schools-drive.md b/.changeset/nice-schools-drive.md deleted file mode 100644 index 61b2a1474..000000000 --- a/.changeset/nice-schools-drive.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"eslint-plugin-import-x": patch ---- - -fix(no-unused-modules): improves the type declaration of the rule `no-unused-modules`’s `missingExports` option diff --git a/.changeset/nine-wolves-repeat.md b/.changeset/nine-wolves-repeat.md deleted file mode 100644 index 218d7f33e..000000000 --- a/.changeset/nine-wolves-repeat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"eslint-plugin-import-x": patch ---- - -fix(no-deprecated): improve error message when no description is available diff --git a/.changeset/orange-nails-attack.md b/.changeset/orange-nails-attack.md deleted file mode 100644 index c369ff1d2..000000000 --- a/.changeset/orange-nails-attack.md +++ /dev/null @@ -1,188 +0,0 @@ ---- -"eslint-plugin-import-x": minor ---- - -The PR implements the new resolver design proposed in https://github.com/un-ts/eslint-plugin-import-x/issues/40#issuecomment-2381444266 - -### For `eslint-plugin-import-x` users - -Like the ESLint flat config allows you to use js objects (e.g. import and require) as ESLint plugins, the new `eslint-plugin-import-x` resolver settings allow you to use js objects as custom resolvers through the new setting `import-x/resolver-next`: - -```js -// eslint.config.js -import { createTsResolver } from '#custom-resolver'; -const { createOxcResolver } = require('path/to/a/custom/resolver'); - -const resolverInstance = new ResolverFactory({}); -const customResolverObject = { - interfaceVersion: 3, - name: 'my-custom-eslint-import-resolver', - resolve(modPath, sourcePath) { - const path = resolverInstance.resolve(modPath, sourcePath); - if (path) { - return { - found: true, - path - }; - } - - return { - found: false, - path: null - } - }; -}; - -module.exports = { - settings: { - // multiple resolvers - 'import-x/resolver-next': [ - customResolverObject, - createTsResolver(enhancedResolverOptions), - createOxcResolver(oxcOptions), - ], - // single resolver: - 'import-x/resolver-next': [createOxcResolver(oxcOptions)] - } -} -``` - -The new `import-x/resolver-next` no longer accepts strings as the resolver, thus will not be compatible with the ESLint legacy config (a.k.a. `.eslintrc`). Those who are still using the ESLint legacy config should stick with `import-x/resolver`. - -In the next major version of `eslint-plugin-import-x` (v5), we will rename the currently existing `import-x/resolver` to `import-x/resolver-legacy` (which allows the existing ESLint legacy config users to use their existing resolver settings), and `import-x/resolver-next` will become the new `import-x/resolver`. When ESLint v9 (the last ESLint version with ESLint legacy config support) reaches EOL in the future, we will remove `import-x/resolver-legacy`. - -We have also made a few breaking changes to the new resolver API design, so you can't use existing custom resolvers directly with `import-x/resolver-next`: - -```js -// When migrating to `import-x/resolver-next`, you CAN'T use legacy versions of resolvers directly: -module.exports = { - settings: { - // THIS WON'T WORK, the resolver interface required for `import-x/resolver-next` is different. - 'import-x/resolver-next': [ - require('eslint-import-resolver-node'), - require('eslint-import-resolver-webpack'), - require('some-custom-resolver') - ]; - } -} -``` - -For easier migration, the PR also introduces a compat utility `importXResolverCompat` that you can use in your `eslint.config.js`: - -```js -// eslint.config.js -import eslintPluginImportX, { importXResolverCompat } from 'eslint-plugin-import-x'; -// or -const eslintPluginImportX = require('eslint-plugin-import-x'); -const { importXResolverCompat } = eslintPluginImportX; - -module.exports = { - settings: { - // THIS WILL WORK as you have wrapped the previous version of resolvers with the `importXResolverCompat` - 'import-x/resolver-next': [ - importXResolverCompat(require('eslint-import-resolver-node'), nodeResolveOptions), - importXResolverCompat(require('eslint-import-resolver-webpack'), webpackResolveOptions), - importXResolverCompat(require('some-custom-resolver'), { option1: true, option2: '' }) - ]; - } -} -``` - -### For custom import resolver developers - -This is the new API design of the resolver interface: - -```ts -export interface NewResolver { - interfaceVersion: 3, - name?: string, // This will be included in the debug log - resolve: (modulePath: string, sourceFile: string) => ResolvedResult -} - -// The `ResultNotFound` (returned when not resolved) is the same, no changes -export interface ResultNotFound { - found: false - path?: undefined -} - -// The `ResultFound` (returned resolve result) is also the same, no changes -export interface ResultFound { - found: true - path: string | null -} - -export type ResolvedResult = ResultNotFound | ResultFound -``` - -You will be able to import `NewResolver` from `eslint-plugin-import-x/types`. - -The most notable change is that `eslint-plugin-import-x` no longer passes the third argument (`options`) to the `resolve` function. - -We encourage custom resolvers' authors to consume the options outside the actual `resolve` function implementation. You can export a factory function to accept the options, this factory function will then be called inside the `eslint.config.js` to get the actual resolver: - -```js -// custom-resolver.js -exports.createCustomResolver = (options) => { - // The options are consumed outside the `resolve` function. - const resolverInstance = new ResolverFactory(options); - - return { - name: 'custom-resolver', - interfaceVersion: 3, - resolve(mod, source) { - const found = resolverInstance.resolve(mod, {}); - - // Of course, you still have access to the `options` variable here inside - // the `resolve` function. That's the power of JavaScript Closures~ - } - } -}; - -// eslint.config.js -const { createCustomResolver } = require('custom-resolver') - -module.exports = { - settings: { - 'import-x/resolver-next': [ - createCustomResolver(options) - ]; - } -} -``` - -This allows you to create a reusable resolver instance to improve the performance. With the existing version of the resolver interface, because the options are passed to the `resolver` function, you will have to create a resolver instance every time the `resolve` function is called: - -```js -module.exports = { - interfaceVersion: 2, - resolve(mod, source) { - // every time the `resolve` function is called, a new instance is created - // This is very slow - const resolverInstance = ResolverFactory.createResolver({}); - const found = resolverInstance.resolve(mod, {}); - } -} -``` - -With the factory function pattern, you can create a resolver instance beforehand: - -```js -exports.createCustomResolver = (options) => { - // `enhance-resolve` allows you to create a reusable instance: - const resolverInstance = ResolverFactory.createResolver({}); - const resolverInstance = enhanceResolve.create({}); - - // `oxc-resolver` also allows you to create a reusable instance: - const resolverInstance = new ResolverFactory({}); - - return { - name: 'custom-resolver', - interfaceVersion: 3, - resolve(mod, source) { - // the same re-usable instance is shared across `resolve` invocations. - // more performant - const found = resolverInstance.resolve(mod, {}); - } - } -}; -``` diff --git a/CHANGELOG.md b/CHANGELOG.md index dd146c606..849e303bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,204 @@ # eslint-plugin-import-x +## 4.5.0 + +### Minor Changes + +- [#192](https://github.com/un-ts/eslint-plugin-import-x/pull/192) [`fbf639b`](https://github.com/un-ts/eslint-plugin-import-x/commit/fbf639b85a6b22f7668c86c9ceaca5482ffc1045) Thanks [@SukkaW](https://github.com/SukkaW)! - The PR implements the new resolver design proposed in https://github.com/un-ts/eslint-plugin-import-x/issues/40#issuecomment-2381444266 + + ### For `eslint-plugin-import-x` users + + Like the ESLint flat config allows you to use js objects (e.g. import and require) as ESLint plugins, the new `eslint-plugin-import-x` resolver settings allow you to use js objects as custom resolvers through the new setting `import-x/resolver-next`: + + ```js + // eslint.config.js + import { createTsResolver } from '#custom-resolver'; + const { createOxcResolver } = require('path/to/a/custom/resolver'); + + const resolverInstance = new ResolverFactory({}); + const customResolverObject = { + interfaceVersion: 3, + name: 'my-custom-eslint-import-resolver', + resolve(modPath, sourcePath) { + const path = resolverInstance.resolve(modPath, sourcePath); + if (path) { + return { + found: true, + path + }; + } + + return { + found: false, + path: null + } + }; + }; + + module.exports = { + settings: { + // multiple resolvers + 'import-x/resolver-next': [ + customResolverObject, + createTsResolver(enhancedResolverOptions), + createOxcResolver(oxcOptions), + ], + // single resolver: + 'import-x/resolver-next': [createOxcResolver(oxcOptions)] + } + } + ``` + + The new `import-x/resolver-next` no longer accepts strings as the resolver, thus will not be compatible with the ESLint legacy config (a.k.a. `.eslintrc`). Those who are still using the ESLint legacy config should stick with `import-x/resolver`. + + In the next major version of `eslint-plugin-import-x` (v5), we will rename the currently existing `import-x/resolver` to `import-x/resolver-legacy` (which allows the existing ESLint legacy config users to use their existing resolver settings), and `import-x/resolver-next` will become the new `import-x/resolver`. When ESLint v9 (the last ESLint version with ESLint legacy config support) reaches EOL in the future, we will remove `import-x/resolver-legacy`. + + We have also made a few breaking changes to the new resolver API design, so you can't use existing custom resolvers directly with `import-x/resolver-next`: + + ```js + // When migrating to `import-x/resolver-next`, you CAN'T use legacy versions of resolvers directly: + module.exports = { + settings: { + // THIS WON'T WORK, the resolver interface required for `import-x/resolver-next` is different. + 'import-x/resolver-next': [ + require('eslint-import-resolver-node'), + require('eslint-import-resolver-webpack'), + require('some-custom-resolver') + ]; + } + } + ``` + + For easier migration, the PR also introduces a compat utility `importXResolverCompat` that you can use in your `eslint.config.js`: + + ```js + // eslint.config.js + import eslintPluginImportX, { importXResolverCompat } from 'eslint-plugin-import-x'; + // or + const eslintPluginImportX = require('eslint-plugin-import-x'); + const { importXResolverCompat } = eslintPluginImportX; + + module.exports = { + settings: { + // THIS WILL WORK as you have wrapped the previous version of resolvers with the `importXResolverCompat` + 'import-x/resolver-next': [ + importXResolverCompat(require('eslint-import-resolver-node'), nodeResolveOptions), + importXResolverCompat(require('eslint-import-resolver-webpack'), webpackResolveOptions), + importXResolverCompat(require('some-custom-resolver'), { option1: true, option2: '' }) + ]; + } + } + ``` + + ### For custom import resolver developers + + This is the new API design of the resolver interface: + + ```ts + export interface NewResolver { + interfaceVersion: 3; + name?: string; // This will be included in the debug log + resolve: (modulePath: string, sourceFile: string) => ResolvedResult; + } + + // The `ResultNotFound` (returned when not resolved) is the same, no changes + export interface ResultNotFound { + found: false; + path?: undefined; + } + + // The `ResultFound` (returned resolve result) is also the same, no changes + export interface ResultFound { + found: true; + path: string | null; + } + + export type ResolvedResult = ResultNotFound | ResultFound; + ``` + + You will be able to import `NewResolver` from `eslint-plugin-import-x/types`. + + The most notable change is that `eslint-plugin-import-x` no longer passes the third argument (`options`) to the `resolve` function. + + We encourage custom resolvers' authors to consume the options outside the actual `resolve` function implementation. You can export a factory function to accept the options, this factory function will then be called inside the `eslint.config.js` to get the actual resolver: + + ```js + // custom-resolver.js + exports.createCustomResolver = (options) => { + // The options are consumed outside the `resolve` function. + const resolverInstance = new ResolverFactory(options); + + return { + name: 'custom-resolver', + interfaceVersion: 3, + resolve(mod, source) { + const found = resolverInstance.resolve(mod, {}); + + // Of course, you still have access to the `options` variable here inside + // the `resolve` function. That's the power of JavaScript Closures~ + } + } + }; + + // eslint.config.js + const { createCustomResolver } = require('custom-resolver') + + module.exports = { + settings: { + 'import-x/resolver-next': [ + createCustomResolver(options) + ]; + } + } + ``` + + This allows you to create a reusable resolver instance to improve the performance. With the existing version of the resolver interface, because the options are passed to the `resolver` function, you will have to create a resolver instance every time the `resolve` function is called: + + ```js + module.exports = { + interfaceVersion: 2, + resolve(mod, source) { + // every time the `resolve` function is called, a new instance is created + // This is very slow + const resolverInstance = ResolverFactory.createResolver({}); + const found = resolverInstance.resolve(mod, {}); + }, + }; + ``` + + With the factory function pattern, you can create a resolver instance beforehand: + + ```js + exports.createCustomResolver = (options) => { + // `enhance-resolve` allows you to create a reusable instance: + const resolverInstance = ResolverFactory.createResolver({}); + const resolverInstance = enhanceResolve.create({}); + + // `oxc-resolver` also allows you to create a reusable instance: + const resolverInstance = new ResolverFactory({}); + + return { + name: "custom-resolver", + interfaceVersion: 3, + resolve(mod, source) { + // the same re-usable instance is shared across `resolve` invocations. + // more performant + const found = resolverInstance.resolve(mod, {}); + }, + }; + }; + ``` + +### Patch Changes + +- [#184](https://github.com/un-ts/eslint-plugin-import-x/pull/184) [`bc4de89`](https://github.com/un-ts/eslint-plugin-import-x/commit/bc4de89dc425436461e87d7793ba4bc3b9ab386d) Thanks [@marcalexiei](https://github.com/marcalexiei)! - fix(no-cycle): improves the type declaration of the rule `no-cycle`’s `maxDepth` option + +- [#184](https://github.com/un-ts/eslint-plugin-import-x/pull/184) [`bc4de89`](https://github.com/un-ts/eslint-plugin-import-x/commit/bc4de89dc425436461e87d7793ba4bc3b9ab386d) Thanks [@marcalexiei](https://github.com/marcalexiei)! - fix(first): improves the type declaration of the rule `first`'s option + +- [#184](https://github.com/un-ts/eslint-plugin-import-x/pull/184) [`bc4de89`](https://github.com/un-ts/eslint-plugin-import-x/commit/bc4de89dc425436461e87d7793ba4bc3b9ab386d) Thanks [@marcalexiei](https://github.com/marcalexiei)! - fix(no-unused-modules): improves the type declaration of the rule `no-unused-modules`’s `missingExports` option + +- [#184](https://github.com/un-ts/eslint-plugin-import-x/pull/184) [`bc4de89`](https://github.com/un-ts/eslint-plugin-import-x/commit/bc4de89dc425436461e87d7793ba4bc3b9ab386d) Thanks [@marcalexiei](https://github.com/marcalexiei)! - fix(no-deprecated): improve error message when no description is available + ## 4.4.3 ### Patch Changes diff --git a/package.json b/package.json index 7635a7568..cab2b8d0c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-import-x", - "version": "4.4.3", + "version": "4.5.0", "description": "Import with sanity.", "repository": "git+https://github.com/un-ts/eslint-plugin-import-x", "author": "JounQin (https://www.1stG.me)",