The router for easy microfrontends
See changelog
See announcement blog post for what changed in single-spa@6
Full Changelog: https://github.com/single-spa/single-spa/compare/v5.9.4...v5.9.5
Full Changelog: https://github.com/single-spa/single-spa/compare/v6.0.0-beta.2...v6.0.0-beta.3
Full Changelog: https://github.com/single-spa/single-spa/compare/v5.9.3...v5.9.4
single-spa@6 provides advanced features such as async navigation cancelation and parcel-only mode (via patchHistoryApi
), while also updating the package configuration to use modern NodeJS and bundler features like package entrypoints and "type": "module"
. We also updated the default for urlRerouteOnly
to true, as it boosts performance and we consider it to be a best practice to author applications that work when urlRerouteOnly is set to true.
We still support IE11 and the same versions of NodeJS (at least as old as Node 10). However, we've changed our defaults such that IE11 is only supported with some additional configuration, as described in the IE11 Migration section below.
For the single-spa
npm package, we plan single-spa@6 to be the last major version that supports IE11. In general, we've released a major version of single-spa every 1-2 years. We do not have a concrete timeline or plans for single-spa@7, and will accept community contributions for any important patches to single-spa@6 after single-spa@7 is released.
For all surrounding packages (single-spa-react, single-spa-vue, systemjs-webpack-interop, single-spa-angular, etc) we may begin dropping IE11 support sooner than the single-spa@7 release. As we do so, we'll create documentation that lists the latest versions of packages that support IE11, and also accept community contributions to those versions for important updates.
The motivation for dropping IE11 support over time is to allow our core team to spend less time on supporting a nine year old browser and more time pushing the single-spa ecosystem forward. Also, we believe that the majority of end users should not suffer performance penalties because of a small percentage of users still using IE11. Slowly dropping IE11 also will also allow us to focus on a systemjs-less future for single-spa, where native browser modules are used rather than systemjs modules.
We understand and sympathize with companies who cannot drop IE11 support now, which is why we're supporting IE11 even though much of the ecosystem has already dropped it (Vue 3 does not support ie11, Angular only does after some effort, and even webpack 5 requires extra configuration to get it working in IE11). Many of single-spa's users are large financial institutions, large ecommerce companies, and other very large companies, where dropping IE11 support is a long process that involves many dozens of people from separate departments. We encourage single-spa users to start the conversations at your companies about dropping IE11 support, even if they take a long time or result in a decision to drop IE11 years in the future.
We think that >95% of single-spa users will be able to safely upgrade with no code changes. The breaking changes below are largely related to advanced features that most single-spa users do not use.
<script type="systemjs-importmap">
{
"imports": {
- "single-spa": "https://cdn.jsdelivr.net/npm/[email protected]/lib/system/single-spa.min.js"
+ "single-spa": "https://cdn.jsdelivr.net/npm/[email protected]/lib/es2015/system/single-spa.min.js"
}
}
</script>
npm install single-spa@beta
yarn add single-spa@beta
pnpm install single-spa@beta
start()
import { start } from 'single-spa';
// DO NOT MAKE THIS CHANGE unless you are experiencing problems.
- start();
+ start({
+ urlRerouteOnly: false
+ });
That's it! If you experience other issues, let us know in Github issues.
If you support IE11, use the es5
version of single-spa rather than es2015
. The method of doing this depends on your configuration - some common ones are explained below:
<script type="systemjs-importmap">
{
"imports": {
- "single-spa": "https://cdn.jsdelivr.net/npm/[email protected]/lib/es2015/system/single-spa.min.js"
+ "single-spa": "https://cdn.jsdelivr.net/npm/[email protected]/lib/es5/system/single-spa.min.js"
}
}
</script>
If externalizing single-spa in your webpack config (very common, and the default with webpack-config-single-spa), you do not need to make the changes below. Otherwise, though, these changes will ensure you use the IE11-compatible version of single-spa.
// webpack.config.js
module.exports = {
resolve: {
"alias": {
"single-spa": require.resolve("single-spa/lib/es5/esm/single-spa.min.js")
}
}
}
Use https://www.npmjs.com/package/@rollup/plugin-alias to alias the import similarly to webpack
If you do not wish to change bundler configuration, you can modify your import statements.
- import { start } from 'single-spa';
+ import { start } from 'single-spa/lib/es5/esm/single-spa.min.js';
"main"
field now points to an es2015 version of single-spa that does not work in IE11. To support IE11, see section below.start({urlRerouteOnly: false})
in your root config. (#828)cancelNavigation(val)
no longer cancels navigation if val
is falsy (#826)"type"
is now set to "module"
. This only impacts NodeJS usage of single-spa (not webpack/rollup/browser). Read more at official nodejs docs."exports"
. This changes which of single-spa's bundles are used by NodeJS, webpack, and rollup. The main change is that webpack / rollup will now use an IE11-incompatible (es2015) version of single-spa. See IE11 section below for more details. Additionally, an ESM version of single-spa will now be used when loaded via import('single-spa')
or import 'single-spa';
, whereas a UMD version will be used when calling require("single-spa')
. To avoid the dual package hazard, only use import
or require
to load single-spa in your NodeJS code - do not use both. You can see the package exports at https://github.com/single-spa/single-spa/blob/dea22f1aac39777a07252897ae625ab1d8313e9d/package.json#L8-L25.umd
builds now have .cjs
extensions rather than .js
, since all .js
files in the single-spa package are assumed to be ESM.File structure published to npm
# Before
# See https://www.jsdelivr.com/package/npm/single-spa?path=lib&version=5.9.3
lib/
# IE11
umd/
single-spa.dev.js
single-spa.min.js
# IE11
esm/
single-spa.dev.js
single-spa.min.js
# IE11
system/
single-spa.dev.js
single-spa.min.js
# No IE11
es2015/
single-spa.dev.js
single-spa.min.js
# After
# See https://www.jsdelivr.com/package/npm/single-spa?path=lib&version=6.0.0-beta.0
lib
# IE11
es5/
umd/
single-spa.dev.js
single-spa.min.js
system/
single-spa.dev.js
single-spa.min.js
esm/
single-spa.dev.js
single-spa.min.js
# No IE11
es2015/
umd/
single-spa.dev.cjs
single-spa.min.cjs
system/
single-spa.dev.js
single-spa.min.js
esm/
single-spa.dev.js
single-spa.min.js
cancelNavigation(promise)
with a promise as an argument. Single-spa will wait until that promise resolves/rejects before proceeding with navigation. If the promise resolves with a truthy value, navigation is canceled. If the promise resolves with a falsy value or rejects, navigation is not canceled. (#826)window.addEventListener("single-spa:before-routing-event", evt => {
if (evt.detail.oldUrl === "/settings") {
evt.detail.cancelNavigation(checkSettingsOkay())
}
})
async function checkSettingsOkay() {
const response = await fetch('/api/settings-okay')
if (response.ok) {
return true;
} else {
alert("Please fix your settings before leaving the page");
return false
}
}
patchHistoryApi()
api. This lets you use single-spa's modified implementations of pushState/replaceState/popstate/hashchange without using single-spa applications (#827)import { patchHistoryApi, mountRootParcel } from 'single-spa';
patchHistoryApi({
urlRerouteOnly: true
})
// now you don't need to call start() if you're only using parcels
mountRootParcel(parcelConfig, parcelProps)
location.origin
. This might allow single-spa to work in IE10, but is not guaranteed. IE10 is not officially supported. (#789 via @gongshun)