mirror of https://github.com/webpack/webpack.git
test: add test case for circular dependency with externals (#19623)
Github Actions / lint (push) Waiting to run
Details
Github Actions / validate-legacy-node (push) Waiting to run
Details
Github Actions / benchmark (1/4) (push) Waiting to run
Details
Github Actions / benchmark (2/4) (push) Waiting to run
Details
Github Actions / benchmark (3/4) (push) Waiting to run
Details
Github Actions / benchmark (4/4) (push) Waiting to run
Details
Github Actions / basic (push) Waiting to run
Details
Github Actions / unit (push) Waiting to run
Details
Github Actions / integration (10.x, macos-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (10.x, macos-latest, b) (push) Blocked by required conditions
Details
Github Actions / integration (10.x, ubuntu-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (10.x, ubuntu-latest, b) (push) Blocked by required conditions
Details
Github Actions / integration (10.x, windows-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (10.x, windows-latest, b) (push) Blocked by required conditions
Details
Github Actions / integration (12.x, ubuntu-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (14.x, ubuntu-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (16.x, ubuntu-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (18.x, ubuntu-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (20.x, macos-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (20.x, macos-latest, b) (push) Blocked by required conditions
Details
Github Actions / integration (20.x, ubuntu-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (20.x, ubuntu-latest, b) (push) Blocked by required conditions
Details
Github Actions / integration (20.x, windows-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (20.x, windows-latest, b) (push) Blocked by required conditions
Details
Github Actions / integration (22.x, macos-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (22.x, macos-latest, b) (push) Blocked by required conditions
Details
Github Actions / integration (22.x, ubuntu-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (22.x, ubuntu-latest, b) (push) Blocked by required conditions
Details
Github Actions / integration (22.x, windows-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (22.x, windows-latest, b) (push) Blocked by required conditions
Details
Github Actions / integration (24.x, macos-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (24.x, macos-latest, b) (push) Blocked by required conditions
Details
Github Actions / integration (24.x, ubuntu-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (24.x, ubuntu-latest, b) (push) Blocked by required conditions
Details
Github Actions / integration (24.x, windows-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (24.x, windows-latest, b) (push) Blocked by required conditions
Details
Github Actions / integration (lts/*, ubuntu-latest, a, 1) (push) Blocked by required conditions
Details
Github Actions / integration (lts/*, ubuntu-latest, b, 1) (push) Blocked by required conditions
Details
Github Actions / lint (push) Waiting to run
Details
Github Actions / validate-legacy-node (push) Waiting to run
Details
Github Actions / benchmark (1/4) (push) Waiting to run
Details
Github Actions / benchmark (2/4) (push) Waiting to run
Details
Github Actions / benchmark (3/4) (push) Waiting to run
Details
Github Actions / benchmark (4/4) (push) Waiting to run
Details
Github Actions / basic (push) Waiting to run
Details
Github Actions / unit (push) Waiting to run
Details
Github Actions / integration (10.x, macos-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (10.x, macos-latest, b) (push) Blocked by required conditions
Details
Github Actions / integration (10.x, ubuntu-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (10.x, ubuntu-latest, b) (push) Blocked by required conditions
Details
Github Actions / integration (10.x, windows-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (10.x, windows-latest, b) (push) Blocked by required conditions
Details
Github Actions / integration (12.x, ubuntu-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (14.x, ubuntu-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (16.x, ubuntu-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (18.x, ubuntu-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (20.x, macos-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (20.x, macos-latest, b) (push) Blocked by required conditions
Details
Github Actions / integration (20.x, ubuntu-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (20.x, ubuntu-latest, b) (push) Blocked by required conditions
Details
Github Actions / integration (20.x, windows-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (20.x, windows-latest, b) (push) Blocked by required conditions
Details
Github Actions / integration (22.x, macos-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (22.x, macos-latest, b) (push) Blocked by required conditions
Details
Github Actions / integration (22.x, ubuntu-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (22.x, ubuntu-latest, b) (push) Blocked by required conditions
Details
Github Actions / integration (22.x, windows-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (22.x, windows-latest, b) (push) Blocked by required conditions
Details
Github Actions / integration (24.x, macos-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (24.x, macos-latest, b) (push) Blocked by required conditions
Details
Github Actions / integration (24.x, ubuntu-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (24.x, ubuntu-latest, b) (push) Blocked by required conditions
Details
Github Actions / integration (24.x, windows-latest, a) (push) Blocked by required conditions
Details
Github Actions / integration (24.x, windows-latest, b) (push) Blocked by required conditions
Details
Github Actions / integration (lts/*, ubuntu-latest, a, 1) (push) Blocked by required conditions
Details
Github Actions / integration (lts/*, ubuntu-latest, b, 1) (push) Blocked by required conditions
Details
This commit is contained in:
parent
21b28a82f7
commit
10fb5566e7
|
@ -0,0 +1,10 @@
|
||||||
|
import { externalValue as valueB, getOtherExternal as getB } from "./external-b.mjs";
|
||||||
|
|
||||||
|
export const externalValue = "external-A";
|
||||||
|
|
||||||
|
export function getOtherExternal() {
|
||||||
|
return valueB;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-export to test circular re-exports
|
||||||
|
export { getB as getOtherValue };
|
|
@ -0,0 +1,10 @@
|
||||||
|
import { externalValue as valueA, getOtherExternal as getA } from "./external-a.mjs";
|
||||||
|
|
||||||
|
export const externalValue = "external-B";
|
||||||
|
|
||||||
|
export function getOtherExternal() {
|
||||||
|
return valueA;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-export to test circular re-exports
|
||||||
|
export { getA as getOtherValue };
|
|
@ -0,0 +1,51 @@
|
||||||
|
import { valueA, getFromExternalA, callB } from "./module-a.js";
|
||||||
|
import { valueB, getFromExternalB, callA } from "./module-b.js";
|
||||||
|
import { externalValue as directExternalA } from "external-module-a";
|
||||||
|
import { externalValue as directExternalB } from "external-module-b";
|
||||||
|
|
||||||
|
it("should handle circular dependencies between internal modules", () => {
|
||||||
|
expect(valueA).toBe("module-A");
|
||||||
|
expect(valueB).toBe("module-B");
|
||||||
|
expect(callB()).toBe("module-B");
|
||||||
|
expect(callA()).toBe("module-A");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle imports from external modules", () => {
|
||||||
|
expect(getFromExternalA()).toBe("external-A");
|
||||||
|
expect(getFromExternalB()).toBe("external-B");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle direct imports from external modules", () => {
|
||||||
|
expect(directExternalA).toBe("external-A");
|
||||||
|
expect(directExternalB).toBe("external-B");
|
||||||
|
});
|
||||||
|
|
||||||
|
// ESM external modules with circular dependencies
|
||||||
|
it("should maintain live bindings for ESM external modules", async () => {
|
||||||
|
// Import external modules that have circular dependencies
|
||||||
|
const moduleA = await import("external-module-a");
|
||||||
|
const moduleB = await import("external-module-b");
|
||||||
|
|
||||||
|
// Verify that circular dependencies are resolved correctly
|
||||||
|
expect(moduleA.externalValue).toBe("external-A");
|
||||||
|
expect(moduleB.externalValue).toBe("external-B");
|
||||||
|
|
||||||
|
// Verify that re-exports work correctly in circular scenarios
|
||||||
|
expect(moduleA.getOtherValue).toBeDefined();
|
||||||
|
expect(moduleB.getOtherValue).toBeDefined();
|
||||||
|
|
||||||
|
// Test that the modules maintain their identity (live bindings)
|
||||||
|
expect(await import("external-module-a")).toBe(moduleA);
|
||||||
|
expect(await import("external-module-b")).toBe(moduleB);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Edge case: Multiple imports of the same external module
|
||||||
|
it("should handle multiple imports of circular external modules", () => {
|
||||||
|
// This tests that the runtime module correctly caches external modules
|
||||||
|
const firstImportA = directExternalA;
|
||||||
|
const secondImportA = getFromExternalA();
|
||||||
|
|
||||||
|
// Both should reference the same value
|
||||||
|
expect(firstImportA).toBe(secondImportA);
|
||||||
|
expect(firstImportA).toBe("external-A");
|
||||||
|
});
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { valueB } from "./module-b.js";
|
||||||
|
import { externalValue } from "external-module-a";
|
||||||
|
|
||||||
|
export const valueA = "module-A";
|
||||||
|
|
||||||
|
export function getFromExternalA() {
|
||||||
|
return externalValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function callB() {
|
||||||
|
return valueB;
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { valueA } from "./module-a.js";
|
||||||
|
import { externalValue } from "external-module-b";
|
||||||
|
|
||||||
|
export const valueB = "module-B";
|
||||||
|
|
||||||
|
export function getFromExternalB() {
|
||||||
|
return externalValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function callA() {
|
||||||
|
return valueA;
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
module.exports = {
|
||||||
|
findBundle() {
|
||||||
|
return "./main.mjs";
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,65 @@
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
/** @type {import("../../../../types").Configuration} */
|
||||||
|
module.exports = {
|
||||||
|
entry: "./index.js",
|
||||||
|
experiments: {
|
||||||
|
outputModule: true
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
module: true,
|
||||||
|
library: {
|
||||||
|
type: "module"
|
||||||
|
},
|
||||||
|
filename: "[name].mjs",
|
||||||
|
chunkFormat: "module"
|
||||||
|
},
|
||||||
|
externals: {
|
||||||
|
"external-module-a": "module ./external-a.mjs",
|
||||||
|
"external-module-b": "module ./external-b.mjs"
|
||||||
|
},
|
||||||
|
externalsType: "module",
|
||||||
|
optimization: {
|
||||||
|
concatenateModules: false
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
{
|
||||||
|
apply(compiler) {
|
||||||
|
compiler.hooks.thisCompilation.tap(
|
||||||
|
"copy-external-files",
|
||||||
|
compilation => {
|
||||||
|
compilation.hooks.processAssets.tap(
|
||||||
|
{
|
||||||
|
name: "copy-external-files",
|
||||||
|
stage:
|
||||||
|
compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
// Read the external module files
|
||||||
|
const externalA = fs.readFileSync(
|
||||||
|
path.join(__dirname, "external-a.mjs"),
|
||||||
|
"utf-8"
|
||||||
|
);
|
||||||
|
const externalB = fs.readFileSync(
|
||||||
|
path.join(__dirname, "external-b.mjs"),
|
||||||
|
"utf-8"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Emit them as assets
|
||||||
|
compilation.emitAsset(
|
||||||
|
"external-a.mjs",
|
||||||
|
new compiler.webpack.sources.RawSource(externalA)
|
||||||
|
);
|
||||||
|
compilation.emitAsset(
|
||||||
|
"external-b.mjs",
|
||||||
|
new compiler.webpack.sources.RawSource(externalB)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
Loading…
Reference in New Issue