Skip to content

Commit

Permalink
Use native in-browser modules and import maps
Browse files Browse the repository at this point in the history
  • Loading branch information
joeldenning committed Aug 21, 2023
1 parent e5b4fd4 commit 86f3b00
Show file tree
Hide file tree
Showing 7 changed files with 1,883 additions and 329 deletions.
6 changes: 6 additions & 0 deletions .changeset/tough-hornets-notice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"generator-single-spa": major
"webpack-config-single-spa": major
---

Use native in-browser modules and import maps rather than SystemJS
Original file line number Diff line number Diff line change
Expand Up @@ -5,74 +5,45 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Root Config</title>
<!--
Remove this if you only support browsers that support async/await.
This is needed by babel to share largeish helper code for compiling async/await in older
browsers. More information at https://github.com/single-spa/create-single-spa/issues/112
-->
<script src="https://cdn.jsdelivr.net/npm/regenerator-runtime@0.13.7/runtime.min.js"></script>
<!--
This CSP allows any SSL-enabled host and for arbitrary eval(), but you should limit these directives further to increase your app's security.
Learn more about CSP policies at https://content-security-policy.com/#directive
-->
<meta http-equiv="Content-Security-Policy" content="default-src 'self' https: localhost:*; script-src 'unsafe-inline' 'unsafe-eval' https: localhost:*; connect-src https: localhost:* ws://localhost:*; style-src 'unsafe-inline' https:; object-src 'none';">
<meta name="importmap-type" content="systemjs-importmap" />
<!-- If you wish to turn off import-map-overrides for specific environments (prod), uncomment the line below -->
<!-- More info at https://github.com/joeldenning/import-map-overrides/blob/master/docs/configuration.md#domain-list -->
<!-- <meta name="import-map-overrides-domains" content="denylist:prod.example.com" /> -->

<!-- Shared dependencies go into this import map. Your shared dependencies must be of one of the following formats:
1. System.register (preferred when possible) - https://github.com/systemjs/systemjs/blob/master/docs/system-register.md
2. UMD - https://github.com/umdjs/umd
3. Global variable
More information about shared dependencies can be found at https://single-spa.js.org/docs/recommended-setup#sharing-with-import-maps.
-->
<script type="systemjs-importmap">
{
"imports": {
"single-spa": "https://cdn.jsdelivr.net/npm/single-spa@5.9.0/lib/system/single-spa.min.js"
}
}
</script>
<link rel="preload" href="https://cdn.jsdelivr.net/npm/single-spa@5.9.0/lib/system/single-spa.min.js" as="script">

<!-- Add your organization's prod import map URL to this script's src -->
<!-- <script type="systemjs-importmap" src="/importmap.json"></script> -->

<% if (isLocal) { %>
<script type="systemjs-importmap">
<script type="overridable-importmap">
{
"imports": {
"single-spa": "https://cdn.jsdelivr.net/npm/single-spa@5.9.1/lib/system/single-spa.min.js",
"@<?- orgName ?>/root-config": "//localhost:9000/<?- orgName ?>-root-config.js"
}
}
</script>
<% } else { %>
<!-- Replace the "src" attribute's value to be the URL of your deployed import map -->
<script type="importmap" src="//replace-this-with-your-deployed-import-map-url.js"></script>
<% } %>
<link rel="modulepreload" href="https://cdn.jsdelivr.net/npm/single-spa@5.9.1/lib/system/single-spa.min.js" />
<!--
If you need to support Angular applications, uncomment the script tag below to ensure only one instance of ZoneJS is loaded
Learn more about why at https://single-spa.js.org/docs/ecosystem-angular/#zonejs
-->
<!-- <script src="https://cdn.jsdelivr.net/npm/zone.js@0.11.3/dist/zone.min.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/import-map-overrides@2.2.0/dist/import-map-overrides.js"></script>
<% if (isLocal) { %>
<script src="https://cdn.jsdelivr.net/npm/systemjs@6.8.3/dist/system.js"></script>
<script src="https://cdn.jsdelivr.net/npm/systemjs@6.8.3/dist/extras/amd.js"></script>
<% } else { %>
<script src="https://cdn.jsdelivr.net/npm/systemjs@6.8.3/dist/system.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/systemjs@6.8.3/dist/extras/amd.min.js"></script>
<% } %>
<script src="https://cdn.jsdelivr.net/npm/import-map-overrides@3.1.0/dist/import-map-overrides.js"></script>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<main></main>
<script>
System.import('@<?- orgName ?>/root-config');
import('@<?- orgName ?>/root-config');
</script>
<import-map-overrides-full show-when-local-storage="devtools" dev-libs></import-map-overrides-full>
</body>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,76 +6,41 @@
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Root Config</title>

<!--
Remove this if you only support browsers that support async/await.
This is needed by babel to share largeish helper code for compiling async/await in older
browsers. More information at https://github.com/single-spa/create-single-spa/issues/112
-->
<script src="https://cdn.jsdelivr.net/npm/regenerator-runtime@0.13.7/runtime.min.js"></script>

<!--
This CSP allows any SSL-enabled host and for arbitrary eval(), but you should limit these directives further to increase your app's security.
Learn more about CSP policies at https://content-security-policy.com/#directive
-->
<meta http-equiv="Content-Security-Policy" content="default-src 'self' https: localhost:*; script-src 'unsafe-inline' 'unsafe-eval' https: localhost:*; connect-src https: localhost:* ws://localhost:*; style-src 'unsafe-inline' https:; object-src 'none';">
<meta name="importmap-type" content="systemjs-importmap" />
<!-- If you wish to turn off import-map-overrides for specific environments (prod), uncomment the line below -->
<!-- More info at https://github.com/joeldenning/import-map-overrides/blob/master/docs/configuration.md#domain-list -->
<!-- <meta name="import-map-overrides-domains" content="denylist:prod.example.com" /> -->

