Skip to content

systemjs/systemjs

Repository files navigation

SystemJS

Gitter Backers on Open Collective Sponsors on Open Collective Downloads on JS Delivr

SystemJS is a hookable, standards-based module loader. It provides a workflow where code written for production workflows of native ES modules in browsers (like Rollup code-splitting builds), can be transpiled to the System.register module format to work in older browsers that don't support native modules, running almost-native module speeds while supporting top-level await, dynamic import, circular references and live bindings, import.meta.url, module types, import maps, integrity and Content Security Policy with compatibility in older browsers back to IE11.

Sponsors

Support SystemJS by becoming a sponsor. Your logo will show up here with a link to your website.

Backers

Thank you to all our backers! 🙏 [Become a backer]

Overview

1. s.js minimal production loader

The minimal 2.8KB s.js production loader includes the following features:

  • Loads System.register modules, the CSP-compatible SystemJS module format.
  • Support for loading bare specifier names with import maps via '>
    <script src="system.js">script>
    <script type="systemjs-module" src="/js/main.js">script>
    <script type="systemjs-module" src="import:name-of-module">script>

Loading with System.import

You can also dynamically load modules at any time with System.import():

System.import('/js/main.js');

where main.js is a module available in the System.register module format.

Bundling workflow

For an example of a bundling workflow, see the Rollup Code Splitting starter project - https://github.com/rollup/rollup-starter-code-splitting.

Note that when building System modules you typically want to ensure anonymous System.register statements like:

System.register([], function () { ... });

are emitted, as these can be loaded in a way that behaves the same as normal ES modules, and not named register statements like:

System.register('name', [], function () { ... });

While these can be supported with the named register extension, this approach is typically not recommended for modern modules workflows.

Import Maps

Say main.js depends on loading 'lodash', then we can define an import map:

<script src="system.js">script>
<script type="systemjs-importmap">
{
  "imports": {
    "lodash": "https://unpkg.com/[email protected]/lodash.js"
  }
}
script>

<script type="systemjs-module" src="/js/main.js">script>

IE11 Support

IE11 continues to be fully supported, provided the relevant polyfills are available.

The main required polyfill is a Promise polyfill. If using import maps a fetch polyfill is also needed.

Both of these can be loaded conditionally using for example using Bluebird Promises and the GitHub Fetch Polyfill over Unpkg:

<\/script>'); if (typeof fetch === 'undefined') document.write('">
<script>
  if (typeof Promise === 'undefined')
    document.write(' during parsing of the initial HTML page. However, IE11 does so. Codesandbox demonstration

Normally this is not an issue, as SystemJS will make an additional request via fetch/xhr for the import map. However, a problem can occur when the file is cached after the first request, since the first request caused by IE11 does not send the Origin request header by default. If the request requires CORS, the lack of an Origin request header causes many web servers (including AWS Cloudfront) to omit the response CORS headers. This can result in the resource being cached without CORS headers, which causes the later SystemJS fetch() to fail because of CORS checks.

This can be worked around by adding crossorigin="anonymous" as an attribute to the

About

Dynamic ES module loader

Resources

License

Stars

Watchers

Forks

Sponsor this project

Packages

No packages published

Contributors 117