Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: import-js/eslint-plugin-import
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: c5a094470b9984e1a83ffd740459cbaab739673d
Choose a base ref
..
head repository: import-js/eslint-plugin-import
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 2cf2a68323f28009be93a05b4ca8b0a0f117b380
Choose a head ref
13 changes: 13 additions & 0 deletions .github/workflows/node-pretest.yml
Original file line number Diff line number Diff line change
@@ -18,6 +18,19 @@ jobs:
# skip-ls-check: true
# - run: npm run pretest

types:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ljharb/actions/node/install@main
name: 'npm install'
with:
skip-ls-check: true
# for some reason we've got to force typescript to install here
# even though the npm script has `typescript@latest`
- run: npm i --force typescript@latest
- run: npm run test-types

posttest:
runs-on: ubuntu-latest

4 changes: 4 additions & 0 deletions .markdownlint.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
{
"line-length": false,
"ignore_case": true,
"no-duplicate-heading": {
"siblings_only": true
},
"ul-indent": {
"start_indent": 1,
"start_indented": true
19 changes: 17 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -6,6 +6,13 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange

## [Unreleased]

### Added
- add [`enforce-node-protocol-usage`] rule and `import/node-version` setting ([#3024], thanks [@GoldStrikeArch] and [@sevenc-nanashi])
- add TypeScript types ([#3097], thanks [@G-Rath])

### Changed
- [Docs] [`extensions`], [`order`]: improve documentation ([#3106], thanks [@Xunnamius])

## [2.31.0] - 2024-10-03

### Added
@@ -1103,10 +1110,12 @@ for info on changes for earlier releases.
[`import/core-modules` setting]: ./README.md#importcore-modules
[`import/external-module-folders` setting]: ./README.md#importexternal-module-folders
[`internal-regex` setting]: ./README.md#importinternal-regex
[`import/node-version` setting]: ./README.md#importnode-version

[`consistent-type-specifier-style`]: ./docs/rules/consistent-type-specifier-style.md
[`default`]: ./docs/rules/default.md
[`dynamic-import-chunkname`]: ./docs/rules/dynamic-import-chunkname.md
[`enforce-node-protocol-usage`]: ./docs/rules/enforce-node-protocol-usage.md
[`export`]: ./docs/rules/export.md
[`exports-last`]: ./docs/rules/exports-last.md
[`extensions`]: ./docs/rules/extensions.md
@@ -1152,6 +1161,8 @@ for info on changes for earlier releases.

[`memo-parser`]: ./memo-parser/README.md

[#3106]: https://github.com/import-js/eslint-plugin-import/pull/3106
[#3097]: https://github.com/import-js/eslint-plugin-import/pull/3097
[#3073]: https://github.com/import-js/eslint-plugin-import/pull/3073
[#3072]: https://github.com/import-js/eslint-plugin-import/pull/3072
[#3071]: https://github.com/import-js/eslint-plugin-import/pull/3071
@@ -1165,6 +1176,7 @@ for info on changes for earlier releases.
[#3036]: https://github.com/import-js/eslint-plugin-import/pull/3036
[#3033]: https://github.com/import-js/eslint-plugin-import/pull/3033
[#3032]: https://github.com/import-js/eslint-plugin-import/pull/3032
[#3024]: https://github.com/import-js/eslint-plugin-import/pull/3024
[#3018]: https://github.com/import-js/eslint-plugin-import/pull/3018
[#3012]: https://github.com/import-js/eslint-plugin-import/pull/3012
[#3011]: https://github.com/import-js/eslint-plugin-import/pull/3011
@@ -1784,7 +1796,6 @@ for info on changes for earlier releases.
[@bicstone]: https://github.com/bicstone
[@Blasz]: https://github.com/Blasz
[@bmish]: https://github.com/bmish
[@developer-bandi]: https://github.com/developer-bandi
[@borisyankov]: https://github.com/borisyankov
[@bradennapier]: https://github.com/bradennapier
[@bradzacher]: https://github.com/bradzacher
@@ -1804,6 +1815,7 @@ for info on changes for earlier releases.
[@darkartur]: https://github.com/darkartur
[@davidbonnet]: https://github.com/davidbonnet
[@dbrewer5]: https://github.com/dbrewer5
[@developer-bandi]: https://github.com/developer-bandi
[@devinrhode2]: https://github.com/devinrhode2
[@devongovett]: https://github.com/devongovett
[@dmnd]: https://github.com/dmnd
@@ -1838,6 +1850,7 @@ for info on changes for earlier releases.
[@georeith]: https://github.com/georeith
[@giodamelio]: https://github.com/giodamelio
[@gnprice]: https://github.com/gnprice
[@GoldStrikeArch]: https://github.com/GoldStrikeArch
[@golergka]: https://github.com/golergka
[@golopot]: https://github.com/golopot
[@GoodForOneFare]: https://github.com/GoodForOneFare
@@ -1897,9 +1910,9 @@ for info on changes for earlier releases.
[@Librazy]: https://github.com/Librazy
[@liby]: https://github.com/liby
[@lilling]: https://github.com/lilling
[@liuxingbaoyu]: https://github.com/liuxingbaoyu
[@ljharb]: https://github.com/ljharb
[@ljqx]: https://github.com/ljqx
[@liuxingbaoyu]: https://github.com/liuxingbaoyu
[@lo1tuma]: https://github.com/lo1tuma
[@loganfsmyth]: https://github.com/loganfsmyth
[@luczsoma]: https://github.com/luczsoma
@@ -1973,6 +1986,7 @@ for info on changes for earlier releases.
[@Schweinepriester]: https://github.com/Schweinepriester
[@scottnonnenberg]: https://github.com/scottnonnenberg
[@sergei-startsev]: https://github.com/sergei-startsev
[@sevenc-nanashi]: https://github.com/sevenc-nanashi
[@sharmilajesupaul]: https://github.com/sharmilajesupaul
[@sheepsteak]: https://github.com/sheepsteak
[@silverwind]: https://github.com/silverwind
@@ -2018,6 +2032,7 @@ for info on changes for earlier releases.
[@wtgtybhertgeghgtwtg]: https://github.com/wtgtybhertgeghgtwtg
[@xM8WVqaG]: https://github.com/xM8WVqaG
[@xpl]: https://github.com/xpl
[@Xunnamius]: https://github.com/Xunnamius
[@yesl-kim]: https://github.com/yesl-kim
[@yndajas]: https://github.com/yndajas
[@yordis]: https://github.com/yordis
47 changes: 31 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -51,22 +51,23 @@ This plugin intends to support linting of ES2015+ (ES6+) import/export syntax, a

### Static analysis

| Name                       | Description | 💼 | ⚠️ | 🚫 | 🔧 | 💡 ||
| :--------------------------------------------------------------------- | :----------------------------------------------------------------------------------- | :--- | :- | :- | :- | :- | :- |
| [default](docs/rules/default.md) | Ensure a default export is present, given a default import. | ❗ ☑️ | | | | | |
| [named](docs/rules/named.md) | Ensure named imports correspond to a named export in the remote file. | ❗ ☑️ | | ⌨️ | | | |
| [namespace](docs/rules/namespace.md) | Ensure imported namespaces contain dereferenced properties as they are dereferenced. | ❗ ☑️ | | | | | |
| [no-absolute-path](docs/rules/no-absolute-path.md) | Forbid import of modules using absolute paths. | | | | 🔧 | | |
| [no-cycle](docs/rules/no-cycle.md) | Forbid a module from importing a module with a dependency path back to itself. | | | | | | |
| [no-dynamic-require](docs/rules/no-dynamic-require.md) | Forbid `require()` calls with expressions. | | | | | | |
| [no-internal-modules](docs/rules/no-internal-modules.md) | Forbid importing the submodules of other modules. | | | | | | |
| [no-relative-packages](docs/rules/no-relative-packages.md) | Forbid importing packages through relative paths. | | | | 🔧 | | |
| [no-relative-parent-imports](docs/rules/no-relative-parent-imports.md) | Forbid importing modules from parent directories. | | | | | | |
| [no-restricted-paths](docs/rules/no-restricted-paths.md) | Enforce which files can be imported in a given folder. | | | | | | |
| [no-self-import](docs/rules/no-self-import.md) | Forbid a module from importing itself. | | | | | | |
| [no-unresolved](docs/rules/no-unresolved.md) | Ensure imports point to a file/module that can be resolved. | ❗ ☑️ | | | | | |
| [no-useless-path-segments](docs/rules/no-useless-path-segments.md) | Forbid unnecessary path segments in import and require statements. | | | | 🔧 | | |
| [no-webpack-loader-syntax](docs/rules/no-webpack-loader-syntax.md) | Forbid webpack loader syntax in imports. | | | | | | |
| Name                        | Description | 💼 | ⚠️ | 🚫 | 🔧 | 💡 ||
| :----------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------- | :--- | :- | :- | :- | :- | :- |
| [default](docs/rules/default.md) | Ensure a default export is present, given a default import. | ❗ ☑️ | | | | | |
| [enforce-node-protocol-usage](docs/rules/enforce-node-protocol-usage.md) | Enforce either using, or omitting, the `node:` protocol when importing Node.js builtin modules. | | | | 🔧 | | |
| [named](docs/rules/named.md) | Ensure named imports correspond to a named export in the remote file. | ❗ ☑️ | | ⌨️ | | | |
| [namespace](docs/rules/namespace.md) | Ensure imported namespaces contain dereferenced properties as they are dereferenced. | ❗ ☑️ | | | | | |
| [no-absolute-path](docs/rules/no-absolute-path.md) | Forbid import of modules using absolute paths. | | | | 🔧 | | |
| [no-cycle](docs/rules/no-cycle.md) | Forbid a module from importing a module with a dependency path back to itself. | | | | | | |
| [no-dynamic-require](docs/rules/no-dynamic-require.md) | Forbid `require()` calls with expressions. | | | | | | |
| [no-internal-modules](docs/rules/no-internal-modules.md) | Forbid importing the submodules of other modules. | | | | | | |
| [no-relative-packages](docs/rules/no-relative-packages.md) | Forbid importing packages through relative paths. | | | | 🔧 | | |
| [no-relative-parent-imports](docs/rules/no-relative-parent-imports.md) | Forbid importing modules from parent directories. | | | | | | |
| [no-restricted-paths](docs/rules/no-restricted-paths.md) | Enforce which files can be imported in a given folder. | | | | | | |
| [no-self-import](docs/rules/no-self-import.md) | Forbid a module from importing itself. | | | | | | |
| [no-unresolved](docs/rules/no-unresolved.md) | Ensure imports point to a file/module that can be resolved. | ❗ ☑️ | | | | | |
| [no-useless-path-segments](docs/rules/no-useless-path-segments.md) | Forbid unnecessary path segments in import and require statements. | | | | 🔧 | | |
| [no-webpack-loader-syntax](docs/rules/no-webpack-loader-syntax.md) | Forbid webpack loader syntax in imports. | | | | | | |

### Style guide

@@ -495,6 +496,20 @@ For example, if your packages in a monorepo are all in `@scope`, you can configu
}
```

### `import/node-version`

A string that represents the version of Node.js that you are using.
A falsy value will imply the version of Node.js that you are running ESLint with.

```jsonc
// .eslintrc
{
"settings": {
"import/node-version": "22.3.4",
},
}
```

## SublimeLinter-eslint

SublimeLinter-eslint introduced a change to support `.eslintignore` files
81 changes: 81 additions & 0 deletions docs/rules/enforce-node-protocol-usage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# import/enforce-node-protocol-usage

🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).

<!-- end auto-generated rule header -->

Enforce either using, or omitting, the `node:` protocol when importing Node.js builtin modules.

## Rule Details

This rule enforces that builtins node imports are using, or omitting, the `node:` protocol.

Determining whether a specifier is a core module depends on the node version being used to run `eslint`.
This version can be specified in the configuration with the [`import/node-version` setting](../../README.md#importnode-version).

Reasons to prefer using the protocol include:

- the code is more explicitly and clearly referencing a Node.js built-in module

Reasons to prefer omitting the protocol include:

- some tools don't support the `node:` protocol
- the code is more portable, because import maps and automatic polyfilling can be used

## Options

The rule requires a single string option which may be one of:

- `'always'` - enforces that builtins node imports are using the `node:` protocol.
- `'never'` - enforces that builtins node imports are not using the `node:` protocol.

## Examples

### `'always'`

❌ Invalid

```js
import fs from 'fs';
export { promises } from 'fs';
// require
const fs = require('fs/promises');
```

✅ Valid

```js
import fs from 'node:fs';
export { promises } from 'node:fs';
import * as test from 'node:test';
// require
const fs = require('node:fs/promises');
```

### `'never'`

❌ Invalid

```js
import fs from 'node:fs';
export { promises } from 'node:fs';
// require
const fs = require('node:fs/promises');
```

✅ Valid

```js
import fs from 'fs';
export { promises } from 'fs';

// require
const fs = require('fs/promises');

// This rule will not enforce not using `node:` protocol when the module is only available under the `node:` protocol.
import * as test from 'node:test';
```

## When Not To Use It

If you don't want to consistently enforce using, or omitting, the `node:` protocol when importing Node.js builtin modules.
55 changes: 51 additions & 4 deletions docs/rules/extensions.md
Original file line number Diff line number Diff line change
@@ -10,13 +10,13 @@ In order to provide a consistent use of file extensions across your code base, t

This rule either takes one string option, one object option, or a string and an object option. If it is the string `"never"` (the default value), then the rule forbids the use for any extension. If it is the string `"always"`, then the rule enforces the use of extensions for all import statements. If it is the string `"ignorePackages"`, then the rule enforces the use of extensions for all import statements except package imports.

```json
```jsonc
"import/extensions": [<severity>, "never" | "always" | "ignorePackages"]
```

By providing an object you can configure each extension separately.

```json
```jsonc
"import/extensions": [<severity>, {
<extension>: "never" | "always" | "ignorePackages"
}]
@@ -26,7 +26,7 @@ By providing an object you can configure each extension separately.

By providing both a string and an object, the string will set the default setting for all extensions, and the object can be used to set granular overrides for specific extensions.

```json
```jsonc
"import/extensions": [
<severity>,
"never" | "always" | "ignorePackages",
@@ -40,7 +40,7 @@ For example, `["error", "never", { "svg": "always" }]` would require that all ex

`ignorePackages` can be set as a separate boolean option like this:

```json
```jsonc
"import/extensions": [
<severity>,
"never" | "always" | "ignorePackages",
@@ -58,6 +58,50 @@ Default value of `ignorePackages` is `false`.

By default, `import type` and `export type` style imports/exports are ignored. If you want to check them as well, you can set the `checkTypeImports` option to `true`.

Unfortunately, in more advanced linting setups, such as when employing custom specifier aliases (e.g. you're using `eslint-import-resolver-alias`, `paths` in `tsconfig.json`, etc), this rule can be too coarse-grained when determining which imports to ignore and on which to enforce the config.
This is especially troublesome if you have import specifiers that [look like externals or builtins](./order.md#how-imports-are-grouped).

Set `pathGroupOverrides` to force this rule to always ignore certain imports and never ignore others.
`pathGroupOverrides` accepts an array of one or more [`PathGroupOverride`](#pathgroupoverride) objects.

For example:

```jsonc
"import/extensions": [
<severity>,
"never" | "always" | "ignorePackages",
{
ignorePackages: true | false,
pattern: {
<extension>: "never" | "always" | "ignorePackages"
},
pathGroupOverrides: [
{
pattern: "package-name-to-ignore",
action: "ignore",
},
{
pattern: "bespoke+alias:{*,*/**}",
action: "enforce",
}
]
}
]
```

> \[!NOTE]
>
> `pathGroupOverrides` is inspired by [`pathGroups` in `'import/order'`](./order.md#pathgroups) and shares a similar interface.
> If you're using `pathGroups` already, you may find `pathGroupOverrides` very useful.
### `PathGroupOverride`

| property | required | type | description |
| :--------------: | :------: | :---------------------: | --------------------------------------------------------------- |
| `pattern` | ☑️ | `string` | [Minimatch pattern][16] for specifier matching |
| `patternOptions` | | `object` | [Minimatch options][17]; default: `{nocomment: true}` |
| `action` | ☑️ | `"enforce" \| "ignore"` | What action to take on imports whose specifiers match `pattern` |

### Exception

When disallowing the use of certain extensions this rule makes an exception and allows the use of extension when the file would not be resolvable without extension.
@@ -190,3 +234,6 @@ export type { Foo } from './foo';
If you are not concerned about a consistent usage of file extension.

In the future, when this rule supports native node ESM resolution, and the plugin is configured to use native rather than transpiled ESM (a config option that is not yet available) - setting this to `always` will have no effect.

[16]: https://www.npmjs.com/package/minimatch#features
[17]: https://www.npmjs.com/package/minimatch#options
Loading