Skip to content

Commit abf805f

Browse files
authored
import-style: Support node: builtins (#3207)
1 parent d52f71b commit abf805f

5 files changed

Lines changed: 171 additions & 81 deletions

File tree

docs/rules/import-style.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
Sometimes a module contains unrelated functions, like `util`, thus it is a good practice to enforce destructuring or named imports here. Other times, in modules like `path`, it is good to use default import as they have similar functions, all likely to be utilized.
1111

12-
This rule only applies to modules listed in the `styles` option. Imports of unlisted modules are not affected.
12+
This rule applies to modules listed in the `styles` option and the default styles below. Other imports are not affected.
1313

1414
This rule defines 4 import styles:
1515

@@ -39,6 +39,14 @@ import * as util from 'node:util';
3939
import {promisify} from 'node:util';
4040
```
4141

42+
```js
43+
//
44+
import * as path from 'node:path';
45+
46+
//
47+
import path from 'node:path';
48+
```
49+
4250
## Options
4351

4452
### styles
@@ -49,9 +57,11 @@ You can extend default import styles per module by passing the `styles` option.
4957

5058
Default options per module are:
5159

52-
- `util` - `named` only
53-
- `path` - `default` only
5460
- `chalk` - `default` only
61+
- `path` - `default` only
62+
- `util` - `named` only
63+
64+
Imports with the `node:` protocol are matched as if the protocol were omitted. For example, `node:util` uses the same style as `util`. Configure these modules by their bare name, like `util` or `path`.
5565

5666
The example below:
5767

rules/import-style.js

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const messages = {
88
[MESSAGE_ID_BANNED]: 'All import styles are disabled for module `{{moduleName}}`. Use the `no-restricted-imports` rule to disallow a module.',
99
};
1010
const disjunctionListFormat = new Intl.ListFormat('en-US', {type: 'disjunction'});
11+
const NODE_PROTOCOL = 'node:';
1112

1213
const getActualImportDeclarationStyles = importDeclaration => {
1314
const {specifiers} = importDeclaration;
@@ -110,6 +111,11 @@ const isAssignedDynamicImport = node =>
110111
&& node.parent.parent.type === 'VariableDeclarator'
111112
&& node.parent.parent.init === node.parent;
112113

114+
const getModuleStyleName = moduleName =>
115+
typeof moduleName === 'string' && moduleName.startsWith(NODE_PROTOCOL)
116+
? moduleName.slice(NODE_PROTOCOL.length)
117+
: moduleName;
118+
113119
// Keep this alphabetically sorted for easier maintenance
114120
const defaultStyles = {
115121
chalk: {
@@ -118,15 +124,9 @@ const defaultStyles = {
118124
path: {
119125
default: true,
120126
},
121-
'node:path': {
122-
default: true,
123-
},
124127
util: {
125128
named: true,
126129
},
127-
'node:util': {
128-
named: true,
129-
},
130130
};
131131

132132
/** @param {import('eslint').Rule.RuleContext} context */
@@ -158,14 +158,16 @@ const create = context => {
158158

159159
const {sourceCode} = context;
160160

161-
// eslint-disable-next-line max-params
162-
const report = (node, moduleName, actualImportStyles, allowedImportStyles, isRequire = false) => {
161+
const report = (node, moduleName, actualImportStyles, isRequire = false) => {
162+
const moduleStyleName = getModuleStyleName(moduleName);
163+
const allowedImportStyles = styles.get(moduleStyleName);
164+
163165
if (!allowedImportStyles) {
164166
return;
165167
}
166168

167169
if (allowedImportStyles.size === 0) {
168-
if (bannedModules.has(moduleName)) {
170+
if (bannedModules.has(moduleStyleName)) {
169171
context.report({
170172
node,
171173
messageId: MESSAGE_ID_BANNED,
@@ -206,11 +208,9 @@ const create = context => {
206208
if (checkImport) {
207209
context.on('ImportDeclaration', node => {
208210
const moduleName = getStringIfConstant(node.source, sourceCode.getScope(node.source));
209-
210-
const allowedImportStyles = styles.get(moduleName);
211211
const actualImportStyles = getActualImportDeclarationStyles(node);
212212

213-
report(node, moduleName, actualImportStyles, allowedImportStyles);
213+
report(node, moduleName, actualImportStyles);
214214
});
215215
}
216216

@@ -221,10 +221,9 @@ const create = context => {
221221
}
222222

223223
const moduleName = getStringIfConstant(node.source, sourceCode.getScope(node.source));
224-
const allowedImportStyles = styles.get(moduleName);
225224
const actualImportStyles = ['unassigned'];
226225

227-
report(node, moduleName, actualImportStyles, allowedImportStyles);
226+
report(node, moduleName, actualImportStyles);
228227
});
229228

230229
context.on('VariableDeclarator', node => {
@@ -243,21 +242,19 @@ const create = context => {
243242
}
244243

245244
const assignmentTargetNode = node.id;
246-
const allowedImportStyles = styles.get(moduleName);
247245
const actualImportStyles = getActualAssignmentTargetImportStyles(assignmentTargetNode);
248246

249-
report(node, moduleName, actualImportStyles, allowedImportStyles);
247+
report(node, moduleName, actualImportStyles);
250248
});
251249
}
252250

253251
if (checkExportFrom) {
254252
context.on('ExportAllDeclaration', node => {
255253
const moduleName = getStringIfConstant(node.source, sourceCode.getScope(node.source));
256254

257-
const allowedImportStyles = styles.get(moduleName);
258255
const actualImportStyles = ['namespace'];
259256

260-
report(node, moduleName, actualImportStyles, allowedImportStyles);
257+
report(node, moduleName, actualImportStyles);
261258
});
262259

263260
context.on('ExportNamedDeclaration', node => {
@@ -267,10 +264,9 @@ const create = context => {
267264

268265
const moduleName = getStringIfConstant(node.source, sourceCode.getScope(node.source));
269266

270-
const allowedImportStyles = styles.get(moduleName);
271267
const actualImportStyles = getActualExportDeclarationStyles(node);
272268

273-
report(node, moduleName, actualImportStyles, allowedImportStyles);
269+
report(node, moduleName, actualImportStyles);
274270
});
275271
}
276272

@@ -288,10 +284,9 @@ const create = context => {
288284
}
289285

290286
const moduleName = getStringIfConstant(node.arguments[0], sourceCode.getScope(node.arguments[0]));
291-
const allowedImportStyles = styles.get(moduleName);
292287
const actualImportStyles = ['unassigned'];
293288

294-
report(node, moduleName, actualImportStyles, allowedImportStyles, true);
289+
report(node, moduleName, actualImportStyles, true);
295290
});
296291

297292
context.on('VariableDeclarator', node => {
@@ -311,10 +306,9 @@ const create = context => {
311306
}
312307

313308
const assignmentTargetNode = node.id;
314-
const allowedImportStyles = styles.get(moduleName);
315309
const actualImportStyles = getActualAssignmentTargetImportStyles(assignmentTargetNode);
316310

317-
report(node, moduleName, actualImportStyles, allowedImportStyles, true);
311+
report(node, moduleName, actualImportStyles, true);
318312
});
319313
}
320314
};

0 commit comments

Comments
 (0)