-
-
Notifications
You must be signed in to change notification settings - Fork 743
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Stop using module.createRequire (problematic under webpack), incorpor…
…ate and export resolveModule helper from markdownlint-cli2.
- Loading branch information
1 parent
a6cc4cc
commit 1461764
Showing
16 changed files
with
327 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// @ts-check | ||
|
||
"use strict"; | ||
|
||
/** | ||
* Calls require for markdownit.cjs. Used to synchronously defer loading because module.createRequire is buggy under webpack (https://github.com/webpack/webpack/issues/16724). | ||
* | ||
* @returns {any} Exported module content. | ||
*/ | ||
function requireMarkdownItCjs() { | ||
return require("./markdownit.cjs"); | ||
} | ||
|
||
module.exports = { | ||
requireMarkdownItCjs | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// @ts-check | ||
|
||
"use strict"; | ||
|
||
// @ts-ignore | ||
// eslint-disable-next-line camelcase, no-inline-comments, no-undef | ||
const nativeRequire = (typeof __non_webpack_require__ === "undefined") ? require : /* c8 ignore next */ __non_webpack_require__; | ||
// Captures the native require implementation (even under webpack). | ||
|
||
/** | ||
* @typedef RequireResolveOptions | ||
* @property {string[]} [paths] Additional paths to resolve from. | ||
*/ | ||
|
||
/** | ||
* @callback RequireResolve | ||
* @param {string} id Module name or path. | ||
* @param {RequireResolveOptions} options Options to apply. | ||
* @returns {string} Resolved module path. | ||
*/ | ||
|
||
/** | ||
* Resolves modules according to Node's resolution rules. | ||
* | ||
* @param {RequireResolve} resolve Node-like require.resolve implementation. | ||
* @param {string} id Module name or path. | ||
* @param {string[]} [paths] Additional paths to resolve from. | ||
* @returns {string} Resolved module path. | ||
*/ | ||
const resolveModuleCustomResolve = (resolve, id, paths = []) => { | ||
// resolve.paths is sometimes not present under webpack or VS Code | ||
// @ts-ignore | ||
const resolvePaths = resolve.paths?.("") || []; | ||
const allPaths = [ ...paths, ...resolvePaths ]; | ||
return resolve(id, { "paths": allPaths }); | ||
}; | ||
|
||
/** | ||
* Resolves modules according to Node's resolution rules. | ||
* | ||
* @param {string} id Module name or path. | ||
* @param {string[]} [paths] Additional paths to resolve from. | ||
* @returns {string} Resolved module path. | ||
*/ | ||
const resolveModule = (id, paths) => ( | ||
resolveModuleCustomResolve(nativeRequire.resolve, id, paths) | ||
); | ||
|
||
module.exports = { | ||
resolveModule, | ||
resolveModuleCustomResolve | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
export type RequireResolveOptions = { | ||
/** | ||
* Additional paths to resolve from. | ||
*/ | ||
paths?: string[]; | ||
}; | ||
export type RequireResolve = (id: string, options: RequireResolveOptions) => string; | ||
/** | ||
* Resolves modules according to Node's resolution rules. | ||
* | ||
* @param {string} id Module name or path. | ||
* @param {string[]} [paths] Additional paths to resolve from. | ||
* @returns {string} Resolved module path. | ||
*/ | ||
export function resolveModule(id: string, paths?: string[]): string; | ||
/** | ||
* @typedef RequireResolveOptions | ||
* @property {string[]} [paths] Additional paths to resolve from. | ||
*/ | ||
/** | ||
* @callback RequireResolve | ||
* @param {string} id Module name or path. | ||
* @param {RequireResolveOptions} options Options to apply. | ||
* @returns {string} Resolved module path. | ||
*/ | ||
/** | ||
* Resolves modules according to Node's resolution rules. | ||
* | ||
* @param {RequireResolve} resolve Node-like require.resolve implementation. | ||
* @param {string} id Module name or path. | ||
* @param {string[]} [paths] Additional paths to resolve from. | ||
* @returns {string} Resolved module path. | ||
*/ | ||
export function resolveModuleCustomResolve(resolve: RequireResolve, id: string, paths?: string[]): string; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
// @ts-check | ||
|
||
import test from "ava"; | ||
import path from "node:path"; | ||
import { __dirname as getDirname } from "./esm-helpers.mjs"; | ||
import { resolveModule, resolveModuleCustomResolve } from "../lib/resolve-module.cjs"; | ||
|
||
import { createRequire } from "node:module"; | ||
const require = createRequire(import.meta.url); | ||
// eslint-disable-next-line no-underscore-dangle | ||
const __dirname = getDirname(import.meta); | ||
|
||
test("built-in module", (t) => { | ||
t.plan(1); | ||
t.deepEqual( | ||
resolveModule("node:fs"), | ||
require.resolve("node:fs") | ||
); | ||
}); | ||
|
||
test("locally-installed module", (t) => { | ||
t.plan(1); | ||
t.deepEqual( | ||
resolveModule("micromark"), | ||
require.resolve("micromark") | ||
); | ||
}); | ||
|
||
test("absolute path to module", (t) => { | ||
t.plan(1); | ||
const absolute = | ||
path.resolve( | ||
__dirname, | ||
"./rules/node_modules/markdownlint-rule-sample-commonjs" | ||
); | ||
t.deepEqual( | ||
resolveModule(absolute), | ||
require.resolve(absolute) | ||
); | ||
}); | ||
|
||
test("relative (to __dirname) path to module", (t) => { | ||
t.plan(1); | ||
t.deepEqual( | ||
resolveModule( | ||
"./rules/node_modules/markdownlint-rule-sample-module", | ||
// __dirname is needed because require.resolve is relative to this | ||
// file while resolveModule is relative to resolve-module.cjs | ||
[ __dirname ] | ||
), | ||
require.resolve( | ||
"./rules/node_modules/markdownlint-rule-sample-module" | ||
) | ||
); | ||
}); | ||
|
||
test("module in alternate node_modules", (t) => { | ||
t.plan(3); | ||
t.throws( | ||
() => require.resolve("markdownlint-rule-sample-commonjs"), | ||
{ "code": "MODULE_NOT_FOUND" } | ||
); | ||
t.throws( | ||
() => resolveModule("markdownlint-rule-sample-commonjs"), | ||
{ "code": "MODULE_NOT_FOUND" } | ||
); | ||
t.deepEqual( | ||
resolveModule( | ||
"markdownlint-rule-sample-commonjs", | ||
[ path.join(__dirname, "rules") ] | ||
), | ||
require.resolve( | ||
"markdownlint-rule-sample-commonjs", | ||
{ "paths": [ path.join(__dirname, "rules") ] } | ||
) | ||
); | ||
}); | ||
|
||
test("module local, relative, and in alternate node_modules (same paths)", (t) => { | ||
t.plan(3); | ||
const paths = [ | ||
__dirname, | ||
path.join(__dirname, "rules") | ||
]; | ||
t.deepEqual( | ||
resolveModule( | ||
"micromark", | ||
paths | ||
), | ||
require.resolve( | ||
"micromark", | ||
{ paths } | ||
) | ||
); | ||
t.deepEqual( | ||
resolveModule( | ||
"./rules/node_modules/markdownlint-rule-sample-commonjs", | ||
paths | ||
), | ||
require.resolve( | ||
"./rules/node_modules/markdownlint-rule-sample-commonjs", | ||
{ paths } | ||
) | ||
); | ||
t.deepEqual( | ||
resolveModule( | ||
"markdownlint-rule-sample-commonjs", | ||
paths | ||
), | ||
require.resolve( | ||
"markdownlint-rule-sample-commonjs", | ||
{ paths } | ||
) | ||
); | ||
}); | ||
|
||
test("custom resolve implementation", (t) => { | ||
t.plan(1); | ||
const expected = | ||
require.resolve("./rules/node_modules/markdownlint-rule-sample-module"); | ||
const customResolve = (id, options) => require.resolve(id, options); | ||
customResolve.paths = (request) => require.resolve.paths(request); | ||
t.deepEqual( | ||
resolveModuleCustomResolve( | ||
customResolve, | ||
"./rules/node_modules/markdownlint-rule-sample-module", | ||
[ __dirname ] | ||
), | ||
expected | ||
); | ||
}); | ||
|
||
test("custom resolve implementation, missing paths", (t) => { | ||
t.plan(1); | ||
const expected = | ||
require.resolve("./rules/node_modules/markdownlint-rule-sample-commonjs"); | ||
const customResolve = (id, options) => require.resolve(id, options); | ||
t.deepEqual( | ||
resolveModuleCustomResolve( | ||
// @ts-ignore | ||
customResolve, | ||
"./rules/node_modules/markdownlint-rule-sample-commonjs", | ||
[ __dirname ] | ||
), | ||
expected | ||
); | ||
}); |
14 changes: 14 additions & 0 deletions
14
test/rules/node_modules/markdownlint-rule-sample-commonjs/package.json
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.