Skip to content

Coexistence with native import maps #2497

@oravecz-jpmc

Description

@oravecz-jpmc
  • SystemJS Version: 6.15.1
  • 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?

Preferred way to coexist with native import maps

I have a host application built using React in the standard manner of bundling React along with the application. This happens to be bundled using Webpack, but I expect the behavior is the same with other bundlers.

In this application, there are some components exposed as native ESM packages, and others that are exposed as both native ESM and as System.register(). They are all loaded dynamically at runtime based on URL's provided by a service call (i.e. unknown at build time).

I've been having a difficult time trying to get these components to share an instance of React which is required for host-level communication and context sharing. I did stumble across mention of this in a @guybedford post, but with a caveat that this should not be done?

index.html

    <script type="importmap">
        {
            "imports": {
                "react": "/inbrowser/esm/react.production.min.js",
                "react-dom": "/inbrowser/esm/react-dom.production.min.js",
                "react/jsx-runtime": "/inbrowser/esm/react-jsx-runtime.production.min.js",
                ...other_shared_libraries
            }
        }
    </script>
    <script type="systemjs-importmap">
        {
            "imports": {
                "react": "app:react",
                "react-dom": "app:react-dom",
                "react/jsx-runtime": "app:react/jsx-runtime",
                ...other_shared_libraries
            }
        }
    </script>

index.tsx

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import * as JsxRuntime from 'react/jsx-runtime';

import 'systemjs';
System.set('app:react', React);
System.set('app:react-dom', ReactDOM);
System.set('app:react/jsx-runtime', JsxRuntime);

This works for me, but I'm not sure what edge cases exist. I am not worried about backwards compatibility with browsers pre-2023 that do not support native import maps, but I do want some of the enhanced features such as external import map fetching and dynamic import map features.

I'm also unclear as to how SystemJS is sometimes referred to as a polyfill. In my attempts, all shared dependencies and the remote component I am loading have to be bundled using the System.register() format which requires an invasive step into all of these libraries.

When I attempt to System.import('/path/to/esm'), I receive the Cannot use import statement outside a module exception.

Would I be better served to use the es-module-shims package for my particular use case?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions