Skip to content

Commit 1466bec

Browse files
authoredDec 10, 2024··
feat(resolve): allow overriding enhanced-resolve's options (#384)
1 parent af4f774 commit 1466bec

20 files changed

+153
-2
lines changed
 

‎docs/rules/no-extraneous-import.md

+5
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ Please see the shared settings documentation for more information.
3737
This can be configured in the rule options or as a shared setting [`settings.resolvePaths`](../shared-settings.md#resolvepaths).
3838
Please see the shared settings documentation for more information.
3939

40+
#### resolverConfig
41+
42+
This can be configured in the rule options or as a shared setting [`settings.resolverConfig`](../shared-settings.md#resolverconfig).
43+
Please see the shared settings documentation for more information.
44+
4045
#### convertPath
4146

4247
This can be configured in the rule options or as a shared setting [`settings.convertPath`](../shared-settings.md#convertpath).

‎docs/rules/no-extraneous-require.md

+5
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ Please see the shared settings documentation for more information.
3838
This can be configured in the rule options or as a shared setting [`settings.resolvePaths`](../shared-settings.md#resolvepaths).
3939
Please see the shared settings documentation for more information.
4040

41+
#### resolverConfig
42+
43+
This can be configured in the rule options or as a shared setting [`settings.resolverConfig`](../shared-settings.md#resolverconfig).
44+
Please see the shared settings documentation for more information.
45+
4146
#### convertPath
4247

4348
This can be configured in the rule options or as a shared setting [`settings.convertPath`](../shared-settings.md#convertpath).

‎docs/rules/no-missing-import.md

+5
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ Please see the shared settings documentation for more information.
5252
This can be configured in the rule options or as a shared setting [`settings.resolvePaths`](../shared-settings.md#resolvepaths).
5353
Please see the shared settings documentation for more information.
5454

55+
#### resolverConfig
56+
57+
This can be configured in the rule options or as a shared setting [`settings.resolverConfig`](../shared-settings.md#resolverconfig).
58+
Please see the shared settings documentation for more information.
59+
5560
#### tsconfigPath
5661

5762
This can be configured in the rule options or as a shared setting [`settings.tsconfigPath`](../shared-settings.md#tsconfigpath).

‎docs/rules/no-missing-require.md

+5
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ Please see the shared settings documentation for more information.
6060
This can be configured in the rule options or as a shared setting [`settings.resolvePaths`](../shared-settings.md#resolvepaths).
6161
Please see the shared settings documentation for more information.
6262

63+
#### resolverConfig
64+
65+
This can be configured in the rule options or as a shared setting [`settings.resolverConfig`](../shared-settings.md#resolverconfig).
66+
Please see the shared settings documentation for more information.
67+
6368
#### tryExtensions
6469

6570
This can be configured in the rule options or as a shared setting [`settings.tryExtensions`](../shared-settings.md#tryextensions).

‎docs/rules/no-unpublished-import.md

+5
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ Please see the shared settings documentation for more information.
4141
This can be configured in the rule options or as a shared setting [`settings.resolvePaths`](../shared-settings.md#resolvepaths).
4242
Please see the shared settings documentation for more information.
4343

44+
#### resolverConfig
45+
46+
This can be configured in the rule options or as a shared setting [`settings.resolverConfig`](../shared-settings.md#resolverconfig).
47+
Please see the shared settings documentation for more information.
48+
4449
#### convertPath
4550

4651
This can be configured in the rule options or as a shared setting [`settings.convertPath`](../shared-settings.md#convertpath).

‎docs/rules/no-unpublished-require.md

+5
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ Please see the shared settings documentation for more information.
4343
This can be configured in the rule options or as a shared setting [`settings.resolvePaths`](../shared-settings.md#resolvepaths).
4444
Please see the shared settings documentation for more information.
4545

46+
#### resolverConfig
47+
48+
This can be configured in the rule options or as a shared setting [`settings.resolverConfig`](../shared-settings.md#resolverconfig).
49+
Please see the shared settings documentation for more information.
50+
4651
#### convertPath
4752

4853
This can be configured in the rule options or as a shared setting [`settings.convertPath`](../shared-settings.md#convertpath).

‎docs/shared-settings.md

+24
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,30 @@ If a path is relative, it will be resolved from CWD.
6060
{ "resolvePaths": [] }
6161
```
6262

63+
## resolverConfig
64+
65+
Override the options generated by this plugin for resolving require and import statements.
66+
67+
While these options are passed down to [`enhanced-resolve`](https://github.com/webpack/enhanced-resolve)'s factory method, we only support a subset of the options they allow. These are documented below.
68+
69+
The options you define here are assigned over the default options generated by the plugin.
70+
71+
Supported options:
72+
73+
- `resolverConfig.modules`: A list of directories to resolve modules from, can be absolute path or folder name
74+
75+
### Example resolverConfig
76+
77+
```json
78+
{ "resolverConfig": { "modules": ["node_modules", "bower_components"] } }
79+
```
80+
81+
### Default resolverConfig
82+
83+
```json
84+
{ "resolverConfig": {} }
85+
```
86+
6387
## convertPath
6488

6589
If we use transpilers (e.g. Babel), perhaps the file path to a source code is never published.

‎lib/rules/no-extraneous-import.js

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const { checkExtraneous, messages } = require("../util/check-extraneous")
88
const getAllowModules = require("../util/get-allow-modules")
99
const getConvertPath = require("../util/get-convert-path")
1010
const getResolvePaths = require("../util/get-resolve-paths")
11+
const getResolverConfig = require("../util/get-resolver-config")
1112
const visitImport = require("../util/visit-import")
1213

1314
/** @type {import('eslint').Rule.RuleModule} */
@@ -28,6 +29,7 @@ module.exports = {
2829
allowModules: getAllowModules.schema,
2930
convertPath: getConvertPath.schema,
3031
resolvePaths: getResolvePaths.schema,
32+
resolverConfig: getResolverConfig.schema,
3133
},
3234
additionalProperties: false,
3335
},

‎lib/rules/no-extraneous-require.js

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const { checkExtraneous, messages } = require("../util/check-extraneous")
88
const getAllowModules = require("../util/get-allow-modules")
99
const getConvertPath = require("../util/get-convert-path")
1010
const getResolvePaths = require("../util/get-resolve-paths")
11+
const getResolverConfig = require("../util/get-resolver-config")
1112
const getTryExtensions = require("../util/get-try-extensions")
1213
const visitRequire = require("../util/visit-require")
1314

@@ -29,6 +30,7 @@ module.exports = {
2930
allowModules: getAllowModules.schema,
3031
convertPath: getConvertPath.schema,
3132
resolvePaths: getResolvePaths.schema,
33+
resolverConfig: getResolverConfig.schema,
3234
tryExtensions: getTryExtensions.schema,
3335
},
3436
additionalProperties: false,

‎lib/rules/no-missing-import.js

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
const { checkExistence, messages } = require("../util/check-existence")
88
const getAllowModules = require("../util/get-allow-modules")
99
const getResolvePaths = require("../util/get-resolve-paths")
10+
const getResolverConfig = require("../util/get-resolver-config")
1011
const getTryExtensions = require("../util/get-try-extensions")
1112
const getTSConfig = require("../util/get-tsconfig")
1213
const getTypescriptExtensionMap = require("../util/get-typescript-extension-map")
@@ -29,6 +30,7 @@ module.exports = {
2930
properties: {
3031
allowModules: getAllowModules.schema,
3132
resolvePaths: getResolvePaths.schema,
33+
resolverConfig: getResolverConfig.schema,
3234
tryExtensions: getTryExtensions.schema,
3335
ignoreTypeImport: { type: "boolean", default: false },
3436
tsconfigPath: getTSConfig.schema,

‎lib/rules/no-missing-require.js

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
const { checkExistence, messages } = require("../util/check-existence")
88
const getAllowModules = require("../util/get-allow-modules")
99
const getResolvePaths = require("../util/get-resolve-paths")
10+
const getResolverConfig = require("../util/get-resolver-config")
1011
const getTSConfig = require("../util/get-tsconfig")
1112
const getTryExtensions = require("../util/get-try-extensions")
1213
const getTypescriptExtensionMap = require("../util/get-typescript-extension-map")
@@ -30,6 +31,7 @@ module.exports = {
3031
allowModules: getAllowModules.schema,
3132
tryExtensions: getTryExtensions.schema,
3233
resolvePaths: getResolvePaths.schema,
34+
resolverConfig: getResolverConfig.schema,
3335
typescriptExtensionMap: getTypescriptExtensionMap.schema,
3436
tsconfigPath: getTSConfig.schema,
3537
},

‎lib/rules/no-unpublished-import.js

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const { checkPublish, messages } = require("../util/check-publish")
88
const getAllowModules = require("../util/get-allow-modules")
99
const getConvertPath = require("../util/get-convert-path")
1010
const getResolvePaths = require("../util/get-resolve-paths")
11+
const getResolverConfig = require("../util/get-resolver-config")
1112
const visitImport = require("../util/visit-import")
1213

1314
/** @type {import('eslint').Rule.RuleModule} */
@@ -28,6 +29,7 @@ module.exports = {
2829
allowModules: getAllowModules.schema,
2930
convertPath: getConvertPath.schema,
3031
resolvePaths: getResolvePaths.schema,
32+
resolverConfig: getResolverConfig.schema,
3133
ignoreTypeImport: { type: "boolean", default: false },
3234
ignorePrivate: { type: "boolean", default: true },
3335
},

‎lib/rules/no-unpublished-require.js

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const { checkPublish, messages } = require("../util/check-publish")
88
const getAllowModules = require("../util/get-allow-modules")
99
const getConvertPath = require("../util/get-convert-path")
1010
const getResolvePaths = require("../util/get-resolve-paths")
11+
const getResolverConfig = require("../util/get-resolver-config")
1112
const getTryExtensions = require("../util/get-try-extensions")
1213
const visitRequire = require("../util/visit-require")
1314

@@ -29,6 +30,7 @@ module.exports = {
2930
allowModules: getAllowModules.schema,
3031
convertPath: getConvertPath.schema,
3132
resolvePaths: getResolvePaths.schema,
33+
resolverConfig: getResolverConfig.schema,
3234
tryExtensions: getTryExtensions.schema,
3335
ignorePrivate: { type: "boolean", default: true },
3436
},

‎lib/util/get-resolver-config.js

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/**
2+
* @author Toru Nagashima
3+
* See LICENSE file in root directory for full license.
4+
*/
5+
"use strict"
6+
7+
/**
8+
* @typedef {Partial<import('enhanced-resolve').ResolveOptions>} ResolverConfig
9+
*/
10+
11+
/** @type {ResolverConfig} */
12+
const DEFAULT_VALUE = {}
13+
14+
/**
15+
* Gets `resolverConfig` property from a given option object.
16+
*
17+
* @param {{ resolverConfig: ResolverConfig } | undefined} option - An option object to get.
18+
* @returns {ResolverConfig | undefined} The `allowModules` value, or `null`.
19+
*/
20+
function get(option) {
21+
if (option?.resolverConfig) return option.resolverConfig
22+
}
23+
24+
/**
25+
* Gets "resolverConfig" setting.
26+
*
27+
* 1. This checks `options` property, then returns it if exists.
28+
* 2. This checks `settings.n` | `settings.node` property, then returns it if exists.
29+
* 3. This returns `[]`.
30+
*
31+
* @param {import('eslint').Rule.RuleContext} context - The rule context.
32+
* @returns {ResolverConfig} A resolver config object.
33+
*/
34+
module.exports = function getResolverConfig(context, optionIndex = 0) {
35+
return (
36+
get(context.options?.[optionIndex]) ??
37+
get(context.settings?.n) ??
38+
get(context.settings?.node) ??
39+
DEFAULT_VALUE
40+
)
41+
}
42+
43+
module.exports.schema = {
44+
type: "object",
45+
properties: {},
46+
additionalProperties: true,
47+
}

‎lib/util/import-target.js

+6
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ function getTSConfigAliases(context) {
7171
* @typedef Options
7272
* @property {string[]} [extensions]
7373
* @property {string[]} [paths]
74+
* @property {Partial<import('enhanced-resolve').ResolveOptions>} [resolverConfig]
7475
* @property {string} basedir
7576
*/
7677
/** @typedef { 'unknown' | 'relative' | 'absolute' | 'node' | 'npm' | 'http' } ModuleType */
@@ -323,6 +324,11 @@ module.exports = class ImportTarget {
323324
).backward
324325
}
325326

327+
this.resolverConfig = {
328+
...this.resolverConfig,
329+
...this.options.resolverConfig,
330+
}
331+
326332
const requireResolve = resolver.create.sync(this.resolverConfig)
327333

328334
const cwd = this.context.settings?.cwd ?? process.cwd()

‎lib/util/visit-import.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
const path = require("path")
88
const { isBuiltin } = require("node:module")
99
const getResolvePaths = require("./get-resolve-paths")
10+
const getResolverConfig = require("./get-resolver-config")
1011
const getTryExtensions = require("./get-try-extensions")
1112
const ImportTarget = require("./import-target")
1213
const stripImportPathParams = require("./strip-import-path-params")
@@ -41,8 +42,9 @@ module.exports = function visitImport(
4142
path.resolve(context.filename ?? context.getFilename())
4243
)
4344
const paths = getResolvePaths(context, optionIndex)
45+
const resolverConfig = getResolverConfig(context, optionIndex)
4446
const extensions = getTryExtensions(context, optionIndex)
45-
const options = { basedir, paths, extensions }
47+
const options = { basedir, paths, extensions, resolverConfig }
4648

4749
/**
4850
* @param {(

‎lib/util/visit-require.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const {
1212
} = require("@eslint-community/eslint-utils")
1313
const { isBuiltin } = require("node:module")
1414
const getResolvePaths = require("./get-resolve-paths")
15+
const getResolverConfig = require("./get-resolver-config")
1516
const getTryExtensions = require("./get-try-extensions")
1617
const ImportTarget = require("./import-target")
1718
const stripImportPathParams = require("./strip-import-path-params")
@@ -42,8 +43,9 @@ module.exports = function visitRequire(
4243
path.resolve(context.filename ?? context.getFilename())
4344
)
4445
const paths = getResolvePaths(context)
46+
const resolverConfig = getResolverConfig(context)
4547
const extensions = getTryExtensions(context)
46-
const options = { basedir, paths, extensions }
48+
const options = { basedir, paths, extensions, resolverConfig }
4749

4850
return {
4951
"Program:exit"(node) {

‎tests/fixtures/no-missing/my_modules/my-module/a-file.js

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"main": "./a-file.js"
3+
}

‎tests/lib/rules/no-missing-require.js

+25
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,31 @@ ruleTester.run("no-missing-require", rule, {
141141
options: [{ resolvePaths: ["tests"] }],
142142
},
143143

144+
// resolverConfig
145+
{
146+
filename: fixture("test.js"),
147+
code: "require('a');",
148+
options: [
149+
{
150+
resolverConfig: {
151+
modules: [fixture("./")],
152+
},
153+
},
154+
],
155+
},
156+
157+
{
158+
filename: fixture("test.js"),
159+
code: "require('my-module');",
160+
options: [
161+
{
162+
resolverConfig: {
163+
modules: [fixture("my_modules")],
164+
},
165+
},
166+
],
167+
},
168+
144169
// Ignores it if not callee.
145170
{
146171
filename: fixture("test.js"),

0 commit comments

Comments
 (0)
Please sign in to comment.