SystemJS - proof of concept with Create React App ejected Webpack - unable to access module properties
See original GitHub issue- SystemJS Version:
- Which library are you using?
- [ X] 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
Hi, I have a proof of concept where I am trying to use a Create React App ejected Webpack 5 config as the basis for a module that is exported to System JS format. The config has been updated to support System JS format. The consumer of the module is not able to access the properties that the module exposes. I have followed the System JS guidelines for Webpack config and Webpack dev server config. When I try to load the module, System.import() seems to load the module’s main entry, but I am not able to access any of the module’s properties. Is there something else I would need to do?
Consumer app index.html:
<script src="https://cdn.jsdelivr.net/npm/systemjs@6.8.3/dist/system.min.js"></script>
<script type="systemjs-importmap">
{
"imports": {
"wp5-ms": "//localhost:3000/static/js/main.chunk.js"
}
}
</script>
Consumer app TypeScript:
React.useEffect(() => {
const loadExample = async () => {
const wp5Example = await global.System.import('wp5-ms');
console.log('wp5Example', wp5Example);
};
loadExample();
}, []);
Module main entry file:
import "systemjs-webpack-interop/auto-public-path";
console.log("hi outside");
const foo = { foo: "bar" };
export default foo;
Console output in consumer application (why is foo not available?):
Here is the high level output of the SystemJS module that is generated with my Webpack config:
Issue Analytics
- State:
- Created 2 years ago
- Comments:8
Using webpack dynamic import is an effective way of code splitting when using libraryTarget system.
The main limitation with webpack’s
optimization
config is that it generates a bunch of files that must be loaded in a specific order in order for the bundle to correctly instantiate. The majority of the webpack ecosystem uses html-webpack-plugin which inserts<script>
elements to load all the separate bundles in the correct order.SystemJS modules are each a single javascript file, that can have dependencies on each other. Ideally, the main output bundle would correctly list its dependencies in a way that SystemJS could understand and then load. However, webpack does not do this, as webpack code splits generated via
optimization
are in webpackJsonp format rather than System.register format, and also do not know what their dependencies are. This limitation is something that the author of webpack was open to being solved, but just said would take a lot of work. See https://github.com/webpack/webpack/issues/8833#issuecomment-468181544 where this was discussed further.With the limitation in mind, some people have tried to make it work anyway by doing
Promise.all(['/main.js', '/chunk1.js', 'chunk2.js', 'vendors.js'])
, but that is problematic because it does not guarantee order of execution.@naivefun No, I didn’t get it to work in my proof of concept. Chunking is not supported with the Webpack system library target. I guess other library formats would be needed with Webpack if chunking were desired, or perhaps create additional Webpack outputs of type system as an alternate strategy to chunking.