| [9af201e] | 1 | # import/extensions
|
|---|
| 2 |
|
|---|
| 3 | <!-- end auto-generated rule header -->
|
|---|
| 4 |
|
|---|
| 5 | Some file resolve algorithms allow you to omit the file extension within the import source path. For example the `node` resolver (which does not yet support ESM/`import`) can resolve `./foo/bar` to the absolute path `/User/someone/foo/bar.js` because the `.js` extension is resolved automatically by default in CJS. Depending on the resolver you can configure more extensions to get resolved automatically.
|
|---|
| 6 |
|
|---|
| 7 | In order to provide a consistent use of file extensions across your code base, this rule can enforce or disallow the use of certain file extensions.
|
|---|
| 8 |
|
|---|
| 9 | ## Rule Details
|
|---|
| 10 |
|
|---|
| 11 | 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.
|
|---|
| 12 |
|
|---|
| 13 | ```jsonc
|
|---|
| 14 | "import/extensions": [<severity>, "never" | "always" | "ignorePackages"]
|
|---|
| 15 | ```
|
|---|
| 16 |
|
|---|
| 17 | By providing an object you can configure each extension separately.
|
|---|
| 18 |
|
|---|
| 19 | ```jsonc
|
|---|
| 20 | "import/extensions": [<severity>, {
|
|---|
| 21 | <extension>: "never" | "always" | "ignorePackages"
|
|---|
| 22 | }]
|
|---|
| 23 | ```
|
|---|
| 24 |
|
|---|
| 25 | For example `{ "js": "always", "json": "never" }` would always enforce the use of the `.js` extension but never allow the use of the `.json` extension.
|
|---|
| 26 |
|
|---|
| 27 | 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.
|
|---|
| 28 |
|
|---|
| 29 | ```jsonc
|
|---|
| 30 | "import/extensions": [
|
|---|
| 31 | <severity>,
|
|---|
| 32 | "never" | "always" | "ignorePackages",
|
|---|
| 33 | {
|
|---|
| 34 | <extension>: "never" | "always" | "ignorePackages"
|
|---|
| 35 | }
|
|---|
| 36 | ]
|
|---|
| 37 | ```
|
|---|
| 38 |
|
|---|
| 39 | For example, `["error", "never", { "svg": "always" }]` would require that all extensions are omitted, except for "svg".
|
|---|
| 40 |
|
|---|
| 41 | `ignorePackages` can be set as a separate boolean option like this:
|
|---|
| 42 |
|
|---|
| 43 | ```jsonc
|
|---|
| 44 | "import/extensions": [
|
|---|
| 45 | <severity>,
|
|---|
| 46 | "never" | "always" | "ignorePackages",
|
|---|
| 47 | {
|
|---|
| 48 | ignorePackages: true | false,
|
|---|
| 49 | pattern: {
|
|---|
| 50 | <extension>: "never" | "always" | "ignorePackages"
|
|---|
| 51 | }
|
|---|
| 52 | }
|
|---|
| 53 | ]
|
|---|
| 54 | ```
|
|---|
| 55 |
|
|---|
| 56 | In that case, if you still want to specify extensions, you can do so inside the **pattern** property.
|
|---|
| 57 | Default value of `ignorePackages` is `false`.
|
|---|
| 58 |
|
|---|
| 59 | 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`.
|
|---|
| 60 |
|
|---|
| 61 | 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.
|
|---|
| 62 | This is especially troublesome if you have import specifiers that [look like externals or builtins](./order.md#how-imports-are-grouped).
|
|---|
| 63 |
|
|---|
| 64 | Set `pathGroupOverrides` to force this rule to always ignore certain imports and never ignore others.
|
|---|
| 65 | `pathGroupOverrides` accepts an array of one or more [`PathGroupOverride`](#pathgroupoverride) objects.
|
|---|
| 66 |
|
|---|
| 67 | For example:
|
|---|
| 68 |
|
|---|
| 69 | ```jsonc
|
|---|
| 70 | "import/extensions": [
|
|---|
| 71 | <severity>,
|
|---|
| 72 | "never" | "always" | "ignorePackages",
|
|---|
| 73 | {
|
|---|
| 74 | ignorePackages: true | false,
|
|---|
| 75 | pattern: {
|
|---|
| 76 | <extension>: "never" | "always" | "ignorePackages"
|
|---|
| 77 | },
|
|---|
| 78 | pathGroupOverrides: [
|
|---|
| 79 | {
|
|---|
| 80 | pattern: "package-name-to-ignore",
|
|---|
| 81 | action: "ignore",
|
|---|
| 82 | },
|
|---|
| 83 | {
|
|---|
| 84 | pattern: "bespoke+alias:{*,*/**}",
|
|---|
| 85 | action: "enforce",
|
|---|
| 86 | }
|
|---|
| 87 | ]
|
|---|
| 88 | }
|
|---|
| 89 | ]
|
|---|
| 90 | ```
|
|---|
| 91 |
|
|---|
| 92 | > \[!NOTE]
|
|---|
| 93 | >
|
|---|
| 94 | > `pathGroupOverrides` is inspired by [`pathGroups` in `'import/order'`](./order.md#pathgroups) and shares a similar interface.
|
|---|
| 95 | > If you're using `pathGroups` already, you may find `pathGroupOverrides` very useful.
|
|---|
| 96 |
|
|---|
| 97 | ### `PathGroupOverride`
|
|---|
| 98 |
|
|---|
| 99 | | property | required | type | description |
|
|---|
| 100 | | :--------------: | :------: | :---------------------: | --------------------------------------------------------------- |
|
|---|
| 101 | | `pattern` | ☑️ | `string` | [Minimatch pattern][16] for specifier matching |
|
|---|
| 102 | | `patternOptions` | | `object` | [Minimatch options][17]; default: `{nocomment: true}` |
|
|---|
| 103 | | `action` | ☑️ | `"enforce" \| "ignore"` | What action to take on imports whose specifiers match `pattern` |
|
|---|
| 104 |
|
|---|
| 105 | ### Exception
|
|---|
| 106 |
|
|---|
| 107 | 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.
|
|---|
| 108 |
|
|---|
| 109 | For example, given the following folder structure:
|
|---|
| 110 |
|
|---|
| 111 | ```pt
|
|---|
| 112 | ├── foo
|
|---|
| 113 | │ ├── bar.js
|
|---|
| 114 | │ ├── bar.json
|
|---|
| 115 | ```
|
|---|
| 116 |
|
|---|
| 117 | and this import statement:
|
|---|
| 118 |
|
|---|
| 119 | ```js
|
|---|
| 120 | import bar from './foo/bar.json';
|
|---|
| 121 | ```
|
|---|
| 122 |
|
|---|
| 123 | then the extension can’t be omitted because it would then resolve to `./foo/bar.js`.
|
|---|
| 124 |
|
|---|
| 125 | ### Examples
|
|---|
| 126 |
|
|---|
| 127 | The following patterns are considered problems when configuration set to "never":
|
|---|
| 128 |
|
|---|
| 129 | ```js
|
|---|
| 130 | import foo from './foo.js';
|
|---|
| 131 |
|
|---|
| 132 | import bar from './bar.json';
|
|---|
| 133 |
|
|---|
| 134 | import Component from './Component.jsx';
|
|---|
| 135 |
|
|---|
| 136 | import express from 'express/index.js';
|
|---|
| 137 | ```
|
|---|
| 138 |
|
|---|
| 139 | The following patterns are not considered problems when configuration set to "never":
|
|---|
| 140 |
|
|---|
| 141 | ```js
|
|---|
| 142 | import foo from './foo';
|
|---|
| 143 |
|
|---|
| 144 | import bar from './bar';
|
|---|
| 145 |
|
|---|
| 146 | import Component from './Component';
|
|---|
| 147 |
|
|---|
| 148 | import express from 'express/index';
|
|---|
| 149 |
|
|---|
| 150 | import * as path from 'path';
|
|---|
| 151 | ```
|
|---|
| 152 |
|
|---|
| 153 | The following patterns are considered problems when the configuration is set to "never" and the option "checkTypeImports" is set to `true`:
|
|---|
| 154 |
|
|---|
| 155 | ```js
|
|---|
| 156 | import type { Foo } from './foo.ts';
|
|---|
| 157 |
|
|---|
| 158 | export type { Foo } from './foo.ts';
|
|---|
| 159 | ```
|
|---|
| 160 |
|
|---|
| 161 | The following patterns are considered problems when configuration set to "always":
|
|---|
| 162 |
|
|---|
| 163 | ```js
|
|---|
| 164 | import foo from './foo';
|
|---|
| 165 |
|
|---|
| 166 | import bar from './bar';
|
|---|
| 167 |
|
|---|
| 168 | import Component from './Component';
|
|---|
| 169 |
|
|---|
| 170 | import foo from '@/foo';
|
|---|
| 171 | ```
|
|---|
| 172 |
|
|---|
| 173 | The following patterns are not considered problems when configuration set to "always":
|
|---|
| 174 |
|
|---|
| 175 | ```js
|
|---|
| 176 | import foo from './foo.js';
|
|---|
| 177 |
|
|---|
| 178 | import bar from './bar.json';
|
|---|
| 179 |
|
|---|
| 180 | import Component from './Component.jsx';
|
|---|
| 181 |
|
|---|
| 182 | import * as path from 'path';
|
|---|
| 183 |
|
|---|
| 184 | import foo from '@/foo.js';
|
|---|
| 185 | ```
|
|---|
| 186 |
|
|---|
| 187 | The following patterns are considered problems when configuration set to "ignorePackages":
|
|---|
| 188 |
|
|---|
| 189 | ```js
|
|---|
| 190 | import foo from './foo';
|
|---|
| 191 |
|
|---|
| 192 | import bar from './bar';
|
|---|
| 193 |
|
|---|
| 194 | import Component from './Component';
|
|---|
| 195 |
|
|---|
| 196 | ```
|
|---|
| 197 |
|
|---|
| 198 | The following patterns are not considered problems when configuration set to "ignorePackages":
|
|---|
| 199 |
|
|---|
| 200 | ```js
|
|---|
| 201 | import foo from './foo.js';
|
|---|
| 202 |
|
|---|
| 203 | import bar from './bar.json';
|
|---|
| 204 |
|
|---|
| 205 | import Component from './Component.jsx';
|
|---|
| 206 |
|
|---|
| 207 | import express from 'express';
|
|---|
| 208 |
|
|---|
| 209 | import foo from '@/foo'
|
|---|
| 210 | ```
|
|---|
| 211 |
|
|---|
| 212 | The following patterns are not considered problems when configuration set to `['error', 'always', {ignorePackages: true} ]`:
|
|---|
| 213 |
|
|---|
| 214 | ```js
|
|---|
| 215 | import Component from './Component.jsx';
|
|---|
| 216 |
|
|---|
| 217 | import baz from 'foo/baz.js';
|
|---|
| 218 |
|
|---|
| 219 | import express from 'express';
|
|---|
| 220 |
|
|---|
| 221 | import foo from '@/foo';
|
|---|
| 222 | ```
|
|---|
| 223 |
|
|---|
| 224 | The following patterns are considered problems when the configuration is set to "always" and the option "checkTypeImports" is set to `true`:
|
|---|
| 225 |
|
|---|
| 226 | ```js
|
|---|
| 227 | import type { Foo } from './foo';
|
|---|
| 228 |
|
|---|
| 229 | export type { Foo } from './foo';
|
|---|
| 230 | ```
|
|---|
| 231 |
|
|---|
| 232 | ## When Not To Use It
|
|---|
| 233 |
|
|---|
| 234 | If you are not concerned about a consistent usage of file extension.
|
|---|
| 235 |
|
|---|
| 236 | 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.
|
|---|
| 237 |
|
|---|
| 238 | [16]: https://www.npmjs.com/package/minimatch#features
|
|---|
| 239 | [17]: https://www.npmjs.com/package/minimatch#options
|
|---|