Git Product home page Git Product logo

un-es / eslint-plugin-i Goto Github PK

View Code? Open in Web Editor NEW

This project forked from import-js/eslint-plugin-import

293.0 3.0 13.0 4.57 MB

`eslint-plugin-import-x` is a fork of `eslint-plugin-import` that aims to provide a more performant and more lightweight version of the original plugin.

Home Page: https://npm.im/eslint-plugin-import-x

License: MIT License

JavaScript 0.46% TypeScript 99.54%
eslint eslint-plugin eslint-plugin-import

eslint-plugin-i's Issues

Publish type definitions

In flat config format, eslint plugins are imported using import statements should therefor publish type definitions to avoid such typescript errors:

TS7016: Could not find a declaration file for module 'eslint-plugin-import-x'

support for `exports`

A major issue with eslint-plugin-import is that it doesn't support exports: import-js#1810

I was wondering if you might consider using resolve.exports or enhanced-resolve rather than the outdated resolve package in this library to address that

What does `settings."import-x/resolver".typescript: true` do ?

https://github.com/un-ts/eslint-plugin-import-x#typescript suggests doing (translated to js/json):

"settings": {
  "import-x/resolver": {
    "typescript": true
  }
}

but also links to https://github.com/import-js/eslint-import-resolver-typescript#configuration which tells me to do (after changing import/ to import-x/:

"settings": {
  "import-x/parsers": { // Updated to import-x
    "@typescript-eslint/parser": [".ts", ".tsx"]
  },
  "import-x/resolver": { // Updated to import-x
    "typescript": {
      "alwaysTryTypes": true,
      "project": [ // I'm using my @typescript-eslint/parser projects configs for this example
          "tsconfig?(.*).json",
          // From our Angular preset
          "projects/*/tsconfig?(.*).json",
          "*/tsconfig?(.*).json" // For example: e2e/tsconfig.json
        ]
    }
  }
}

It is unclear to me what "typescript": true does and why it differs from the linked documentation.

[Perf] `import-x/no-cycle` has a very poor performance

eslint-react on main [!] via v22.4.0 took 24s 
❯ TIMING="ALL" pnpm eslint .

Rule                                                       | Time (ms) | Relative
:----------------------------------------------------------|----------:|--------:
import-x/no-cycle                                          | 10430.996 |    89.7%
perfectionist/sort-objects                                 |   225.766 |     1.9%
import-x/no-duplicates                                     |   132.804 |     1.1%
jsdoc/check-access                                         |    60.685 |     0.5%
@typescript-eslint/no-unused-vars                          |    60.420 |     0.5%
jsdoc/valid-types                                          |    39.484 |     0.3%
simple-import-sort/imports                                 |    39.262 |     0.3%
jsdoc/informative-docs                                     |    36.719 |     0.3%
jsdoc/check-values                                         |    35.114 |     0.3%
jsdoc/check-types                                          |    35.065 |     0.3%
jsdoc/no-multi-asterisks                                   |    30.249 |     0.3%
jsdoc/require-property-description                         |    29.917 |     0.3%
jsdoc/check-alignment                                      |    27.214 |     0.2%
import-x/export                                            |    26.432 |     0.2%                                          

[Proposal] Support using any object satisfied `Resolver` type in `import-x/resolver` options

The resolver currently supports three reference methods:

  • name -> eslint-import-resolver-name
  • npm package name
  • filesystem path

I propose that it support the direct use of any object satisfied Resolver type, and I further propose configuration other than this should be deprecated in the future.

Advantage:

  • Reduce complexity when trying to require resolvers
  • Defining a custom resolver is more convenient

For advantage 1, you can refer to ESLint’s thoughts on the introduction of flat config:

Use native loading for everything - one of our biggest regrets about eslintrc was recreating the Node.js require resolution in a custom way. This was a significant source of complexity and, in hindsight, unnecessary. Going forward, we wanted to leverage the loading capabilities of the JavaScript runtime directly.

Reference: https://eslint.org/blog/2022/08/new-config-system-part-2/#the-goals-of-flat-config

For advantage 2, there may be cases when existing resolvers don't meet the needs and needs to be temporarily added.

In this case, if the direct use of objects is supported, the steps of "creating new file -> processing filesystem path" can be eliminated, and the object can be created in place and used immediately.

In order to support the use of Resolver objects, the configuration structure of the import-x/resolver configuration item needs to be modified.

Before:

export type ImportResolver =
  | LiteralUnion<'node' | 'typescript' | 'webpack', string>
  | {
      node?: boolean | NodeResolverOptions
      typescript?: boolean | TsResolverOptions
      webpack?: WebpackResolverOptions
      [resolve: string]: unknown
    }

