System.import returns empty module
See original GitHub issue- SystemJS Version: 6.11.0
- Which library are you using?
- system.js
- s.js
- system-node.cjs
- Which extras are you using?
- AMD extra
- Named Exports
- Named Register
- Transform
- Use Default
- Global
- Dynamic Import Maps
- Are you using any custom hooks?
Question
This might be a bug, but I think I will need help debugging before I’d be able to produce a minimum reproduction.
Summary
When providing an import map override for a module using module federation and being served with webpack-dev-server, System.import(thatModule)
always resolves to an empty object. This module has the same webpack configuration as other modules, which don’t have the same problem.
Details
I have an application using import-map-overrides. Using it, I create a new systemjs-importmap
entry to add @openmrs/esm-patient-chart-app (and @openmrs/esm-login-app just for comparison) running from webpack-dev-servers.
<script type="systemjs-importmap" id="import-map-overrides" data-is-importmap-override="">{
"imports": {
"@openmrs/esm-patient-chart-app": "//localhost:8081/openmrs-esm-patient-chart-app.js",
"@openmrs/esm-login-app": "//localhost:8082/openmrs-esm-login-app.js"
},
"scopes": {}
}</script>
both modules use the same webpack configuration, which is using webpack module federation. Some key points of the webpack config, I think, include:
entry: {
[name]: "systemjs-webpack-interop/auto-public-path",
},
output: {
libraryTarget: "system",
publicPath: "",
path: resolve(root, outDir),
},
plugins: [
new ModuleFederationPlugin({
name,
library: { type: "system", name },
filename,
exposes: {
app: srcFile,
},
shared: Object.keys(peerDependencies).reduce((obj, depName) => {
obj[depName] = {
requiredVersion: peerDependencies[depName],
singleton: true,
import: depName,
shareKey: depName,
shareScope: "default",
};
return obj;
}, {}),
}),
The JS returned at //localhost:8081/openmrs-esm-patient-chart-app.js
and //localhost:8082/openmrs-esm-login-app.js
is approximately the same, and are here:
openmrs-esm-patient-chart-app.js.txt openmrs-esm-login-app.js.txt
Both start with
System.register("@openmrs/esm-patient-chart-app", [], function(__WEBPACK_DYNAMIC_EXPORT__, __system_context__) {
and eventually have something like
/*!***********************!*\
!*** container entry ***!
\***********************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
var moduleMap = { ... };
var get = (module, getScope) => { ... };
var init = (shareScope, initScope) => { ... };
// This exports getters to disallow modifications
__webpack_require__.d(exports, {
get: () => (get),
init: () => (init)
});
Where get
and init
are familiar to me as the functions that I expect to be present on the object I receive from System.import
.
In the browser console:
System.import("@openmrs/esm-login-app").then(n => console.log(n));
VM2467:1 Module {Symbol(Symbol.toStringTag): 'Module', get: ƒ, init: ƒ}
This module has the right functions on it.
System.import("@openmrs/esm-patient-chart-app").then(n => console.log(n));
VM2475:1 Module {Symbol(Symbol.toStringTag): 'Module'}
This module is empty. The import doesn’t fail, but simply resolves to nothing.
The two overrides don’t seem to interact with each other—esm-patient-chart-app
always fails and esm-login-app
always works, regardless of whether the other is there.
That’s as far as I got with debugging. I figure the next step is to start instrumenting SystemJS. But I wanted to file this issue first in case there might be easier answers or things to check.
Issue Analytics
- State:
- Created 2 years ago
- Comments:12 (5 by maintainers)
@Paramesh-C I think that Joel was merely hypothesizing that the problem I was experiencing might have been caused by named-registers. Not that there is any particular problem with named registers generally. As explained above, it turned out that my problem was caused by a bad webpack configuration.
Thanks @brandones for the repro, and @Paramesh-C for helping out. I’ve created https://github.com/brandones/systemjs-issue-2379-repro/pull/1 which fixes the issue.
Suggestion 1 from @Paramesh-C is the main issue - the webpack config for
module
wasn’t telling webpack to compile the code in the project.Suggestion 2 is necessary just because once you fix the first thing there’s a new issue.
Suggestion 3 is not necessary nor recommended since it’s completely appropriate and good to load modules via import bare specifiers - you don’t need to load by url when you have an import map for them.
I’m not sure if your reproduction correctly captured what you were hoping, since the issue was just a simple problem with the webpack config that’s completely unrelated to named registers. So I’ll leave this open in case there’s more.