Skip to content
This repository has been archived by the owner on Aug 13, 2022. It is now read-only.

Add user-specified conditions to ESM resolution #73

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 27 additions & 7 deletions lib/trace.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,9 @@ const _recurseDeps = async ({
bailOnMissing = true,
includeSourceMaps = false,
_extraImports,
_tracedDepPaths
_tracedDepPaths,
userConditions,
replaceConditions
}) => {
// Start **only** with depPaths.
let dependencies = Array.from(depPaths);
Expand Down Expand Up @@ -181,7 +183,9 @@ const _recurseDeps = async ({
bailOnMissing,
includeSourceMaps,
_extraImports,
_tracedDepPaths
_tracedDepPaths,
userConditions,
replaceConditions
});

// Aggregate.
Expand All @@ -208,6 +212,8 @@ const _resolveDep = async ({
addMisses,
allowMissing,
bailOnMissing,
userConditions,
replaceConditions,
addRootPackagePaths = false
}) => {
// Capture all package.json files encountered in node resolution.
Expand Down Expand Up @@ -298,7 +304,9 @@ const _resolveDep = async ({
}
});

CONDITIONS.forEach((cond) => {
const conditions = replaceConditions ? userConditions : CONDITIONS.concat(userConditions);

conditions.forEach((cond) => {
let resolveOpts;
if (Array.isArray(cond)) {
resolveOpts = cond[1];
Expand Down Expand Up @@ -452,6 +460,8 @@ const _resolveDep = async ({
* @param {Object} opts.extraImports map files to additional imports to trace
* @param {Object} opts._extraImports (internal) normalized map
* @param {Set} opts._tracedDepPaths (internal) tracked dependencies
* @param {Array<string>} opts.userConditions list of conditional exports https://nodejs.org/api/packages.html#packages_conditional_exports
* @param {boolean} opts.replaceConditions flag to replace conditions with userConditions
* @returns {Promise<Object>} dependencies and other information
*/
// eslint-disable-next-line max-statements,complexity
Expand All @@ -463,7 +473,9 @@ const traceFile = async ({
includeSourceMaps = false,
extraImports = {},
_extraImports,
_tracedDepPaths = new Set()
_tracedDepPaths = new Set(),
userConditions = [],
replaceConditions = false
} = {}) => {
if (!srcPath) {
throw new Error("Empty source file path");
Expand Down Expand Up @@ -553,7 +565,9 @@ const traceFile = async ({
extraDepKeys,
addMisses,
allowMissing,
bailOnMissing
bailOnMissing,
userConditions,
replaceConditions
})))
// Post-resolution processing.
.then((allPaths) => allPaths
Expand Down Expand Up @@ -614,6 +628,8 @@ const traceFile = async ({
* @param {Object} opts.extraImports map files to additional imports to trace
* @param {Object} opts._extraImports (internal) normalized map
* @param {Set} opts._tracedDepPaths (internal) tracked dependencies
* @param {Array<string>} opts.userConditions list of conditional exports https://nodejs.org/api/packages.html#packages_conditional_exports
* @param {boolean} opts.replaceConditions flag to replace conditions with userConditions
* @returns {Promise<Object>} dependencies and other information
*/
const traceFiles = async ({
Expand All @@ -624,7 +640,9 @@ const traceFiles = async ({
includeSourceMaps = false,
extraImports = {},
_extraImports,
_tracedDepPaths = new Set()
_tracedDepPaths = new Set(),
userConditions = [],
replaceConditions = false
} = {}) => {
_extraImports = _extraImports || normalizeExtraImports(extraImports);

Expand All @@ -636,7 +654,9 @@ const traceFiles = async ({
bailOnMissing,
includeSourceMaps,
_extraImports,
_tracedDepPaths
_tracedDepPaths,
userConditions,
replaceConditions
});

// Make unique and return.
Expand Down
105 changes: 105 additions & 0 deletions test/lib/trace.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2793,5 +2793,110 @@ describe("lib/trace", () => {
}
});
});

it("Replace conditions with supplied userConditions when tracing files", async () => {
mock({
"hi.js": `
const core = require("trace/core");
`,
node_modules: {
trace: {
"package.json": stringify({
name: "trace",
main: "index.cjs",
exports: {
".": {
require: "index.cjs"
},
"./core": {
lite: {
node: "./core-lite.cjs"
},
require: "./core.cjs"
}
}
}),
"index.cjs": `
const hello = () => {};
module.exports = hello;
`,
"core.cjs": `
const core = () => {};

module.exports = core;
`,
"core-lite.cjs": `
const coreLight = () => {};

module.exports = coreLight;
`
}
}
});

const { dependencies } = await traceFiles({
srcPaths: ["hi.js"],
userConditions: ["lite"],
replaceConditions: true
});

expect(dependencies).to.eql(fullPaths([
"node_modules/trace/core-lite.cjs",
"node_modules/trace/package.json"
]));
});

it("Append supplied userConditions to conditions when tracing files", async () => {
mock({
"hi.js": `
const core = require("trace/core");
`,
node_modules: {
trace: {
"package.json": stringify({
name: "trace",
main: "index.cjs",
exports: {
".": {
require: "index.cjs"
},
"./core": {
lite: {
node: "./core-lite.cjs"
},
require: "./core.cjs"
}
}
}),
"index.cjs": `
const hello = () => {};
module.exports = hello;
`,
"core.cjs": `
const core = () => {};

module.exports = core;
`,
"core-lite.cjs": `
const coreLight = () => {};

module.exports = coreLight;
`
}
}
});

const { dependencies } = await traceFiles({
srcPaths: ["hi.js"],
userConditions: ["lite"],
replaceConditions: false
});

expect(dependencies).to.eql(fullPaths([
"node_modules/trace/core-lite.cjs",
"node_modules/trace/core.cjs",
"node_modules/trace/package.json"
]));
});
});
});