-
#192
fbf639b
Thanks @SukkaW! - The PR implements the new resolver design proposed in un-ts#40 (comment)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 settingimport-x/resolver-next
:// 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 withimport-x/resolver
.In the next major version of
eslint-plugin-import-x
(v5), we will rename the currently existingimport-x/resolver
toimport-x/resolver-legacy
(which allows the existing ESLint legacy config users to use their existing resolver settings), andimport-x/resolver-next
will become the newimport-x/resolver
. When ESLint v9 (the last ESLint version with ESLint legacy config support) reaches EOL in the future, we will removeimport-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
:// 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 youreslint.config.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: '' }) ]; } }
This is the new API design of the resolver interface:
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
fromeslint-plugin-import-x/types
.The most notable change is that
eslint-plugin-import-x
no longer passes the third argument (options
) to theresolve
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 theeslint.config.js
to get the actual resolver:// 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 theresolve
function is called: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:
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, {}); }, }; };
-
#184
bc4de89
Thanks @marcalexiei! - fix(no-cycle): improves the type declaration of the ruleno-cycle
’smaxDepth
option -
#184
bc4de89
Thanks @marcalexiei! - fix(first): improves the type declaration of the rulefirst
's option -
#184
bc4de89
Thanks @marcalexiei! - fix(no-unused-modules): improves the type declaration of the ruleno-unused-modules
’smissingExports
option -
#184
bc4de89
Thanks @marcalexiei! - fix(no-deprecated): improve error message when no description is available
- #181
cc4ee65
Thanks @SukkaW! - Fix #144, read propersourceType
for both eslint flat config and legacy eslintrc config.
-
#175
acebd98
Thanks @marcalexiei! - fix(extensions): correctOptions
type -
#174
e01dce0
Thanks @marcalexiei! - fix(no-extraneous-dependencies): correct someOptions
type properties
- #169
9c58269
Thanks @teidesu! - Add new rule optioncheckTypedImports
forextensions
, backports import-js#2817
-
#171
9715220
Thanks @SukkaW! - Perf: avoid regexp during parser choosing -
#171
9715220
Thanks @SukkaW! - Add extra guard for ruleno-named-as-default
. A few guards are borrowed from import-js#3032, but we don't sync the rest of changes from upstream since we have already implemented a way more performant check. -
#171
9715220
Thanks @SukkaW! - More test cases forno-named-export
andno-defualt-export
rule specifically with non-modulesourceType
-
#171
9715220
Thanks @SukkaW! - Fixexport
when there is only oneTSDeclareFunction
(import-js#3065) -
#171
9715220
Thanks @SukkaW! - PreventExportMap
's cache is being tainted by incompatible parser (e.g. oldbabel-eslint
). The cache is now skipped w/ incompatible parsers, which might introduce performance impacts only for those who are using incompatible parsers. (import-js#3062) -
#171
9715220
Thanks @SukkaW! - Docs: fix a few typos here and there -
#168
5de039c
Thanks @hyoban! - Fixes un-ts#167, theno-duplicates
rule now allows co-existing inline type imports and namespace imports. -
#171
9715220
Thanks @SukkaW! - Properly fix espree parser w/ ESLint Flat Config
- #162
38d0081
Thanks @AaronMoat! - Fix issue whereno-duplicates
rule withprefer-inline
incorrectly marks default type and named type imports as duplicates
- #159
4da5388
Thanks @GoodbyeNJN! - feat: add support for using resolver object directly in settings
-
#148
d228129
Thanks @SukkaW! - Fixnewline-after-import
'sconsiderComments
options when lintingrequire
, backports import-js#2952 -
#147
eca73ed
Thanks @nchevsky! - Fix regression in ruleno-unused-modules
which would incorrectly initialize optionsrc
to[]
instead of[process.cwd()]
, breaking file discovery. -
#148
d228129
Thanks @SukkaW! - Fixno-duplicates
for TypeScript, backports import-js#3033
- #146
e5e4580
Thanks @SukkaW! - Fix nuxt/eslint#494 by avoid importing from@typescript-eslint/typescript-estree
.
- #133
757ffa9
Thanks @SukkaW! - Fix #123 where the ruleno-named-as-default
will confuse TypeScript namespace exports with actual exports.
-
#122
cd52e86
Thanks @michaelfaith! - Add ESLint flat configuration presets. You can access them with:import eslintPluginImportX from "eslint-plugin-import-x"; eslintPluginImportX.flatConfigs.recommended; eslintPluginImportX.flatConfigs.react; eslintPluginImportX.flatConfigs.typescript; eslintPluginImportX.flatConfigs.electron;
-
#132
9948c78
Thanks @SukkaW! - Addedno-rename-default
that forbid importing a default export by a different name. Originally created by @whitneyit, ported by @SukkaW
- #112
4ba14da
Thanks @SukkaW! - Use typescript-eslint v8. The minimum supported ESLint version is now >= 8.57.0 and the minimum required Node.js version is now 18.18.0.
- #116
38aa4cb
Thanks @silverwind! - AddignoreUnusedTypeExports
option tono-unused-modules
-
#118
0307ff2
Thanks @SukkaW! - Reverts #111. The introduction of SCC causes extra overhead that overcomes the early return it introduced.A new
no-cycle-next
rule is being implemented using the graph. It won't be backward compatible with the current ruleno-cycle
. The currentno-cycle
rule will becomeno-cycle-legacy
in the next major version.
-
#109
fe3121a
Thanks @SukkaW! - Makeeslint-plugin-import-x
overall faster by refactoring theExportMap
util -
#111
5cce946
Thanks @SukkaW! - Drastically improveno-cycle
's performance by skipping unnecessary BFSes using Tarjan's SCC.
-
#106
19f10aa
Thanks @SukkaW! -eslint-plugin-import-x
is a fork ofeslint-plugin-import
that aims to provide a more performant and more lightweight version of the original plugin.Due to the nature of the fork, all
eslint-plugin-import
's git tags and releases have been copied over toeslint-plugin-import-x
. This causes version conflicts when publishing new versions ofeslint-plugin-import-x
.To prevent this, we have decided to publish a new major version of
eslint-plugin-import-x
that will not conflict with the originaleslint-plugin-import
's versions.See also un-ts#76
-
#101
c0cea7b
Thanks @SukkaW! - Allow incorrect file path in extraneous deps check -
#100
293fcf4
Thanks @SukkaW! - feat: webpack comment regex supportwebpackFetchPriority
-
#85
ded3e80
Thanks @kosmotema! - add languageOptions to ChildContext -
#100
293fcf4
Thanks @SukkaW! - Allow empty chunk name when webpackMode: 'eager' is set; add suggestions to remove name in eager mode
-
#66
49418a0
Thanks @JounQin! - chore(dep)!: drop eslint <8.56 support -
#66
49418a0
Thanks @JounQin! - feat!: upgrade @typescript-eslint/utils to v7
- #62
1dbb323
Thanks @JounQin! - feat: use eslint-compat-utils to support eslint v9 (not flat config yet)
-
#51
f4ca4b5
Thanks @JounQin! - refactor: migrate all remaining rules -
#50
de896f4
Thanks @JounQin! - refactor: migrate several rules