Skip to content

Commit

Permalink
feat(resolve): allow overriding enhanced-resolve's options (#384)
Browse files Browse the repository at this point in the history
  • Loading branch information
GertSallaerts authored Dec 10, 2024
1 parent af4f774 commit 1466bec
Show file tree
Hide file tree
Showing 20 changed files with 153 additions and 2 deletions.
5 changes: 5 additions & 0 deletions docs/rules/no-extraneous-import.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ Please see the shared settings documentation for more information.
This can be configured in the rule options or as a shared setting [`settings.resolvePaths`](../shared-settings.md#resolvepaths).
Please see the shared settings documentation for more information.

#### resolverConfig

This can be configured in the rule options or as a shared setting [`settings.resolverConfig`](../shared-settings.md#resolverconfig).
Please see the shared settings documentation for more information.

#### convertPath

This can be configured in the rule options or as a shared setting [`settings.convertPath`](../shared-settings.md#convertpath).
Expand Down
5 changes: 5 additions & 0 deletions docs/rules/no-extraneous-require.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ Please see the shared settings documentation for more information.
This can be configured in the rule options or as a shared setting [`settings.resolvePaths`](../shared-settings.md#resolvepaths).
Please see the shared settings documentation for more information.

#### resolverConfig

This can be configured in the rule options or as a shared setting [`settings.resolverConfig`](../shared-settings.md#resolverconfig).
Please see the shared settings documentation for more information.

#### convertPath

This can be configured in the rule options or as a shared setting [`settings.convertPath`](../shared-settings.md#convertpath).
Expand Down
5 changes: 5 additions & 0 deletions docs/rules/no-missing-import.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ Please see the shared settings documentation for more information.
This can be configured in the rule options or as a shared setting [`settings.resolvePaths`](../shared-settings.md#resolvepaths).
Please see the shared settings documentation for more information.

#### resolverConfig

This can be configured in the rule options or as a shared setting [`settings.resolverConfig`](../shared-settings.md#resolverconfig).
Please see the shared settings documentation for more information.

#### tsconfigPath

This can be configured in the rule options or as a shared setting [`settings.tsconfigPath`](../shared-settings.md#tsconfigpath).
Expand Down
5 changes: 5 additions & 0 deletions docs/rules/no-missing-require.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ Please see the shared settings documentation for more information.
This can be configured in the rule options or as a shared setting [`settings.resolvePaths`](../shared-settings.md#resolvepaths).
Please see the shared settings documentation for more information.

#### resolverConfig

This can be configured in the rule options or as a shared setting [`settings.resolverConfig`](../shared-settings.md#resolverconfig).
Please see the shared settings documentation for more information.

#### tryExtensions

This can be configured in the rule options or as a shared setting [`settings.tryExtensions`](../shared-settings.md#tryextensions).
Expand Down
5 changes: 5 additions & 0 deletions docs/rules/no-unpublished-import.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ Please see the shared settings documentation for more information.
This can be configured in the rule options or as a shared setting [`settings.resolvePaths`](../shared-settings.md#resolvepaths).
Please see the shared settings documentation for more information.

#### resolverConfig

This can be configured in the rule options or as a shared setting [`settings.resolverConfig`](../shared-settings.md#resolverconfig).
Please see the shared settings documentation for more information.

#### convertPath

This can be configured in the rule options or as a shared setting [`settings.convertPath`](../shared-settings.md#convertpath).
Expand Down
5 changes: 5 additions & 0 deletions docs/rules/no-unpublished-require.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ Please see the shared settings documentation for more information.
This can be configured in the rule options or as a shared setting [`settings.resolvePaths`](../shared-settings.md#resolvepaths).
Please see the shared settings documentation for more information.

#### resolverConfig

This can be configured in the rule options or as a shared setting [`settings.resolverConfig`](../shared-settings.md#resolverconfig).
Please see the shared settings documentation for more information.

#### convertPath

This can be configured in the rule options or as a shared setting [`settings.convertPath`](../shared-settings.md#convertpath).
Expand Down
24 changes: 24 additions & 0 deletions docs/shared-settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,30 @@ If a path is relative, it will be resolved from CWD.
{ "resolvePaths": [] }
```

## resolverConfig

Override the options generated by this plugin for resolving require and import statements.

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.

The options you define here are assigned over the default options generated by the plugin.

Supported options:

- `resolverConfig.modules`: A list of directories to resolve modules from, can be absolute path or folder name

### Example resolverConfig

```json
{ "resolverConfig": { "modules": ["node_modules", "bower_components"] } }
```

### Default resolverConfig

```json
{ "resolverConfig": {} }
```

## convertPath

If we use transpilers (e.g. Babel), perhaps the file path to a source code is never published.
Expand Down
2 changes: 2 additions & 0 deletions lib/rules/no-extraneous-import.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const { checkExtraneous, messages } = require("../util/check-extraneous")
const getAllowModules = require("../util/get-allow-modules")
const getConvertPath = require("../util/get-convert-path")
const getResolvePaths = require("../util/get-resolve-paths")
const getResolverConfig = require("../util/get-resolver-config")
const visitImport = require("../util/visit-import")

/** @type {import('eslint').Rule.RuleModule} */
Expand All @@ -28,6 +29,7 @@ module.exports = {
allowModules: getAllowModules.schema,
convertPath: getConvertPath.schema,
resolvePaths: getResolvePaths.schema,
resolverConfig: getResolverConfig.schema,
},
additionalProperties: false,
},
Expand Down
2 changes: 2 additions & 0 deletions lib/rules/no-extraneous-require.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const { checkExtraneous, messages } = require("../util/check-extraneous")
const getAllowModules = require("../util/get-allow-modules")
const getConvertPath = require("../util/get-convert-path")
const getResolvePaths = require("../util/get-resolve-paths")
const getResolverConfig = require("../util/get-resolver-config")
const getTryExtensions = require("../util/get-try-extensions")
const visitRequire = require("../util/visit-require")

Expand All @@ -29,6 +30,7 @@ module.exports = {
allowModules: getAllowModules.schema,
convertPath: getConvertPath.schema,
resolvePaths: getResolvePaths.schema,
resolverConfig: getResolverConfig.schema,
tryExtensions: getTryExtensions.schema,
},
additionalProperties: false,
Expand Down
2 changes: 2 additions & 0 deletions lib/rules/no-missing-import.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
const { checkExistence, messages } = require("../util/check-existence")
const getAllowModules = require("../util/get-allow-modules")
const getResolvePaths = require("../util/get-resolve-paths")
const getResolverConfig = require("../util/get-resolver-config")
const getTryExtensions = require("../util/get-try-extensions")
const getTSConfig = require("../util/get-tsconfig")
const getTypescriptExtensionMap = require("../util/get-typescript-extension-map")
Expand All @@ -29,6 +30,7 @@ module.exports = {
properties: {
allowModules: getAllowModules.schema,
resolvePaths: getResolvePaths.schema,
resolverConfig: getResolverConfig.schema,
tryExtensions: getTryExtensions.schema,
ignoreTypeImport: { type: "boolean", default: false },
tsconfigPath: getTSConfig.schema,
Expand Down
2 changes: 2 additions & 0 deletions lib/rules/no-missing-require.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
const { checkExistence, messages } = require("../util/check-existence")
const getAllowModules = require("../util/get-allow-modules")
const getResolvePaths = require("../util/get-resolve-paths")
const getResolverConfig = require("../util/get-resolver-config")
const getTSConfig = require("../util/get-tsconfig")
const getTryExtensions = require("../util/get-try-extensions")
const getTypescriptExtensionMap = require("../util/get-typescript-extension-map")
Expand All @@ -30,6 +31,7 @@ module.exports = {
allowModules: getAllowModules.schema,
tryExtensions: getTryExtensions.schema,
resolvePaths: getResolvePaths.schema,
resolverConfig: getResolverConfig.schema,
typescriptExtensionMap: getTypescriptExtensionMap.schema,
tsconfigPath: getTSConfig.schema,
},
Expand Down
2 changes: 2 additions & 0 deletions lib/rules/no-unpublished-import.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const { checkPublish, messages } = require("../util/check-publish")
const getAllowModules = require("../util/get-allow-modules")
const getConvertPath = require("../util/get-convert-path")
const getResolvePaths = require("../util/get-resolve-paths")
const getResolverConfig = require("../util/get-resolver-config")
const visitImport = require("../util/visit-import")

/** @type {import('eslint').Rule.RuleModule} */
Expand All @@ -28,6 +29,7 @@ module.exports = {
allowModules: getAllowModules.schema,
convertPath: getConvertPath.schema,
resolvePaths: getResolvePaths.schema,
resolverConfig: getResolverConfig.schema,
ignoreTypeImport: { type: "boolean", default: false },
ignorePrivate: { type: "boolean", default: true },
},
Expand Down
2 changes: 2 additions & 0 deletions lib/rules/no-unpublished-require.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const { checkPublish, messages } = require("../util/check-publish")
const getAllowModules = require("../util/get-allow-modules")
const getConvertPath = require("../util/get-convert-path")
const getResolvePaths = require("../util/get-resolve-paths")
const getResolverConfig = require("../util/get-resolver-config")
const getTryExtensions = require("../util/get-try-extensions")
const visitRequire = require("../util/visit-require")

Expand All @@ -29,6 +30,7 @@ module.exports = {
allowModules: getAllowModules.schema,
convertPath: getConvertPath.schema,
resolvePaths: getResolvePaths.schema,
resolverConfig: getResolverConfig.schema,
tryExtensions: getTryExtensions.schema,
ignorePrivate: { type: "boolean", default: true },
},
Expand Down
47 changes: 47 additions & 0 deletions lib/util/get-resolver-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* @author Toru Nagashima
* See LICENSE file in root directory for full license.
*/
"use strict"

/**
* @typedef {Partial<import('enhanced-resolve').ResolveOptions>} ResolverConfig
*/

/** @type {ResolverConfig} */
const DEFAULT_VALUE = {}

/**
* Gets `resolverConfig` property from a given option object.
*
* @param {{ resolverConfig: ResolverConfig } | undefined} option - An option object to get.
* @returns {ResolverConfig | undefined} The `allowModules` value, or `null`.
*/
function get(option) {
if (option?.resolverConfig) return option.resolverConfig
}

/**
* Gets "resolverConfig" setting.
*
* 1. This checks `options` property, then returns it if exists.
* 2. This checks `settings.n` | `settings.node` property, then returns it if exists.
* 3. This returns `[]`.
*
* @param {import('eslint').Rule.RuleContext} context - The rule context.
* @returns {ResolverConfig} A resolver config object.
*/
module.exports = function getResolverConfig(context, optionIndex = 0) {
return (
get(context.options?.[optionIndex]) ??
get(context.settings?.n) ??
get(context.settings?.node) ??
DEFAULT_VALUE
)
}

module.exports.schema = {
type: "object",
properties: {},
additionalProperties: true,
}
6 changes: 6 additions & 0 deletions lib/util/import-target.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ function getTSConfigAliases(context) {
* @typedef Options
* @property {string[]} [extensions]
* @property {string[]} [paths]
* @property {Partial<import('enhanced-resolve').ResolveOptions>} [resolverConfig]
* @property {string} basedir
*/
/** @typedef { 'unknown' | 'relative' | 'absolute' | 'node' | 'npm' | 'http' } ModuleType */
Expand Down Expand Up @@ -323,6 +324,11 @@ module.exports = class ImportTarget {
).backward
}

this.resolverConfig = {
...this.resolverConfig,
...this.options.resolverConfig,
}

const requireResolve = resolver.create.sync(this.resolverConfig)

const cwd = this.context.settings?.cwd ?? process.cwd()
Expand Down
4 changes: 3 additions & 1 deletion lib/util/visit-import.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
const path = require("path")
const { isBuiltin } = require("node:module")
const getResolvePaths = require("./get-resolve-paths")
const getResolverConfig = require("./get-resolver-config")
const getTryExtensions = require("./get-try-extensions")
const ImportTarget = require("./import-target")
const stripImportPathParams = require("./strip-import-path-params")
Expand Down Expand Up @@ -41,8 +42,9 @@ module.exports = function visitImport(
path.resolve(context.filename ?? context.getFilename())
)
const paths = getResolvePaths(context, optionIndex)
const resolverConfig = getResolverConfig(context, optionIndex)
const extensions = getTryExtensions(context, optionIndex)
const options = { basedir, paths, extensions }
const options = { basedir, paths, extensions, resolverConfig }

/**
* @param {(
Expand Down
4 changes: 3 additions & 1 deletion lib/util/visit-require.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const {
} = require("@eslint-community/eslint-utils")
const { isBuiltin } = require("node:module")
const getResolvePaths = require("./get-resolve-paths")
const getResolverConfig = require("./get-resolver-config")
const getTryExtensions = require("./get-try-extensions")
const ImportTarget = require("./import-target")
const stripImportPathParams = require("./strip-import-path-params")
Expand Down Expand Up @@ -42,8 +43,9 @@ module.exports = function visitRequire(
path.resolve(context.filename ?? context.getFilename())
)
const paths = getResolvePaths(context)
const resolverConfig = getResolverConfig(context)
const extensions = getTryExtensions(context)
const options = { basedir, paths, extensions }
const options = { basedir, paths, extensions, resolverConfig }

return {
"Program:exit"(node) {
Expand Down
Empty file.
3 changes: 3 additions & 0 deletions tests/fixtures/no-missing/my_modules/my-module/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"main": "./a-file.js"
}
25 changes: 25 additions & 0 deletions tests/lib/rules/no-missing-require.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,31 @@ ruleTester.run("no-missing-require", rule, {
options: [{ resolvePaths: ["tests"] }],
},

// resolverConfig
{
filename: fixture("test.js"),
code: "require('a');",
options: [
{
resolverConfig: {
modules: [fixture("./")],
},
},
],
},

{
filename: fixture("test.js"),
code: "require('my-module');",
options: [
{
resolverConfig: {
modules: [fixture("my_modules")],
},
},
],
},

// Ignores it if not callee.
{
filename: fixture("test.js"),
Expand Down

0 comments on commit 1466bec

Please sign in to comment.