<!-- Shared dependencies go into this import map. Your shared dependencies must be of one of the following formats:
1. System.register (preferred when possible) - https://github.com/systemjs/systemjs/blob/master/docs/system-register.md
2. UMD - https://github.com/umdjs/umd
3. Global variable
More information about shared dependencies can be found at https://single-spa.js.org/docs/recommended-setup#sharing-with-import-maps.
-->
<script type="systemjs-importmap">
{
"imports": {
"single-spa": "https://cdn.jsdelivr.net/npm/single-spa@5.9.0/lib/system/single-spa.min.js"
}
}
</script>
<link rel="preload" href="https://cdn.jsdelivr.net/npm/single-spa@5.9.0/lib/system/single-spa.min.js" as="script">

<!-- Add your organization's prod import map URL to this script's src -->
<!-- <script type="systemjs-importmap" src="/importmap.json"></script> -->

<% if (isLocal) { %>
<script type="systemjs-importmap">
<script type="overridable-importmap">
{
"imports": {
"@single-spa/welcome": "https://unpkg.com/single-spa-welcome/dist/single-spa-welcome.js",
"single-spa": "https://cdn.jsdelivr.net/npm/single-spa@5.9.1/lib/system/single-spa.min.js",
"@<?- orgName ?>/root-config": "//localhost:9000/<?- orgName ?>-root-config.js"
}
}
</script>
<% } else { %>
<!-- Replace the "src" attribute's value to be the URL of your deployed import map -->
<script type="importmap" src="//replace-this-with-your-deployed-import-map-url.js"></script>
<% } %>
<link rel="preload" href="https://cdn.jsdelivr.net/npm/single-spa@5.9.1/lib/system/single-spa.min.js" as="script">
<!--
If you need to support Angular applications, uncomment the script tag below to ensure only one instance of ZoneJS is loaded
Learn more about why at https://single-spa.js.org/docs/ecosystem-angular/#zonejs
-->
<!-- <script src="https://cdn.jsdelivr.net/npm/zone.js@0.11.3/dist/zone.min.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/import-map-overrides@2.2.0/dist/import-map-overrides.js"></script>
<% if (isLocal) { %>
<script src="https://cdn.jsdelivr.net/npm/systemjs@6.8.3/dist/system.js"></script>
<script src="https://cdn.jsdelivr.net/npm/systemjs@6.8.3/dist/extras/amd.js"></script>
<% } else { %>
<script src="https://cdn.jsdelivr.net/npm/systemjs@6.8.3/dist/system.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/systemjs@6.8.3/dist/extras/amd.min.js"></script>
<% } %>
<script src="https://cdn.jsdelivr.net/npm/import-map-overrides@3.1.0/dist/import-map-overrides.js"></script>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<script>
System.import('@<?- orgName ?>/root-config');
import('@<?- orgName ?>/root-config');
</script>
<import-map-overrides-full show-when-local-storage="devtools" dev-libs></import-map-overrides-full>
</body>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const routes = constructRoutes(microfrontendLayout);
const applications = constructApplications({
routes,
loadApp({ name }) {
return System.import(name);
return import(/* webpackIgnore: true */ name);
},
});
const layoutEngine = constructLayoutEngine({ routes, applications });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@ import { registerApplication, start<% if (typescript) {%>, LifeCycles<% }%> } fr
registerApplication({
name: "@single-spa/welcome",
app: () =>
System.import<% if (typescript) {%><LifeCycles><% } %>(
import<% if (typescript) {%><LifeCycles><% } %>(
/* webpackIgnore: true */
"https://unpkg.com/single-spa-welcome/dist/single-spa-welcome.js"
),
activeWhen: ["/"],
});

// registerApplication({
// name: "@<%- orgName %>/navbar",
// app: () => System.import("@<%- orgName %>/navbar"),
// app: () => import(/* webpackIgnore: true */ "@<%- orgName %>/navbar"),
// activeWhen: ["/"]
// });

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ const path = require("path");
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
const _HtmlWebpackPlugin = require("html-webpack-plugin");
const StandaloneSingleSpaPlugin = require("standalone-single-spa-webpack-plugin");
const SystemJSPublicPathPlugin = require("systemjs-webpack-interop/SystemJSPublicPathWebpackPlugin");

module.exports = webpackConfigSingleSpa;

Expand Down Expand Up @@ -41,12 +40,17 @@ function webpackConfigSingleSpa(opts) {
),
output: {
filename: `${opts.orgName}-${opts.projectName}.js`,
libraryTarget: "system",
library: {
type: "module",
},
path: path.resolve(process.cwd(), "dist"),
uniqueName: opts.projectName,
devtoolNamespace: `${opts.projectName}`,
publicPath: "",
},
experiments: {
outputModule: true,
},
module: {
rules: [
{
Expand Down Expand Up @@ -125,10 +129,6 @@ function webpackConfigSingleSpa(opts) {
new BundleAnalyzerPlugin({
analyzerMode: webpackConfigEnv.analyze ? "server" : "disabled",
}),
new SystemJSPublicPathPlugin({
systemjsModuleName: `@${opts.orgName}/${opts.projectName}`,
rootDirectoryLevel: opts.rootDirectoryLevel,
}),
!isProduction && !opts.disableHtmlGeneration && new HtmlWebpackPlugin(),
!isProduction &&
!opts.disableHtmlGeneration &&
Expand Down
Loading

0 comments on commit 86f3b00

Please sign in to comment.