After:

export type Resolver = {
  interfaceVersion?: 1 | 2
  resolve: ResolverResolve
  resolveImport: ResolverResolveImport
}

export type ImportResolverItem = {
  // Just for identification, doesn't actually matter
  // node, typescript, webpack...
  name?: string

  // Enabled by default
  enable?: boolean

  // Options passed to the resolver
  options?: NodeResolverOptions | TsResolverOptions | WebpackResolverOptions | unknown

  // Any object satisfied Resolver type
  resolver: Resolver
};

export type ImportResolver =
  | LiteralUnion<'node' | 'typescript' | 'webpack', string>
  | {
      node?: boolean | NodeResolverOptions
      typescript?: boolean | TsResolverOptions
      webpack?: WebpackResolverOptions
      [resolve: string]: unknown
    }
  | ImportResolverItem[]

Documentation links are broken due to fork versioning

The documentation URL generator function appears to have been broken by forking and changing versions.

import pkg from '../../package.json'

const repoUrl = 'https://github.com/un-ts/eslint-plugin-import-x'

export const docsUrl = (ruleName: string, commitish = `v${pkg.version}`) =>
  `${repoUrl}/blob/${commitish}/docs/rules/${ruleName}.md`

As the value of commitish is the current version of the package (0.5.0) by default, this generates the URL:
https://github.com/un-ts/eslint-plugin-import-x/blob/v0.5.0/docs/rules/newline-after-import.md.

Due to this being a fork of the original eslint-plugin-import which had a version 0.5.0, there is already a tag v0.5.0 from 9 years ago which does not include the docs folder, and therefore directs you to the incorrect location if using tools such as VSCode's ESLint extension which allows you to click the rule name to be taken to its documentation.

Dependency strategy

I'm still unsure whether to merge #66 as-is, that PR removes eslint v7 support, it is of course good to keep dependencies clean and updated, but it seems there are still many eslint v7 users.

image

On the other hand, eslint v9 is a big major version, it removes legacy RuleTester class and made previous FlatRuleTester as now RuleTester, so it's difficult to test eslint v9- versions and v9+ at the same time. Maybe we can use something like "eslint9": "npm:eslint^9.0.0-rc.0" to test flat config only for eslint v9.

For @typescript-eslint/utils, I don't know how many efforts it would take to support both v6 and v7 for eslint v7.

However, the last version of eslint v7 was released 3 years ago, maybe we should just consider it as legacy and drop its support.

cc @SukkaW @antfu

Release final version

Would it be possible to release a final version ? The last one is a pre-release one

Does not recognize `i/extensions`

It seems the plugin does not recognize this:

settings:
  i/extensions: [".js", ".jsx", ".ts", ".tsx"]

It only worked after renaming to import/extensions.

New resolver design

I haven't remove the resolver concept in eslint-plugin-import-x<=0.2 because I found that the webpack resolver may be still useful for those webpack users, and although we can use enhanced-resolve directly, but the settings can not fit all projects, I need to figure out how to set the resolver correctly for specific projects.

For example:

  1. plain js
  2. plain typescript
  3. webpack specific syntaxes

I'm thinking the interface of import-x/resolver setting should be:

import type { ResolveOptions } from 'enhanced-resolve'

interface ResolverSettings {
  typescript?: boolean
  webpack?: boolean
  options?: ResolveOptions
}

By default, eslint-plugin-import-x should use enhanced-resolve directly to simulate native node resolve algorithm.

[3.0.1] Huge performance regression in import/no-cycle

Hi. Today I upgraded the plugin to version 3.0.1 and noticed a huge drop in performance in the no-cycle rule. Details below.

Setup

Depencecies:

{
  "eslint": "^9.6.0",
  "eslint-import-resolver-typescript": "^3.6.1",
  "eslint-plugin-import": "npm:eslint-plugin-import-x@^3.0.1",
  "eslint-plugin-import-x": "^3.0.1",
  "typescript": "^5.5.3",
  "typescript-eslint": "^8.0.0-alpha.39"
}
Eslint config, I only left the no-cycle rule
import importX from 'eslint-plugin-import-x';
import tseslint from 'typescript-eslint';

export default [
  {
    languageOptions: {
      parser: tseslint.parser,
      sourceType: 'module',
    },
  },
  {
    files: ['**/*.ts'],
    plugins: {
      'import-x': importX,
    },
    settings: {
      ...importX.configs.typescript.settings,
      'import-x/resolver': {
        typescript: {},
      },
    },
    rules: {
      'import-x/no-cycle': ['error', { maxDepth: 3 }],
    },
  },
];

