Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 950dec7

Browse files
committed
docs: document import/extensions slowness
1 parent 10ce912 commit 950dec7

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

docs/linting/Troubleshooting.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,69 @@ The following rules do not have equivalent checks in TypeScript, so we recommend
311311
- `import/no-unused-modules`
312312
- `import/no-deprecated`
313313

314+
#### `import/extensions`
315+
316+
There are two uses for this rule:
317+
318+
1. to enforce file extensions are always used,
319+
2. to enforce file extensions are never used.
320+
321+
##### Enforcing extensions are used
322+
323+
If you want to enforce file extensions are always used and you're **NOT** using `moduleResolution` `node16` or `nodenext`, then there's not really a good alternative for you, and you should continue using the `import/extensions` lint rule.
324+
325+
If you want to enforce file extensions are always used and you **ARE** using `moduleResolution` `node16` or `nodenext`, then you don't need to use the lint rule at all because TypeScript will automatically enforce that you include extensions (TS 2834 & 2835)!
326+
327+
##### Enforcing extensions are not used
328+
329+
On the surface `import/extensions` seems like it should be fast for this use case, however the rule isn't just a pure AST-check - it has to resolve modules on disk so that it doesn't false positive on cases where you are importing modules with an extension as part of their name (eg `foo.js` resolves to `node_modules/foo.js/index.js`, so the `.js` is required). This disk lookup is costly and thus makes the rule slow.
330+
331+
If your project doesn't use any `npm` packages with a file extension in their name, nor do you name your files with two extensions (like `bar.js.ts`), then this extra cost probably isn't worth it, and you can use a much simpler check using the [`no-restricted-syntax`](https://eslint.org/docs/latest/rules/no-restricted-syntax) lint rule.
332+
333+
The below config is several orders of magnitude faster than `import/extensions` as it does not do disk lookups, however it will false-positive on cases like the aforementioned `foo.js` module.
334+
335+
```js
336+
function banImportExtension(extension) {
337+
const message = `Unexpected use of file extension (.${extension}) in import`;
338+
const literalAttributeMatcher = `Literal[value=/\\.${extension}$/]`;
339+
return [
340+
{
341+
// import foo from 'bar.js';
342+
selector: `ImportDeclaration > ${literalAttributeMatcher}.source`,
343+
message,
344+
},
345+
{
346+
// const foo = import('bar.js');
347+
selector: `ImportExpression > ${literalAttributeMatcher}.source`,
348+
message,
349+
},
350+
{
351+
// type Foo = typeof import('bar.js');
352+
selector: `TSImportType > TSLiteralType > ${literalAttributeMatcher}`,
353+
message,
354+
},
355+
{
356+
// const foo = require('foo.js');
357+
selector: `CallExpression[callee.name = "require"] > ${literalAttributeMatcher}.arguments`,
358+
message,
359+
},
360+
];
361+
}
362+
363+
module.exports = {
364+
// ... other config ...
365+
rules: {
366+
'no-restricted-syntax': [
367+
'error',
368+
...banImportExtension('js'),
369+
...banImportExtension('jsx'),
370+
...banImportExtension('ts'),
371+
...banImportExtension('tsx'),
372+
],
373+
},
374+
};
375+
```
376+
314377
### The `indent` / `@typescript-eslint/indent` rules
315378

316379
This rule helps ensure your codebase follows a consistent indentation pattern.

0 commit comments

Comments
 (0)