Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[dynamic-import-chunkname] Disallow chunk name when eager mode is enabled #3004

Merged
merged 1 commit into from May 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Expand Up @@ -8,6 +8,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange

### Added
- [`dynamic-import-chunkname`]: add `allowEmpty` option to allow empty leading comments ([#2942], thanks [@JiangWeixian])
- [`dynamic-import-chunkname`]: Allow empty chunk name when webpackMode: 'eager' is set; add suggestions to remove name in eager mode ([#3004], thanks [@amsardesai])

### Changed
- [Docs] `no-extraneous-dependencies`: Make glob pattern description more explicit ([#2944], thanks [@mulztob])
Expand Down Expand Up @@ -1115,6 +1116,7 @@ for info on changes for earlier releases.

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

[#3004]: https://github.com/import-js/eslint-plugin-import/pull/3004
[#2991]: https://github.com/import-js/eslint-plugin-import/pull/2991
[#2989]: https://github.com/import-js/eslint-plugin-import/pull/2989
[#2987]: https://github.com/import-js/eslint-plugin-import/pull/2987
Expand Down Expand Up @@ -1701,6 +1703,7 @@ for info on changes for earlier releases.
[@aladdin-add]: https://github.com/aladdin-add
[@alex-page]: https://github.com/alex-page
[@alexgorbatchev]: https://github.com/alexgorbatchev
[@amsardesai]: https://github.com/amsardesai
[@andreubotella]: https://github.com/andreubotella
[@AndrewLeedham]: https://github.com/AndrewLeedham
[@andyogo]: https://github.com/andyogo
Expand Down
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -73,7 +73,7 @@ This plugin intends to support linting of ES2015+ (ES6+) import/export syntax, a
| Name                            | Description | 💼 | ⚠️ | 🚫 | 🔧 | 💡 | ❌ |
| :------------------------------------------------------------------------------- | :------------------------------------------------------------------------- | :- | :---- | :- | :- | :- | :- |
| [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. | | | | | | |
| [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. | | | | | | |
| [first](docs/rules/first.md) | Ensure all imports appear before other statements. | | | | 🔧 | | |
Expand Down
9 changes: 9 additions & 0 deletions docs/rules/dynamic-import-chunkname.md
@@ -1,5 +1,7 @@
# import/dynamic-import-chunkname

💡 This rule is manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).

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

This rule reports any dynamic imports without a webpackChunkName specified in a leading block comment in the proper format.
Expand Down Expand Up @@ -56,6 +58,13 @@ import(
// webpackChunkName: "someModule"
'someModule',
);

// chunk names are disallowed when eager mode is set
import(
/* webpackMode: "eager" */
/* webpackChunkName: "someModule" */
'someModule',
)
```

### valid
Expand Down
51 changes: 49 additions & 2 deletions src/rules/dynamic-import-chunkname.js
Expand Up @@ -27,6 +27,7 @@ module.exports = {
},
},
}],
hasSuggestions: true,
},

create(context) {
Expand All @@ -36,8 +37,10 @@ module.exports = {

const paddedCommentRegex = /^ (\S[\s\S]+\S) $/;
const commentStyleRegex = /^( ((webpackChunkName: .+)|((webpackPrefetch|webpackPreload): (true|false|-?[0-9]+))|(webpackIgnore: (true|false))|((webpackInclude|webpackExclude): \/.*\/)|(webpackMode: ["'](lazy|lazy-once|eager|weak)["'])|(webpackExports: (['"]\w+['"]|\[(['"]\w+['"], *)+(['"]\w+['"]*)\]))),?)+ $/;
const chunkSubstrFormat = ` webpackChunkName: ["']${webpackChunknameFormat}["'],? `;
const chunkSubstrFormat = `webpackChunkName: ["']${webpackChunknameFormat}["'],? `;
ljharb marked this conversation as resolved.
Show resolved Hide resolved
const chunkSubstrRegex = new RegExp(chunkSubstrFormat);
const eagerModeFormat = `webpackMode: ["']eager["'],? `;
const eagerModeRegex = new RegExp(eagerModeFormat);

function run(node, arg) {
const sourceCode = context.getSourceCode();
Expand All @@ -54,6 +57,7 @@ module.exports = {
}

let isChunknamePresent = false;
let isEagerModePresent = false;

for (const comment of leadingComments) {
if (comment.type !== 'Block') {
Expand Down Expand Up @@ -92,12 +96,55 @@ module.exports = {
return;
}

if (eagerModeRegex.test(comment.value)) {
isEagerModePresent = true;
}

if (chunkSubstrRegex.test(comment.value)) {
isChunknamePresent = true;
}
}

if (!isChunknamePresent && !allowEmpty) {
if (isChunknamePresent && isEagerModePresent) {
context.report({
node,
message: 'dynamic imports using eager mode do not need a webpackChunkName',
suggest: [
{
desc: 'Remove webpackChunkName',
fix(fixer) {
for (const comment of leadingComments) {
if (chunkSubstrRegex.test(comment.value)) {
const replacement = comment.value.replace(chunkSubstrRegex, '').trim().replace(/,$/, '');
if (replacement === '') {
return fixer.remove(comment);
} else {
return fixer.replaceText(comment, `/* ${replacement} */`);
}
}
}
},
},
{
desc: 'Remove webpackMode',
fix(fixer) {
for (const comment of leadingComments) {
if (eagerModeRegex.test(comment.value)) {
const replacement = comment.value.replace(eagerModeRegex, '').trim().replace(/,$/, '');
if (replacement === '') {
return fixer.remove(comment);
} else {
return fixer.replaceText(comment, `/* ${replacement} */`);
}
}
}
},
},
],
});
}

if (!isChunknamePresent && !allowEmpty && !isEagerModePresent) {
context.report({
node,
message:
Expand Down