I ran the test on these two machines.

macOS
System:
    OS: macOS 13.6.7
    CPU: (4) x64 Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz
    Memory: 5.96 GB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 22.4.0 - /usr/local/bin/node
    npm: 10.8.1 - /usr/local/bin/npm
    pnpm: 9.5.0 - /usr/local/bin/pnpm
Windows
  System:
    OS: Windows 10 10.0.19045
    CPU: (4) x64 Intel(R) Core(TM) i5-4690K CPU @ 3.50GHz
    Memory: 2.80 GB / 7.94 GB
  Binaries:
    Node: 22.4.1 - C:\Program Files\nodejs\node.EXE
    npm: 10.8.2 - C:\Program Files\nodejs\npm.CMD
    pnpm: 9.5.0 - C:\Program Files\nodejs\pnpm.CMD

Results:

MacOS:

[email protected]
    
Rule              | Time (ms) | Relative
:-----------------|----------:|--------:
import-x/no-cycle |  8580.409 |   100.0%

Rule              | Time (ms) | Relative
:-----------------|----------:|--------:
import-x/no-cycle |  8101.124 |   100.0%

Rule              | Time (ms) | Relative
:-----------------|----------:|--------:
import-x/no-cycle |  8239.801 |   100.0%


[email protected]

Rule              | Time (ms) | Relative
:-----------------|----------:|--------:
import-x/no-cycle | 25850.526 |   100.0%

Rule              | Time (ms) | Relative
:-----------------|----------:|--------:
import-x/no-cycle | 24692.786 |   100.0%

Rule              | Time (ms) | Relative
:-----------------|----------:|--------:
import-x/no-cycle | 26082.004 |   100.0%

Windows:

[email protected]

Rule              | Time (ms) | Relative
:-----------------|----------:|--------:
import-x/no-cycle | 20999.926 |   100.0%

Rule              | Time (ms) | Relative
:-----------------|----------:|--------:
import-x/no-cycle | 19591.972 |   100.0%

Rule              | Time (ms) | Relative
:-----------------|----------:|--------:
import-x/no-cycle | 19811.106 |   100.0%


[email protected]

Rule              | Time (ms) | Relative
:-----------------|----------:|--------:
import-x/no-cycle | 78557.409 |   100.0%

Rule              | Time (ms) | Relative
:-----------------|----------:|--------:
import-x/no-cycle | 82919.007 |   100.0%

Rule              | Time (ms) | Relative
:-----------------|----------:|--------:
import-x/no-cycle | 78773.430 |   100.0%

Summary

So these are the numbers. I ran the test on a fairly large TS codebase (~680 files). You can see that 3.0.1 is at least 3x slower on both machines, which is strange because this release was supposed to significantly improve no-cycle performance. What is also noteworthy to me are the test times on Windows compared to macOS with [email protected] , they're like ~2.5 times slower. I know both my pc's are old and rather slow, but Windows have slightly better cpu, it's also overclocked, so I don't understand why it's so slow there. But the times with [email protected] on Windows are really bad, which worries me the most. I would appreciate your help with this issue and let me know if you need more info from me.

the "plugins" field in presets need to be an object

When i am migrating from eslintrc to flat config, i got the following error

> eslint .


