Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ This plugin intends to support linting of ES2015+ (ES6+) import/export syntax, a
| [consistent-type-specifier-style](docs/rules/consistent-type-specifier-style.md) | Enforce or ban the use of inline type-only markers for named imports. | | | | 🔧 | | |
| [dynamic-import-chunkname](docs/rules/dynamic-import-chunkname.md) | Enforce a leading comment with the webpackChunkName for dynamic imports. | | | | | 💡 | |
| [exports-last](docs/rules/exports-last.md) | Ensure all exports appear after other statements. | | | | | | |
| [extensions](docs/rules/extensions.md) | Ensure consistent use of file extension within the import path. | | | | | | |
| [extensions](docs/rules/extensions.md) | Ensure consistent use of file extension within the import path. | | | | 🔧 | | |
| [first](docs/rules/first.md) | Ensure all imports appear before other statements. | | | | 🔧 | | |
| [group-exports](docs/rules/group-exports.md) | Prefer named exports to be grouped together in a single export declaration | | | | | | |
| [imports-first](docs/rules/imports-first.md) | Replaced by `import/first`. | | | | 🔧 | | ❌ |
Expand Down
2 changes: 2 additions & 0 deletions docs/rules/extensions.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# import/extensions

🔧 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 -->

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.
Expand Down
27 changes: 26 additions & 1 deletion src/rules/extensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ function buildProperties(context) {
defaultConfig: 'never',
pattern: {},
ignorePackages: false,
fix: false,
};

context.options.forEach((obj) => {
Expand All @@ -72,6 +73,11 @@ function buildProperties(context) {
result.ignorePackages = obj.ignorePackages;
}

// If fix is provided, transfer it to result
if (obj.fix !== undefined) {
result.fix = obj.fix;
}

if (obj.checkTypeImports !== undefined) {
result.checkTypeImports = obj.checkTypeImports;
}
Expand All @@ -97,7 +103,7 @@ module.exports = {
description: 'Ensure consistent use of file extension within the import path.',
url: docsUrl('extensions'),
},

fixable: 'code',
schema: {
anyOf: [
{
Expand Down Expand Up @@ -225,13 +231,32 @@ module.exports = {
node: source,
message:
`Missing file extension ${extension ? `"${extension}" ` : ''}for "${importPathWithQueryString}"`,
...props.fix && extension ? {
fix(fixer) {
return fixer.replaceText(
source,
JSON.stringify(`${importPathWithQueryString}.${extension}`),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See https://github.com/un-ts/eslint-plugin-import-x/pull/329/files#r2094349587

JSON.stringify is not correct for single quoted imports.

https://github.com/un-ts/eslint-plugin-import-x/pull/327/files#r2094298890

importPathWithQueryString could contains query and hash, and could also ends with ., .. or /.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done thank you

);
},
} : {},
});
}
} else if (extension) {
if (isUseOfExtensionForbidden(extension) && isResolvableWithoutExtension(importPath)) {
context.report({
node: source,
message: `Unexpected use of file extension "${extension}" for "${importPathWithQueryString}"`,
...props.fix
? {
fix(fixer) {
return fixer.replaceText(
source,
JSON.stringify(
importPath.slice(0, -(extension.length + 1)),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/un-ts/eslint-plugin-import-x/blob/813a4a087aa614a5577fe01c7f135317992d31ca/src/rules/extensions.ts#L410C11-L410C77

I believe you are also still using importPath.slice(0, -(extension.length + 1)),
I have implemented your last recommendations.

Thanks

),
);
},
} : {},
});
}
}
Expand Down
17 changes: 17 additions & 0 deletions tests/src/rules/extensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,16 @@ ruleTester.run('extensions', rule, {
].join('\n'),
options: ['always'],
}),

test({
code: "import foo from './foo';",
options: [{ fix: true }],
}),

test({
code: "import foo from './foo.js';",
options: [{ fix: true, pattern: { js: 'always' } }],
}),
],

invalid: [
Expand Down Expand Up @@ -652,6 +662,13 @@ ruleTester.run('extensions', rule, {
},
],
}),

test({
code: 'import foo from "./foo.js";',
options: ['always', { pattern: { js: 'never' }, fix: true }],
errors: [{ message: 'Unexpected use of file extension "js" for "./foo.js"' }],
output: 'import foo from "./foo";',
}),
],
});

Expand Down