mirror of https://github.com/webpack/webpack.git
Merge dd4769b5ff
into 9f98d803c0
This commit is contained in:
commit
79d8aa507f
|
@ -133,7 +133,20 @@ class SystemLibraryPlugin extends AbstractLibraryPlugin {
|
||||||
chunk.runtime
|
chunk.runtime
|
||||||
);
|
);
|
||||||
if (used) {
|
if (used) {
|
||||||
if (otherUnused || used !== exportInfo.name) {
|
if (used === "default" && exportInfo.name === "default") {
|
||||||
|
instructions.push(
|
||||||
|
Template.asString([
|
||||||
|
"if (typeof module.default !== 'undefined') {",
|
||||||
|
Template.indent([
|
||||||
|
`${external}.default = module.default;`
|
||||||
|
]),
|
||||||
|
"} else {",
|
||||||
|
Template.indent([`${external} = module;`]),
|
||||||
|
"}"
|
||||||
|
])
|
||||||
|
);
|
||||||
|
handledNames.push(exportInfo.name);
|
||||||
|
} else if (otherUnused || used !== exportInfo.name) {
|
||||||
instructions.push(
|
instructions.push(
|
||||||
`${external}${propertyAccess([
|
`${external}${propertyAccess([
|
||||||
used
|
used
|
||||||
|
@ -172,9 +185,24 @@ class SystemLibraryPlugin extends AbstractLibraryPlugin {
|
||||||
} else {
|
} else {
|
||||||
instructions.push(
|
instructions.push(
|
||||||
Template.asString([
|
Template.asString([
|
||||||
"Object.keys(module).forEach(function(key) {",
|
"if (typeof module.default !== 'undefined') {",
|
||||||
Template.indent([`${external}[key] = module[key];`]),
|
Template.indent([
|
||||||
"});"
|
"Object.keys(module).forEach(function(key) {",
|
||||||
|
Template.indent([
|
||||||
|
`${external}[key] = module[key];`
|
||||||
|
]),
|
||||||
|
"});"
|
||||||
|
]),
|
||||||
|
"} else {",
|
||||||
|
Template.indent([
|
||||||
|
`${external} = module;`,
|
||||||
|
"Object.keys(module).forEach(function(key) {",
|
||||||
|
Template.indent([
|
||||||
|
`${external}[key] = module[key];`
|
||||||
|
]),
|
||||||
|
"});"
|
||||||
|
]),
|
||||||
|
"}"
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
import React, { useEffect } from "react";
|
||||||
|
|
||||||
|
/* This test verifies that default imports work correctly with SystemJS externals
|
||||||
|
* when the external module doesn't have a default property (e.g., React)
|
||||||
|
*/
|
||||||
|
|
||||||
|
it("should correctly handle default import from SystemJS external", function() {
|
||||||
|
// React should be the entire module object, not undefined
|
||||||
|
expect(React).toBeDefined();
|
||||||
|
expect(typeof React).toBe("object");
|
||||||
|
expect(React.Component).toBeDefined();
|
||||||
|
expect(React.Fragment).toBeDefined();
|
||||||
|
|
||||||
|
// Named imports should still work
|
||||||
|
expect(typeof useEffect).toBe("function");
|
||||||
|
|
||||||
|
// The default import should not be undefined
|
||||||
|
expect(React).not.toBeUndefined();
|
||||||
|
});
|
|
@ -0,0 +1,26 @@
|
||||||
|
// Mock React module that HAS a default property
|
||||||
|
// This simulates ES6 modules with default exports
|
||||||
|
const React = {
|
||||||
|
Component: function Component() {},
|
||||||
|
Fragment: Symbol("react.fragment"),
|
||||||
|
Profiler: Symbol("react.profiler"),
|
||||||
|
useEffect: function useEffect(callback, deps) {
|
||||||
|
return callback();
|
||||||
|
},
|
||||||
|
useState: function useState(initial) {
|
||||||
|
return [initial, function() {}];
|
||||||
|
},
|
||||||
|
createElement: function createElement(type, props, ...children) {
|
||||||
|
return { type, props, children };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Export with default property (ES6 module format)
|
||||||
|
module.exports = React;
|
||||||
|
module.exports.default = React;
|
||||||
|
module.exports.useEffect = React.useEffect;
|
||||||
|
module.exports.Component = React.Component;
|
||||||
|
module.exports.Fragment = React.Fragment;
|
||||||
|
module.exports.Profiler = React.Profiler;
|
||||||
|
module.exports.useState = React.useState;
|
||||||
|
module.exports.createElement = React.createElement;
|
|
@ -0,0 +1,25 @@
|
||||||
|
// Mock React module that doesn't have a default property
|
||||||
|
// This simulates how React is typically exported in SystemJS environments
|
||||||
|
const React = {
|
||||||
|
Component: function Component() {},
|
||||||
|
Fragment: Symbol("react.fragment"),
|
||||||
|
Profiler: Symbol("react.profiler"),
|
||||||
|
useEffect: function useEffect(callback, deps) {
|
||||||
|
return callback();
|
||||||
|
},
|
||||||
|
useState: function useState(initial) {
|
||||||
|
return [initial, function() {}];
|
||||||
|
},
|
||||||
|
createElement: function createElement(type, props, ...children) {
|
||||||
|
return { type, props, children };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Export named exports (SystemJS style - no default property)
|
||||||
|
module.exports = React;
|
||||||
|
module.exports.useEffect = React.useEffect;
|
||||||
|
module.exports.Component = React.Component;
|
||||||
|
module.exports.Fragment = React.Fragment;
|
||||||
|
module.exports.Profiler = React.Profiler;
|
||||||
|
module.exports.useState = React.useState;
|
||||||
|
module.exports.createElement = React.createElement;
|
|
@ -0,0 +1,27 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
/** @type {import("../../../../").Configuration} */
|
||||||
|
module.exports = {
|
||||||
|
entry: "./test.js",
|
||||||
|
output: {
|
||||||
|
path: path.resolve(__dirname, "dist"),
|
||||||
|
filename: "bundle.js",
|
||||||
|
libraryTarget: "system"
|
||||||
|
},
|
||||||
|
externals: {
|
||||||
|
react: "react",
|
||||||
|
"react-with-default": "react-with-default"
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
react: path.resolve(__dirname, "react.js"),
|
||||||
|
"react-with-default": path.resolve(__dirname, "react-with-default.js")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
node: {
|
||||||
|
__dirname: false,
|
||||||
|
__filename: false
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,36 @@
|
||||||
|
import React, { useEffect } from "react";
|
||||||
|
import ReactWithDefault, { useEffect as useEffectWithDefault } from "react-with-default";
|
||||||
|
|
||||||
|
/* This test verifies that default imports work correctly with SystemJS externals
|
||||||
|
* in both scenarios:
|
||||||
|
* 1. External module without default property (traditional SystemJS)
|
||||||
|
* 2. External module with default property (ES6 module format)
|
||||||
|
*/
|
||||||
|
|
||||||
|
it("should correctly handle default import from SystemJS external without default property", function() {
|
||||||
|
// React should be the entire module object, not undefined
|
||||||
|
expect(React).toBeDefined();
|
||||||
|
expect(typeof React).toBe("object");
|
||||||
|
expect(React.Component).toBeDefined();
|
||||||
|
expect(React.Fragment).toBeDefined();
|
||||||
|
|
||||||
|
// Named imports should still work
|
||||||
|
expect(typeof useEffect).toBe("function");
|
||||||
|
|
||||||
|
// The default import should not be undefined
|
||||||
|
expect(React).not.toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should correctly handle default import from SystemJS external with default property", function() {
|
||||||
|
// ReactWithDefault should be the default property value
|
||||||
|
expect(ReactWithDefault).toBeDefined();
|
||||||
|
expect(typeof ReactWithDefault).toBe("object");
|
||||||
|
expect(ReactWithDefault.Component).toBeDefined();
|
||||||
|
expect(ReactWithDefault.Fragment).toBeDefined();
|
||||||
|
|
||||||
|
// Named imports should still work
|
||||||
|
expect(typeof useEffectWithDefault).toBe("function");
|
||||||
|
|
||||||
|
// The default import should not be undefined
|
||||||
|
expect(ReactWithDefault).not.toBeUndefined();
|
||||||
|
});
|
|
@ -0,0 +1,15 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/** @type {import("../../../../").Configuration} */
|
||||||
|
module.exports = {
|
||||||
|
output: {
|
||||||
|
libraryTarget: "system"
|
||||||
|
},
|
||||||
|
externals: {
|
||||||
|
react: "react"
|
||||||
|
},
|
||||||
|
node: {
|
||||||
|
__dirname: false,
|
||||||
|
__filename: false
|
||||||
|
}
|
||||||
|
};
|
Loading…
Reference in New Issue