Oops! Something went wrong! :(

ESLint: 9.2.0


A config object has a "plugins" key defined as an array of strings.

Flat config requires "plugins" to be an object in this form:

    {
        plugins: {
            import-x: pluginObject
        }
    }

Please see the following page for information on how to convert your config object into the correct format:
https://eslint.org/docs/latest/use/configure/migration-guide#importing-plugins-and-custom-parsers

If you're using a shareable config that you cannot rewrite in flat config format, then use the compatibility utility:
https://eslint.org/docs/latest/use/configure/migration-guide#using-eslintrc-configs-in-flat-config

 ELIFECYCLE  Command failed with exit code 2.

After some research, i found the "plugins" key is defined in recommended preset:

Is it supposed to be a virtual plugin or a module? I'm glad to help improving it.

Full code example
import pluginImportX from "eslint-plugin-import-x";

export const imports = [
  pluginImportX.configs.recommended,
  pluginImportX.configs.typescript,
  {
    plugins: {
      import: pluginImportX,
    },
    rules: {
      "import-x/no-named-as-default": "off",
      "import-x/no-unresolved": ["error", { ignore: ["^virtual:"] }],
      "import-x/order": [
        "error",
        {
          groups: [
            "builtin",
            "external",
            "internal",
            "parent",
            "sibling",
            "index",
          ],
          pathGroups: [
            { pattern: "vue", group: "builtin", position: "before" },
          ],
          pathGroupsExcludedImportTypes: [],
          "newlines-between": "always",
          alphabetize: {
            order: "asc",
          },
        },
      ],
    },
  },
];

export default [
  ...imports
];

How to install with yarn?

I tried to install this using the instructions as given in the README, but I'm using yarn.

~/c/s/s/code ❯❯❯ yarn add  eslint-plugin-import@npm:eslint-plugin-i                                                                                        next ✱
➤ YN0000: ┌ Resolution step
➤ YN0016: │ eslint-plugin-import@npm:eslint-plugin-i: Registry failed to return tag "eslint-plugin-i"

I'll keep looking into a possible solution and report back here if I'm able to find one.

Rebase workflow fails because of branch protection

Since Sep 16, the rebase workflow fails to push. I think you may need to disable branch protection on GitHub UI for it to work again:

 Successfully rebased and updated refs/heads/fork-release.
remote: error: GH006: Protected branch update failed for refs/heads/fork-release.        
remote: error: Changes must be made through a pull request.        
To https://github.com/un-es/eslint-plugin-i
 ! [remote rejected] fork-release -> fork-release (protected branch hook declined)
error: failed to push some refs to 'https://github.com/un-es/eslint-plugin-i'

Add missing dependencies

Trying to use this package for the first time, I got:

Error: Failed to load plugin 'import' declared in '.eslintrc.js': Cannot find module 'array.prototype.flatmap'

Looks like because 2.28.0 added dependencies on:

  • array.prototype.flatmap
  • array.prototype.findlastindex
  • object.fromentries

Which means they should be added to dependencies here too (unless they're being handled some other way).

Workaround is just to add the missing dependency as a dev dependency in my project.

[feature] Allow for custom messaging or remove NPM specific messaging

Some of the error messages for this plugin specifically mention npm commands (like, no-extraneous-dependencies) which can be problematic if the established package manager in the codebase isn't npm. When dealing with a codebase maintained by a single person this isn't really a problem as that person will just know that they are using a specific package manager, but, in a codebase with a lot of developers, even if we've documented that we're using something other than npm, it can be confusing for a tool that we use say that we should use npm to fix an issue with our dependencies.

It would be very useful to either not mention npm explicitly and instead word it in a way that helps people find a solution based on their current expectations, or allow consumers of this plugin to override these messages to explicitly mention how to solve an issue with a specific toolset they have available in the codebase.

Relevant issue from upstream for more context: import-js#2434

import-x/namespace rule not detecting "toBuffer" in bwip-js

I'm using https://github.com/metafloor/bwip-js like so:

import * as bwipjs from 'bwip-js';

bwipjs.toBuffer({})

In VSCode, I see this tooltip/intellisense:

image

toBuffer is defined in the declaration file:

image

https://github.com/metafloor/bwip-js/blob/master/dist/bwip-js-node.d.ts#L192

"toBuffer" is only available in the node declaration, so I suspect this might be a case of the wrong declaration file being loaded. The bwip-js project uses package.json exports.

Environment

Performance benchmarks?

I'm interested in perhaps using this fork, but I'm curious what real-world performance improvements you've seen compared with the upstream project. It would be great to know how much faster I could expect this fork to be.

Manual rebase and sync upstream

@JounQin

eslint-plugin-i seems to be up of sync from upstream for months:

image

A manual rebase is required.


The object.groupby package can be replaced with this:

// This is a **non spec compliant** but works in practice replacement of `object.groupby` package.
const groupBy = (array, grouper) => array.reduce((acc, cur) => {
  const key = grouper(cur);
  (acc[key] = acc[key] || []).push(cur);
  return acc;
}, {});

And object.fromentries can be replaced with const { fromEntries } = Object;

``import-x/no-extraneous-dependencies`` settings not applying to custom files

Steps to reproduce

  1. Set the rule with the following configuration:
      'import-x/no-extraneous-dependencies': [
        'error',
        {
          devDependencies: ['*.config.ts', 'scripts/**/*.ts'],
          optionalDependencies: false,
          peerDependencies: false,
          bundledDependencies: false
        }
      ],
  1. In test.config.ts file, import a dependency defined in devDependencies in package.json

** What's expected?**
No error is logged, since the file is allowed to import dependencies from devDependencies

What happens?
The rule reports an error

Additional context
Upstream doesn't have this issue, so switching back to the original plugin will demonstrate the expected behaviour of this rule.

`eslint-plugin-r`?

Hey there!

I thought I would follow the same path and create a fork of eslint-plugin-react, eslint-plugin-r, shaving off unnecessary polyfills. It's nowhere near as well done, as it lacks auto-release feature for example, but if anyone's interested, here it is:

https://github.com/wojtekmaj/eslint-plugin-r

dependency resolve-pkg-maps is missing in 2.27.5-2

after the update from version 2.27.5-1 to 2.27.5-2 i get the error:

Oops! Something went wrong! :(

ESLint: 8.43.0

Error: Failed to load plugin 'import' declared in '.eslintrc.cjs': Cannot find module 'resolve-pkg-maps'

Error: Cannot find module 'tslib'

It appears that the source code requires tslib:

node_modules/eslint-plugin-import-x/lib/index.js

"use strict";
const tslib_1 = require("tslib");
const electron_1 = tslib_1.__importDefault(require("./config/electron"));
const errors_1 = tslib_1.__importDefault(require("./config/errors"));
const react_1 = tslib_1.__importDefault(require("./config/react"));
// …

but the package does not declare it in its dependencies. This causes the error if tslib has not been already installed by another package, and in Yarn PnP, unconditionally.

Action is broken

I think the rebase action is broken for a while. Can you please fix it?

Regression during upgrade from 2.26.0-2 to 2.27.5

Affected code:

export { DecodedIdToken } from 'firebase-admin/lib/auth/token-verifier';

Error: Unable to resolve path to module 'firebase-admin/lib/auth/token-verifier' import/no-unresolved

Versions before:

    "firebase-admin": "^11.5.0",
    "eslint-plugin-import": "npm:eslint-plugin-i@^2.26.0-2",

Versions after:

    "firebase-admin": "^11.5.0",
    "eslint-plugin-import": "npm:eslint-plugin-i@^2.27.5",

[Bug?] no-unused-modules (and deprecation)

Hey there,

so there are two possibilities: either I'm completely confused and can't see what I'm doing wrong or this is a real bug.

Setting the rule 'import-x/no-unused-modules' results in the following error in the output of vscode:

No ESLint configuration (e.g .eslintrc) found for file: .\eslint-config-404\eslint.config.js
File will not be validated. Consider running 'eslint --init' in the workspace folder eslint-config-404
Alternatively you can disable ESLint by executing the 'Disable ESLint' command.

And the usual one in the cli:

Oops! Something went wrong! :(
ESLint: 9.4.0
ESLint couldn't find a configuration file. To set up a configuration file for this project, please run: ...

While using the following setup:

node -v v20.9.0
VS Code ESLint extension v2.4.4
"@eslint/eslintrc": "^3.1.0",
"eslint": "^9.4.0",
"eslint-plugin-import-x": "^0.5.1"

Here's a reproduction of the error:
https://github.com/error-four-o-four/eslint-config-404/blob/repro-no-unused-modules/eslint.config.js

Additionally

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.
  • I have searched for related issues and found none that matched my issue.
  • I have read the FAQ

deps: upgrade `minimatch` to v9 but it fails on some cases

For anyone may be interested, I just upgraded debug to v4 and removed unused resolve dependencies at v2.29.1. And I tried to upgrade minimatch to v9 but it fails on some cases like

import-js#2900 (comment)

and

https://github.com/import-js/eslint-plugin-import/blob/ee5fadeffff68f2300bed7f67a310496cb969d61/tests/src/rules/no-internal-modules.js

I don't have enough time to work on this replacement, anyone interested can help to raise a PR which will be appreciated.


For import-js#2900 (comment), I think it should be changed to invalid cases instead.

Originally posted by @JounQin in #11 (comment)

Support ESLint v9.0

The context interface has changed, and removed in v9.0. For example: https://eslint.org/blog/2023/09/preparing-custom-rules-eslint-v9/#context.getscope()

This plugin on ESLint v9.0.0-rc.0 will throw errors like:
image

I tried to check the codebase, but it seems the overall dependencies of this repo are still a bit left behind. Like @typescript-eslint/utils is still v5 while now it's v7 - some the we don't even have the compact types for the new APIs - I wonder what's the strategies of this repo, should we keep support eslint v7 and v8, or we could do a major that only support latest v8.40+ + v9?

feature: `prefer-node-protocol`

We're using eslint-plugin-unicorn for a single rule that would make sense to have in this plugin:
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-node-protocol.md

I'd love to switch to this plugin since it has half as many dependencies. See https://npmgraph.js.org/?q=eslint-plugin-unicorn vs https://npmgraph.js.org/?q=eslint-plugin-import-x (and maybe we could cut it in half again if removing globby from @typescript-eslint/typescript-estree)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.