From b9ca91b5f8c138fe565c4c1c3e5d1913c4e64114 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 15 Nov 2024 23:47:47 +0000 Subject: [PATCH] deploy: 92866152c002dd9e2d26a4ac5a4d06fca1bfd720 --- 404.html | 6 +++--- .../js/{02af63f8.ced52ba9.js => 02af63f8.5d2a6c61.js} | 2 +- .../js/{3827c3c6.c3037c1a.js => 3827c3c6.f39d9452.js} | 2 +- .../js/{38eb30df.122fa29d.js => 38eb30df.60202a58.js} | 2 +- .../js/{5896a7ea.9f9af63b.js => 5896a7ea.76ccd6b7.js} | 2 +- .../js/{674fa9c4.bcf3cae5.js => 674fa9c4.a18655f8.js} | 2 +- .../js/{78e9b454.44bd04d8.js => 78e9b454.7980e859.js} | 2 +- .../js/{7bb2f638.5b1c5689.js => 7bb2f638.2e92a58c.js} | 2 +- .../js/{8ac9c664.bdd19a76.js => 8ac9c664.f5b3d18f.js} | 2 +- .../js/{98ffbda8.a66c2c97.js => 98ffbda8.825c1f59.js} | 2 +- .../js/{a4df4865.47cea819.js => a4df4865.da538aa2.js} | 2 +- .../js/{b2f554cd.e2985198.js => b2f554cd.3ed8c3ae.js} | 2 +- .../js/{c4f5d8e4.3c5853db.js => c4f5d8e4.3a59c85d.js} | 2 +- .../js/{daa69925.86d8d961.js => daa69925.dd50233d.js} | 2 +- .../js/{e85cb86b.47c912e2.js => e85cb86b.ba02e77b.js} | 2 +- .../js/{ef491088.a48ce8d7.js => ef491088.1fdd9000.js} | 2 +- .../js/{fa29c2d5.3df033ae.js => fa29c2d5.3881ec39.js} | 2 +- assets/js/{main.0ed23e96.js => main.4d536506.js} | 4 ++-- ...e96.js.LICENSE.txt => main.4d536506.js.LICENSE.txt} | 0 ...ntime~main.98d231f6.js => runtime~main.2cbc57e6.js} | 2 +- .../02/26/a-case-for-soa-in-the-browser/index.html | 6 +++--- .../16/a-step-by-step-guide-to-single-spa/index.html | 6 +++--- .../2018/06/19/single-spa-parcels-explained/index.html | 6 +++--- blog/2019/02/20/single-spa-inspector/index.html | 6 +++--- blog/2020/02/24/single-spa-5/index.html | 6 +++--- .../2023/08/22/single-spa-core-is-expanding/index.html | 6 +++--- .../index.html | 6 +++--- blog/2023/11/07/core-team-meeting-notes/index.html | 6 +++--- blog/2023/11/27/single-spa-6/index.html | 6 +++--- blog/2023/12/12/core-team-meeting-notes/index.html | 6 +++--- blog/2024/01/03/core-team-meeting-notes/index.html | 6 +++--- blog/2024/02/14/core-team-meeting-notes/index.html | 6 +++--- blog/2024/03/12/core-team-meeting-notes/index.html | 6 +++--- .../top-5-microfrontend-hosting-solutions/index.html | 6 +++--- blog/2024/04/10/core-team-meeting-notes/index.html | 6 +++--- blog/2024/06/08/core-team-meeting-notes/index.html | 6 +++--- blog/2024/09/30/core-team-meeting-notes/index.html | 6 +++--- blog/archive/index.html | 6 +++--- blog/atom.xml | 4 ++-- blog/index.html | 6 +++--- blog/page/2/index.html | 10 +++++----- blog/rss.xml | 4 ++-- code-of-conduct/index.html | 6 +++--- contributors/index.html | 6 +++--- docs/4.x/api/index.html | 6 +++--- docs/4.x/building-applications/index.html | 6 +++--- docs/4.x/code-of-conduct/index.html | 6 +++--- docs/4.x/configuration/index.html | 6 +++--- docs/4.x/contributing-overview/index.html | 8 ++++---- docs/4.x/ecosystem-angular/index.html | 8 ++++---- docs/4.x/ecosystem-angularjs/index.html | 6 +++--- docs/4.x/ecosystem-backbone/index.html | 6 +++--- docs/4.x/ecosystem-cycle/index.html | 6 +++--- docs/4.x/ecosystem-ember/index.html | 6 +++--- docs/4.x/ecosystem-html-web-components/index.html | 6 +++--- docs/4.x/ecosystem-inferno/index.html | 6 +++--- docs/4.x/ecosystem-leaked-globals/index.html | 6 +++--- docs/4.x/ecosystem-preact/index.html | 6 +++--- docs/4.x/ecosystem-react/index.html | 6 +++--- docs/4.x/ecosystem-riot/index.html | 6 +++--- docs/4.x/ecosystem-svelte/index.html | 6 +++--- docs/4.x/ecosystem-vue/index.html | 6 +++--- docs/4.x/ecosystem/index.html | 6 +++--- docs/4.x/examples/index.html | 6 +++--- docs/4.x/faq/index.html | 6 +++--- docs/4.x/getting-started-overview/index.html | 6 +++--- docs/4.x/glossary/index.html | 6 +++--- docs/4.x/migrating-angularJS-tutorial/index.html | 6 +++--- docs/4.x/migrating-existing-spas/index.html | 6 +++--- docs/4.x/migrating-react-tutorial/index.html | 6 +++--- docs/4.x/parcels-api/index.html | 6 +++--- docs/4.x/parcels-overview/index.html | 6 +++--- docs/4.x/separating-applications/index.html | 6 +++--- docs/4.x/starting-from-scratch/index.html | 8 ++++---- docs/5.x/api/index.html | 6 +++--- docs/5.x/building-applications/index.html | 6 +++--- docs/5.x/code-of-conduct/index.html | 6 +++--- docs/5.x/configuration/index.html | 6 +++--- docs/5.x/contributing-overview/index.html | 8 ++++---- docs/5.x/create-single-spa/index.html | 6 +++--- docs/5.x/devtools/index.html | 6 +++--- docs/5.x/ecosystem-alpinejs/index.html | 6 +++--- docs/5.x/ecosystem-angular/index.html | 8 ++++---- docs/5.x/ecosystem-angularjs/index.html | 6 +++--- docs/5.x/ecosystem-backbone/index.html | 6 +++--- docs/5.x/ecosystem-css/index.html | 6 +++--- docs/5.x/ecosystem-cycle/index.html | 6 +++--- docs/5.x/ecosystem-dojo/index.html | 6 +++--- docs/5.x/ecosystem-ember/index.html | 6 +++--- docs/5.x/ecosystem-html-web-components/index.html | 6 +++--- docs/5.x/ecosystem-inferno/index.html | 6 +++--- docs/5.x/ecosystem-leaked-globals/index.html | 6 +++--- docs/5.x/ecosystem-preact/index.html | 6 +++--- docs/5.x/ecosystem-react/index.html | 6 +++--- docs/5.x/ecosystem-riot/index.html | 6 +++--- docs/5.x/ecosystem-snowpack/index.html | 6 +++--- docs/5.x/ecosystem-svelte/index.html | 6 +++--- docs/5.x/ecosystem-vite/index.html | 6 +++--- docs/5.x/ecosystem-vue/index.html | 6 +++--- docs/5.x/ecosystem/index.html | 6 +++--- docs/5.x/examples/index.html | 6 +++--- docs/5.x/faq/index.html | 6 +++--- docs/5.x/getting-started-overview/index.html | 8 ++++---- docs/5.x/glossary/index.html | 6 +++--- docs/5.x/layout-api/index.html | 6 +++--- docs/5.x/layout-definition/index.html | 6 +++--- docs/5.x/layout-overview/index.html | 6 +++--- docs/5.x/microfrontends-concept/index.html | 6 +++--- docs/5.x/migrating-existing-spas/index.html | 6 +++--- docs/5.x/module-types/index.html | 6 +++--- docs/5.x/parcels-api/index.html | 6 +++--- docs/5.x/parcels-overview/index.html | 6 +++--- docs/5.x/recommended-setup/index.html | 6 +++--- docs/5.x/separating-applications/index.html | 6 +++--- docs/5.x/shared-webpack-configs/index.html | 6 +++--- docs/5.x/single-spa-playground/index.html | 6 +++--- docs/5.x/ssr-overview/index.html | 6 +++--- docs/5.x/testing/e2e/index.html | 6 +++--- docs/5.x/testing/units/index.html | 6 +++--- docs/5.x/videos/index.html | 6 +++--- docs/api/index.html | 6 +++--- docs/building-applications/index.html | 6 +++--- docs/code-of-conduct/index.html | 6 +++--- docs/configuration/index.html | 6 +++--- docs/contributing-overview/index.html | 8 ++++---- docs/create-single-spa/index.html | 6 +++--- docs/devtools/index.html | 6 +++--- docs/ecosystem-alpinejs/index.html | 6 +++--- docs/ecosystem-angular/index.html | 8 ++++---- docs/ecosystem-angularjs/index.html | 6 +++--- docs/ecosystem-backbone/index.html | 6 +++--- docs/ecosystem-css/index.html | 6 +++--- docs/ecosystem-cycle/index.html | 6 +++--- docs/ecosystem-dojo/index.html | 6 +++--- docs/ecosystem-ember/index.html | 6 +++--- docs/ecosystem-html-web-components/index.html | 6 +++--- docs/ecosystem-inferno/index.html | 6 +++--- docs/ecosystem-leaked-globals/index.html | 6 +++--- docs/ecosystem-preact/index.html | 6 +++--- docs/ecosystem-react/index.html | 6 +++--- docs/ecosystem-riot/index.html | 6 +++--- docs/ecosystem-snowpack/index.html | 6 +++--- docs/ecosystem-svelte/index.html | 6 +++--- docs/ecosystem-vite/index.html | 6 +++--- docs/ecosystem-vue/index.html | 6 +++--- docs/ecosystem/index.html | 6 +++--- docs/examples/index.html | 6 +++--- docs/faq/index.html | 6 +++--- docs/getting-started-overview/index.html | 8 ++++---- docs/glossary/index.html | 6 +++--- docs/index.html | 4 ++-- docs/layout-api/index.html | 6 +++--- docs/layout-definition/index.html | 6 +++--- docs/layout-overview/index.html | 6 +++--- docs/microfrontends-concept/index.html | 6 +++--- docs/migrating-existing-spas/index.html | 6 +++--- docs/module-types/index.html | 6 +++--- docs/next/index.html | 6 +++--- docs/parcels-api/index.html | 6 +++--- docs/parcels-overview/index.html | 6 +++--- docs/recommended-setup/index.html | 6 +++--- docs/separating-applications/index.html | 6 +++--- docs/shared-webpack-configs/index.html | 6 +++--- docs/single-spa-playground/index.html | 6 +++--- docs/ssr-overview/index.html | 6 +++--- docs/testing/e2e/index.html | 6 +++--- docs/testing/units/index.html | 6 +++--- docs/videos/index.html | 6 +++--- error/index.html | 6 +++--- governance/index.html | 6 +++--- help/index.html | 6 +++--- index.html | 6 +++--- languages/index.html | 6 +++--- privacy/single-spa-inspector-privacy-policy/index.html | 6 +++--- search/index.html | 6 +++--- sponsors/index.html | 6 +++--- users/index.html | 6 +++--- versions/index.html | 6 +++--- 178 files changed, 504 insertions(+), 504 deletions(-) rename assets/js/{02af63f8.ced52ba9.js => 02af63f8.5d2a6c61.js} (99%) rename assets/js/{3827c3c6.c3037c1a.js => 3827c3c6.f39d9452.js} (99%) rename assets/js/{38eb30df.122fa29d.js => 38eb30df.60202a58.js} (99%) rename assets/js/{5896a7ea.9f9af63b.js => 5896a7ea.76ccd6b7.js} (98%) rename assets/js/{674fa9c4.bcf3cae5.js => 674fa9c4.a18655f8.js} (98%) rename assets/js/{78e9b454.44bd04d8.js => 78e9b454.7980e859.js} (64%) rename assets/js/{7bb2f638.5b1c5689.js => 7bb2f638.2e92a58c.js} (99%) rename assets/js/{8ac9c664.bdd19a76.js => 8ac9c664.f5b3d18f.js} (99%) rename assets/js/{98ffbda8.a66c2c97.js => 98ffbda8.825c1f59.js} (98%) rename assets/js/{a4df4865.47cea819.js => a4df4865.da538aa2.js} (99%) rename assets/js/{b2f554cd.e2985198.js => b2f554cd.3ed8c3ae.js} (99%) rename assets/js/{c4f5d8e4.3c5853db.js => c4f5d8e4.3a59c85d.js} (98%) rename assets/js/{daa69925.86d8d961.js => daa69925.dd50233d.js} (99%) rename assets/js/{e85cb86b.47c912e2.js => e85cb86b.ba02e77b.js} (99%) rename assets/js/{ef491088.a48ce8d7.js => ef491088.1fdd9000.js} (99%) rename assets/js/{fa29c2d5.3df033ae.js => fa29c2d5.3881ec39.js} (98%) rename assets/js/{main.0ed23e96.js => main.4d536506.js} (94%) rename assets/js/{main.0ed23e96.js.LICENSE.txt => main.4d536506.js.LICENSE.txt} (100%) rename assets/js/{runtime~main.98d231f6.js => runtime~main.2cbc57e6.js} (91%) diff --git a/404.html b/404.html index 7f3ad6763..81c66eecf 100644 --- a/404.html +++ b/404.html @@ -14,10 +14,10 @@ - - + + -
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

+
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

\ No newline at end of file diff --git a/assets/js/02af63f8.ced52ba9.js b/assets/js/02af63f8.5d2a6c61.js similarity index 99% rename from assets/js/02af63f8.ced52ba9.js rename to assets/js/02af63f8.5d2a6c61.js index 0d00892e3..5a29c16bc 100644 --- a/assets/js/02af63f8.ced52ba9.js +++ b/assets/js/02af63f8.5d2a6c61.js @@ -1 +1 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[4067],{9046:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>c});var i=s(4848),t=s(8453);const r={title:"single-spa 5",author:"Joel Denning",authorURL:"https://twitter.com/joelbdenning",authorImageURL:"https://avatars2.githubusercontent.com/u/5524384?s=460&v=4"},a="Announcing single-spa@5",o={permalink:"/blog/2020/02/24/single-spa-5",source:"@site/blog/2020-02-24-single-spa-5.md",title:"single-spa 5",description:"Today we released single-spa@5.0.0.",date:"2020-02-24T00:00:00.000Z",formattedDate:"February 24, 2020",tags:[],readingTime:4.29,hasTruncateMarker:!1,authors:[{name:"Joel Denning",url:"https://twitter.com/joelbdenning",imageURL:"https://avatars2.githubusercontent.com/u/5524384?s=460&v=4"}],frontMatter:{title:"single-spa 5",author:"Joel Denning",authorURL:"https://twitter.com/joelbdenning",authorImageURL:"https://avatars2.githubusercontent.com/u/5524384?s=460&v=4"},unlisted:!1,prevItem:{title:"The single-spa core team is expanding",permalink:"/blog/2023/08/22/single-spa-core-is-expanding"},nextItem:{title:"single-spa Inspector and 4.1",permalink:"/blog/2019/02/20/single-spa-inspector"}},l={authorsImageUrls:[void 0]},c=[{value:"Migration from 4 to 5",id:"migration-from-4-to-5",level:2},{value:"Performance improvements",id:"performance-improvements",level:2},{value:"single-spa CLI",id:"single-spa-cli",level:2},{value:"Tutorial videos",id:"tutorial-videos",level:2},{value:"New example repositories",id:"new-example-repositories",level:2},{value:"Documentation overhaul",id:"documentation-overhaul",level:2},{value:"Development builds and error codes",id:"development-builds-and-error-codes",level:2},{value:"Governance",id:"governance",level:2},{value:"Where next?",id:"where-next",level:2}];function d(e){const n={a:"a",code:"code",h2:"h2",li:"li",p:"p",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"Today we released single-spa@5.0.0."}),"\n",(0,i.jsx)(n.p,{children:"Here are the highlights:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Performance focus: 35% decrease in library size."}),"\n",(0,i.jsxs)(n.li,{children:["A CLI for single-spa: ",(0,i.jsx)(n.a,{href:"/docs/create-single-spa",children:"create-single-spa"})]}),"\n",(0,i.jsxs)(n.li,{children:["New tutorial videos: ",(0,i.jsx)(n.a,{href:"https://www.youtube.com/playlist?list=PLLUD8RtHvsAOhtHnyGx57EYXoaNsxGrTU",children:"Youtube playlist"})," / ",(0,i.jsx)(n.a,{href:"https://space.bilibili.com/495254378/video",children:"Bilibili space"})]}),"\n",(0,i.jsxs)(n.li,{children:["New framework-specific example repositories - ",(0,i.jsx)(n.a,{href:"https://github.com/react-microfrontends",children:"React example"}),", ",(0,i.jsx)(n.a,{href:"https://github.com/vue-microfrontends",children:"Vue example"}),", ",(0,i.jsx)(n.a,{href:"https://github.com/polyglot-microfrontends",children:"Multiple frameworks example"}),", ",(0,i.jsx)(n.a,{href:"/docs/examples",children:"Full list"})]}),"\n",(0,i.jsxs)(n.li,{children:["Massively improved documentation, including ",(0,i.jsx)(n.a,{href:"/docs/microfrontends-concept",children:"Concept: Microfrontends"})," and ",(0,i.jsx)(n.a,{href:"/docs/recommended-setup",children:"The Recommended Setup"}),"."]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"https://github.com/single-spa/single-spa/releases/tag/v5.0.0",children:"Release notes here"})}),"\n",(0,i.jsx)(n.h2,{id:"migration-from-4-to-5",children:"Migration from 4 to 5"}),"\n",(0,i.jsxs)(n.p,{children:["For every user we're aware of, ",(0,i.jsx)(n.strong,{children:"you do not need to change anything in your code in order to upgrade to single-spa@5"}),". The breaking changes listed in the release notes are the removal of features that were originally used by Canopy Tax, but were never documented."]}),"\n",(0,i.jsxs)(n.p,{children:["If installing from npm, you can simply ",(0,i.jsx)(n.code,{children:"npm install --save single-spa@5.0.0"})," or ",(0,i.jsx)(n.code,{children:"yarn add single-spa@5.0.0"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["Alternatively, single-spa is available on ",(0,i.jsx)(n.a,{href:"https://cdnjs.com/libraries/single-spa",children:"cdnjs"}),", ",(0,i.jsx)(n.a,{href:"https://www.jsdelivr.com/package/npm/single-spa",children:"jsdelivr"}),", and ",(0,i.jsx)(n.a,{href:"https://unpkg.com/browse/single-spa/",children:"unpkg"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The single-spa core team is committed to treating our users well, which includes not introducing massive breaking changes. The core single-spa API has not seen massive breaking changes ",(0,i.jsx)(n.a,{href:"https://github.com/single-spa/single-spa/releases/tag/v3.0.0",children:"since single-spa@3 in August 2016"}),". We have added features and improved things, but single-spa is a stable technology. We are committed to maintaining it, documenting it, and adjusting it as technologies like in-browser modules become more and more popular and viable."]}),"\n",(0,i.jsx)(n.h2,{id:"performance-improvements",children:"Performance improvements"}),"\n",(0,i.jsx)(n.p,{children:"The ESM version of single-spa@4 was 23.8kb (7.2kb gzipped). That was improved in single-spa@5 to 15.5kb (5.1kb gzipped). We did this by optimizing our build process and removing unused features."}),"\n",(0,i.jsx)(n.h2,{id:"single-spa-cli",children:"single-spa CLI"}),"\n",(0,i.jsxs)(n.p,{children:["Since single-spa's inception, bundler configuration has been a huge source of user pain. We have heard this pain and implemented ",(0,i.jsx)(n.a,{href:"/docs/create-single-spa",children:"create-single-spa"}),", which creates (and sometimes can update) repositories that are ready to be used as single-spa microfrontends. For Angular and Vue, the official CLIs are used with a few extra plugins automatically installed. For React, a default webpack config with decent eslint / prettier defaults is set up."]}),"\n",(0,i.jsxs)(n.p,{children:["Additionally, we have added a lot of documentation for webpack in ",(0,i.jsx)(n.a,{href:"/docs/recommended-setup#build-tools-webpack--rollup",children:"The Recommended Setup"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"tutorial-videos",children:"Tutorial videos"}),"\n",(0,i.jsx)(n.p,{children:"We understand that single-spa is more than just a library - it is an architecture. The single-spa library itself is the core, but the surrounding ecosystem of concepts and libraries are equally important to successfully migrating to single-spa and having it work for you. As such, we have created a Youtube playlist, currently consisting of seven videos, to help you get started."}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://www.youtube.com/playlist?list=PLLUD8RtHvsAOhtHnyGx57EYXoaNsxGrTU",children:"Youtube playlist"})," / ",(0,i.jsx)(n.a,{href:"https://space.bilibili.com/495254378/video",children:"Bilibili space"})]}),"\n",(0,i.jsx)(n.p,{children:"The videos currently cover the following topics:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"What are Microfrontends?"}),"\n",(0,i.jsx)(n.li,{children:"In-browser vs build-time JavaScript modules"}),"\n",(0,i.jsx)(n.li,{children:"Import Maps"}),"\n",(0,i.jsx)(n.li,{children:"Local Development with single-spa and import maps"}),"\n",(0,i.jsx)(n.li,{children:"Deploying Microfrontends / Continuous Integration (CI)"}),"\n",(0,i.jsx)(n.li,{children:"SystemJS intro"}),"\n",(0,i.jsx)(n.li,{children:"Lazy Loading"}),"\n",(0,i.jsx)(n.li,{children:"Bundlers, webpack, and rollup."}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"new-example-repositories",children:"New example repositories"}),"\n",(0,i.jsxs)(n.p,{children:["What started out as Canopy Tax's special sauce for independently deployed frontend microservices is now fully accessible to the public with our ",(0,i.jsx)(n.a,{href:"/docs/examples",children:"new set of example repos"}),". We have a React example, a Vue example, and a polyglot (multiple framework) example. We hope to add an Angular example, after we achieve support for Angular 9. These example repositories are actively watched and maintained by the single-spa core team, and reflect our current opinions on the best, production-viable way to do microfrontends."]}),"\n",(0,i.jsx)(n.p,{children:"Furthermore, we have deployed each of the examples to our new domains:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://react.microfrontends.app",children:"https://react.microfrontends.app"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://polyglot.microfrontends.app",children:"https://polyglot.microfrontends.app"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://vue.microfrontends.app",children:"https://vue.microfrontends.app"})}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"documentation-overhaul",children:"Documentation overhaul"}),"\n",(0,i.jsx)(n.p,{children:"We removed several dated documentation pages, and added several that were very much lacking. Here are a few pages that give you the most bang for your buck:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"/docs/microfrontends-concept",children:"Concept: Microfrontend"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"/docs/recommended-setup",children:"The Recommended Setup"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"/docs/create-single-spa",children:"create-single-spa CLI"})}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"development-builds-and-error-codes",children:"Development builds and error codes"}),"\n",(0,i.jsxs)(n.p,{children:["Taking inspiration from the ",(0,i.jsx)(n.a,{href:"https://reactjs.org/docs/optimizing-performance.html#use-the-production-build",children:"react development and production builds"}),", we now publish to NPM both development and production builds in the following formats: UMD, ESM, and System.register."]}),"\n",(0,i.jsxs)(n.p,{children:["You can see the ",(0,i.jsx)(n.a,{href:"https://unpkg.com/browse/single-spa@5.0.0/lib/",children:"published build files here"}),". The ",(0,i.jsx)(n.code,{children:".dev.js"})," files provide full debugging information in the browser console, whereas the ",(0,i.jsx)(n.code,{children:".min.js"})," files give you a numeric error code and a link to a documentation page that explains the error. We hope that these error codes and documentation for them will improve discoverability of relevant documentation when you're setting up single-spa."]}),"\n",(0,i.jsxs)(n.p,{children:["An example of these new documentation pages for error codes is ",(0,i.jsx)(n.a,{href:"/error/?code=35&arg=application&arg=app1&arg=%7B%7D",children:"found here"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"governance",children:"Governance"}),"\n",(0,i.jsxs)(n.p,{children:["Some of you may have noticed that we recently moved all github repos from ",(0,i.jsx)(n.a,{href:"https://github.com/CanopyTax",children:"https://github.com/CanopyTax"})," to ",(0,i.jsx)(n.a,{href:"https://github.com/single-spa",children:"https://github.com/single-spa"}),". Canopy Tax was the company where single-spa was first authored, but as a core team we asked to move ownership and governance of the projects to an organization fully managed by the open source community. In agreement with Canopy, we made that change."]}),"\n",(0,i.jsx)(n.p,{children:"This change does not mean anything drastic for single-spa. Its license was and is MIT, and we have no plans to do anything with the project besides make it better."}),"\n",(0,i.jsx)(n.h2,{id:"where-next",children:"Where next?"}),"\n",(0,i.jsxs)(n.p,{children:["We are actively ",(0,i.jsx)(n.a,{href:"https://github.com/single-spa/zh-hans.single-spa.js.org",children:"translating the single-spa documentation to Chinese"}),", and hope to add other languages soon. We will add full ",(0,i.jsx)(n.a,{href:"https://github.com/single-spa/single-spa-angular/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+angular+9",children:"Angular 9 support"})," soon, and hope to add ",(0,i.jsx)(n.a,{href:"https://github.com/single-spa/single-spa/issues/103",children:"server rendering"})," in an upcoming release."]}),"\n",(0,i.jsxs)(n.p,{children:["Please ",(0,i.jsx)(n.a,{href:"/docs/contributing-overview",children:"contribute to our code"})," and ",(0,i.jsx)(n.a,{href:"/docs/ecosystem",children:"ecosystem"}),", ",(0,i.jsx)(n.a,{href:"https://join.slack.com/t/single-spa/shared_invite/zt-2php1iewg-guIu7m9tRV0CjxluXqbCAg",children:"join our single-spa slack channel"}),", ",(0,i.jsx)(n.a,{href:"https://twitter.com/Single_spa",children:"follow our official Twitter account"}),", and contribute to ",(0,i.jsx)(n.a,{href:"https://opencollective.com/single-spa",children:"our open collective"}),". The ",(0,i.jsx)(n.a,{href:"/contributors",children:"single-spa core team"})," all have full-time jobs and maintain this project on a volunteer basis."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>o});var i=s(6540);const t={},r=i.createContext(t);function a(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[4067],{9046:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>c});var i=s(4848),t=s(8453);const r={title:"single-spa 5",author:"Joel Denning",authorURL:"https://twitter.com/joelbdenning",authorImageURL:"https://avatars2.githubusercontent.com/u/5524384?s=460&v=4"},a="Announcing single-spa@5",o={permalink:"/blog/2020/02/24/single-spa-5",source:"@site/blog/2020-02-24-single-spa-5.md",title:"single-spa 5",description:"Today we released single-spa@5.0.0.",date:"2020-02-24T00:00:00.000Z",formattedDate:"February 24, 2020",tags:[],readingTime:4.29,hasTruncateMarker:!1,authors:[{name:"Joel Denning",url:"https://twitter.com/joelbdenning",imageURL:"https://avatars2.githubusercontent.com/u/5524384?s=460&v=4"}],frontMatter:{title:"single-spa 5",author:"Joel Denning",authorURL:"https://twitter.com/joelbdenning",authorImageURL:"https://avatars2.githubusercontent.com/u/5524384?s=460&v=4"},unlisted:!1,prevItem:{title:"The single-spa core team is expanding",permalink:"/blog/2023/08/22/single-spa-core-is-expanding"},nextItem:{title:"single-spa Inspector and 4.1",permalink:"/blog/2019/02/20/single-spa-inspector"}},l={authorsImageUrls:[void 0]},c=[{value:"Migration from 4 to 5",id:"migration-from-4-to-5",level:2},{value:"Performance improvements",id:"performance-improvements",level:2},{value:"single-spa CLI",id:"single-spa-cli",level:2},{value:"Tutorial videos",id:"tutorial-videos",level:2},{value:"New example repositories",id:"new-example-repositories",level:2},{value:"Documentation overhaul",id:"documentation-overhaul",level:2},{value:"Development builds and error codes",id:"development-builds-and-error-codes",level:2},{value:"Governance",id:"governance",level:2},{value:"Where next?",id:"where-next",level:2}];function d(e){const n={a:"a",code:"code",h2:"h2",li:"li",p:"p",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"Today we released single-spa@5.0.0."}),"\n",(0,i.jsx)(n.p,{children:"Here are the highlights:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Performance focus: 35% decrease in library size."}),"\n",(0,i.jsxs)(n.li,{children:["A CLI for single-spa: ",(0,i.jsx)(n.a,{href:"/docs/create-single-spa",children:"create-single-spa"})]}),"\n",(0,i.jsxs)(n.li,{children:["New tutorial videos: ",(0,i.jsx)(n.a,{href:"https://www.youtube.com/playlist?list=PLLUD8RtHvsAOhtHnyGx57EYXoaNsxGrTU",children:"Youtube playlist"})," / ",(0,i.jsx)(n.a,{href:"https://space.bilibili.com/495254378/video",children:"Bilibili space"})]}),"\n",(0,i.jsxs)(n.li,{children:["New framework-specific example repositories - ",(0,i.jsx)(n.a,{href:"https://github.com/react-microfrontends",children:"React example"}),", ",(0,i.jsx)(n.a,{href:"https://github.com/vue-microfrontends",children:"Vue example"}),", ",(0,i.jsx)(n.a,{href:"https://github.com/polyglot-microfrontends",children:"Multiple frameworks example"}),", ",(0,i.jsx)(n.a,{href:"/docs/examples",children:"Full list"})]}),"\n",(0,i.jsxs)(n.li,{children:["Massively improved documentation, including ",(0,i.jsx)(n.a,{href:"/docs/microfrontends-concept",children:"Concept: Microfrontends"})," and ",(0,i.jsx)(n.a,{href:"/docs/recommended-setup",children:"The Recommended Setup"}),"."]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"https://github.com/single-spa/single-spa/releases/tag/v5.0.0",children:"Release notes here"})}),"\n",(0,i.jsx)(n.h2,{id:"migration-from-4-to-5",children:"Migration from 4 to 5"}),"\n",(0,i.jsxs)(n.p,{children:["For every user we're aware of, ",(0,i.jsx)(n.strong,{children:"you do not need to change anything in your code in order to upgrade to single-spa@5"}),". The breaking changes listed in the release notes are the removal of features that were originally used by Canopy Tax, but were never documented."]}),"\n",(0,i.jsxs)(n.p,{children:["If installing from npm, you can simply ",(0,i.jsx)(n.code,{children:"npm install --save single-spa@5.0.0"})," or ",(0,i.jsx)(n.code,{children:"yarn add single-spa@5.0.0"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["Alternatively, single-spa is available on ",(0,i.jsx)(n.a,{href:"https://cdnjs.com/libraries/single-spa",children:"cdnjs"}),", ",(0,i.jsx)(n.a,{href:"https://www.jsdelivr.com/package/npm/single-spa",children:"jsdelivr"}),", and ",(0,i.jsx)(n.a,{href:"https://unpkg.com/browse/single-spa/",children:"unpkg"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The single-spa core team is committed to treating our users well, which includes not introducing massive breaking changes. The core single-spa API has not seen massive breaking changes ",(0,i.jsx)(n.a,{href:"https://github.com/single-spa/single-spa/releases/tag/v3.0.0",children:"since single-spa@3 in August 2016"}),". We have added features and improved things, but single-spa is a stable technology. We are committed to maintaining it, documenting it, and adjusting it as technologies like in-browser modules become more and more popular and viable."]}),"\n",(0,i.jsx)(n.h2,{id:"performance-improvements",children:"Performance improvements"}),"\n",(0,i.jsx)(n.p,{children:"The ESM version of single-spa@4 was 23.8kb (7.2kb gzipped). That was improved in single-spa@5 to 15.5kb (5.1kb gzipped). We did this by optimizing our build process and removing unused features."}),"\n",(0,i.jsx)(n.h2,{id:"single-spa-cli",children:"single-spa CLI"}),"\n",(0,i.jsxs)(n.p,{children:["Since single-spa's inception, bundler configuration has been a huge source of user pain. We have heard this pain and implemented ",(0,i.jsx)(n.a,{href:"/docs/create-single-spa",children:"create-single-spa"}),", which creates (and sometimes can update) repositories that are ready to be used as single-spa microfrontends. For Angular and Vue, the official CLIs are used with a few extra plugins automatically installed. For React, a default webpack config with decent eslint / prettier defaults is set up."]}),"\n",(0,i.jsxs)(n.p,{children:["Additionally, we have added a lot of documentation for webpack in ",(0,i.jsx)(n.a,{href:"/docs/recommended-setup#build-tools-webpack--rollup",children:"The Recommended Setup"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"tutorial-videos",children:"Tutorial videos"}),"\n",(0,i.jsx)(n.p,{children:"We understand that single-spa is more than just a library - it is an architecture. The single-spa library itself is the core, but the surrounding ecosystem of concepts and libraries are equally important to successfully migrating to single-spa and having it work for you. As such, we have created a Youtube playlist, currently consisting of seven videos, to help you get started."}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://www.youtube.com/playlist?list=PLLUD8RtHvsAOhtHnyGx57EYXoaNsxGrTU",children:"Youtube playlist"})," / ",(0,i.jsx)(n.a,{href:"https://space.bilibili.com/495254378/video",children:"Bilibili space"})]}),"\n",(0,i.jsx)(n.p,{children:"The videos currently cover the following topics:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"What are Microfrontends?"}),"\n",(0,i.jsx)(n.li,{children:"In-browser vs build-time JavaScript modules"}),"\n",(0,i.jsx)(n.li,{children:"Import Maps"}),"\n",(0,i.jsx)(n.li,{children:"Local Development with single-spa and import maps"}),"\n",(0,i.jsx)(n.li,{children:"Deploying Microfrontends / Continuous Integration (CI)"}),"\n",(0,i.jsx)(n.li,{children:"SystemJS intro"}),"\n",(0,i.jsx)(n.li,{children:"Lazy Loading"}),"\n",(0,i.jsx)(n.li,{children:"Bundlers, webpack, and rollup."}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"new-example-repositories",children:"New example repositories"}),"\n",(0,i.jsxs)(n.p,{children:["What started out as Canopy Tax's special sauce for independently deployed frontend microservices is now fully accessible to the public with our ",(0,i.jsx)(n.a,{href:"/docs/examples",children:"new set of example repos"}),". We have a React example, a Vue example, and a polyglot (multiple framework) example. We hope to add an Angular example, after we achieve support for Angular 9. These example repositories are actively watched and maintained by the single-spa core team, and reflect our current opinions on the best, production-viable way to do microfrontends."]}),"\n",(0,i.jsx)(n.p,{children:"Furthermore, we have deployed each of the examples to our new domains:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://react.microfrontends.app",children:"https://react.microfrontends.app"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://polyglot.microfrontends.app",children:"https://polyglot.microfrontends.app"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://vue.microfrontends.app",children:"https://vue.microfrontends.app"})}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"documentation-overhaul",children:"Documentation overhaul"}),"\n",(0,i.jsx)(n.p,{children:"We removed several dated documentation pages, and added several that were very much lacking. Here are a few pages that give you the most bang for your buck:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"/docs/microfrontends-concept",children:"Concept: Microfrontend"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"/docs/recommended-setup",children:"The Recommended Setup"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"/docs/create-single-spa",children:"create-single-spa CLI"})}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"development-builds-and-error-codes",children:"Development builds and error codes"}),"\n",(0,i.jsxs)(n.p,{children:["Taking inspiration from the ",(0,i.jsx)(n.a,{href:"https://reactjs.org/docs/optimizing-performance.html#use-the-production-build",children:"react development and production builds"}),", we now publish to NPM both development and production builds in the following formats: UMD, ESM, and System.register."]}),"\n",(0,i.jsxs)(n.p,{children:["You can see the ",(0,i.jsx)(n.a,{href:"https://unpkg.com/browse/single-spa@5.0.0/lib/",children:"published build files here"}),". The ",(0,i.jsx)(n.code,{children:".dev.js"})," files provide full debugging information in the browser console, whereas the ",(0,i.jsx)(n.code,{children:".min.js"})," files give you a numeric error code and a link to a documentation page that explains the error. We hope that these error codes and documentation for them will improve discoverability of relevant documentation when you're setting up single-spa."]}),"\n",(0,i.jsxs)(n.p,{children:["An example of these new documentation pages for error codes is ",(0,i.jsx)(n.a,{href:"/error/?code=35&arg=application&arg=app1&arg=%7B%7D",children:"found here"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"governance",children:"Governance"}),"\n",(0,i.jsxs)(n.p,{children:["Some of you may have noticed that we recently moved all github repos from ",(0,i.jsx)(n.a,{href:"https://github.com/CanopyTax",children:"https://github.com/CanopyTax"})," to ",(0,i.jsx)(n.a,{href:"https://github.com/single-spa",children:"https://github.com/single-spa"}),". Canopy Tax was the company where single-spa was first authored, but as a core team we asked to move ownership and governance of the projects to an organization fully managed by the open source community. In agreement with Canopy, we made that change."]}),"\n",(0,i.jsx)(n.p,{children:"This change does not mean anything drastic for single-spa. Its license was and is MIT, and we have no plans to do anything with the project besides make it better."}),"\n",(0,i.jsx)(n.h2,{id:"where-next",children:"Where next?"}),"\n",(0,i.jsxs)(n.p,{children:["We are actively ",(0,i.jsx)(n.a,{href:"https://github.com/single-spa/zh-hans.single-spa.js.org",children:"translating the single-spa documentation to Chinese"}),", and hope to add other languages soon. We will add full ",(0,i.jsx)(n.a,{href:"https://github.com/single-spa/single-spa-angular/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+angular+9",children:"Angular 9 support"})," soon, and hope to add ",(0,i.jsx)(n.a,{href:"https://github.com/single-spa/single-spa/issues/103",children:"server rendering"})," in an upcoming release."]}),"\n",(0,i.jsxs)(n.p,{children:["Please ",(0,i.jsx)(n.a,{href:"/docs/contributing-overview",children:"contribute to our code"})," and ",(0,i.jsx)(n.a,{href:"/docs/ecosystem",children:"ecosystem"}),", ",(0,i.jsx)(n.a,{href:"https://join.slack.com/t/single-spa/shared_invite/zt-2uvhef42o-g4H3mvKDaenE9xVAewBKww",children:"join our single-spa slack channel"}),", ",(0,i.jsx)(n.a,{href:"https://twitter.com/Single_spa",children:"follow our official Twitter account"}),", and contribute to ",(0,i.jsx)(n.a,{href:"https://opencollective.com/single-spa",children:"our open collective"}),". The ",(0,i.jsx)(n.a,{href:"/contributors",children:"single-spa core team"})," all have full-time jobs and maintain this project on a volunteer basis."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>o});var i=s(6540);const t={},r=i.createContext(t);function a(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3827c3c6.c3037c1a.js b/assets/js/3827c3c6.f39d9452.js similarity index 99% rename from assets/js/3827c3c6.c3037c1a.js rename to assets/js/3827c3c6.f39d9452.js index a7ba635b5..1719144f7 100644 --- a/assets/js/3827c3c6.c3037c1a.js +++ b/assets/js/3827c3c6.f39d9452.js @@ -1 +1 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[1834],{188:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var s=i(4848),t=i(8453);const r={id:"getting-started-overview",title:"Getting Started with single-spa",sidebar_label:"Overview of single-spa"},o=void 0,a={id:"getting-started-overview",title:"Getting Started with single-spa",description:"JavaScript Microfrontends",source:"@site/versioned_docs/version-6.x/getting-started-overview.md",sourceDirName:".",slug:"/getting-started-overview",permalink:"/docs/getting-started-overview",draft:!1,unlisted:!1,editUrl:"https://github.com/single-spa/single-spa.js.org/blob/master/website/versioned_docs/version-6.x/getting-started-overview.md",tags:[],version:"6.x",frontMatter:{id:"getting-started-overview",title:"Getting Started with single-spa",sidebar_label:"Overview of single-spa"},sidebar:"docs",next:{title:"Resources",permalink:"/docs/examples"}},l={},d=[{value:"JavaScript Microfrontends",id:"javascript-microfrontends",level:2},{value:"Demos and Examples",id:"demos-and-examples",level:2},{value:"Architectural Overview",id:"architectural-overview",level:2},{value:"The Recommended Setup",id:"the-recommended-setup",level:2},{value:"How hard will it be to use single-spa?",id:"how-hard-will-it-be-to-use-single-spa",level:2},{value:"Isn't single-spa sort of a redundant name?",id:"isnt-single-spa-sort-of-a-redundant-name",level:2},{value:"Documentation",id:"documentation",level:2},{value:"Quick start",id:"quick-start",level:2},{value:"Create a root config",id:"create-a-root-config",level:3},{value:"Create a single-spa application",id:"create-a-single-spa-application",level:3},{value:"Add shared dependencies",id:"add-shared-dependencies",level:3},{value:"Register the application",id:"register-the-application",level:3},{value:"API",id:"api",level:2},{value:"Contributing",id:"contributing",level:2},{value:"Code of Conduct",id:"code-of-conduct",level:3},{value:"Contributing Guide",id:"contributing-guide",level:3},{value:"Who's Using This?",id:"whos-using-this",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h2:"h2",h3:"h3",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h2,{id:"javascript-microfrontends",children:"JavaScript Microfrontends"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"https://join.slack.com/t/single-spa/shared_invite/zt-2php1iewg-guIu7m9tRV0CjxluXqbCAg",children:"Join the chat on Slack"})}),"\n",(0,s.jsx)(n.p,{children:"single-spa is a framework for bringing together multiple JavaScript microfrontends in a frontend application. Architecting your frontend using single-spa enables many benefits, such as:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"/docs/ecosystem#help-for-frameworks",children:"Use multiple frameworks"})," on the same page ",(0,s.jsx)(n.a,{href:"/docs/building-applications",children:"without page refreshing"}),"\n(",(0,s.jsx)(n.a,{href:"/docs/ecosystem-react",children:"React"}),", ",(0,s.jsx)(n.a,{href:"/docs/ecosystem-angularjs",children:"AngularJS"}),", ",(0,s.jsx)(n.a,{href:"/docs/ecosystem-angular",children:"Angular"}),", ",(0,s.jsx)(n.a,{href:"/docs/ecosystem-ember",children:"Ember"}),", or whatever you're using)"]}),"\n",(0,s.jsx)(n.li,{children:"Deploy your microfrontends independently"}),"\n",(0,s.jsx)(n.li,{children:"Write code using a new framework, without rewriting your existing app"}),"\n",(0,s.jsx)(n.li,{children:"Lazy load code for improved initial load time"}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"demos-and-examples",children:"Demos and Examples"}),"\n",(0,s.jsxs)(n.p,{children:["See ",(0,s.jsx)(n.a,{href:"/docs/examples",children:"our examples page"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"architectural-overview",children:"Architectural Overview"}),"\n",(0,s.jsx)(n.p,{children:'single-spa takes inspiration from modern framework component lifecycles by abstracting lifecycles for entire applications.\nBorn out of Canopy\'s desire to use React + react-router instead of being forever stuck with our AngularJS + ui-router application, single-spa is now a mature library that enables frontend microservices architecture aka "microfrontends". Microfrontends enable many benefits such as independent deployments, migration and experimentation, and resilient applications.'}),"\n",(0,s.jsx)(n.p,{children:"single-spa apps consist of the following:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.a,{href:"configuration",children:"single-spa root config"}),", which renders the HTML page ",(0,s.jsx)(n.em,{children:"and"})," the JavaScript that registers applications. Each application is registered with three things:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"A name"}),"\n",(0,s.jsx)(n.li,{children:"A function to load the application's code"}),"\n",(0,s.jsx)(n.li,{children:"A function that determines when the application is active/inactive"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/docs/building-applications",children:"Applications"})," which can be thought of as single-page applications packaged up into modules. Each application must know how to bootstrap, mount, and unmount itself from the DOM. The main difference between a traditional SPA and single-spa applications is that they must be able to coexist with other applications as they do not each have their own HTML page."]}),"\n",(0,s.jsx)(n.p,{children:"For example, your React or Angular SPAs are applications. When active, they can listen to url routing events and put content on the DOM. When inactive, they do not listen to url routing events and are totally removed from the DOM."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"the-recommended-setup",children:"The Recommended Setup"}),"\n",(0,s.jsxs)(n.p,{children:["The single-spa core team has put together documentation, tools, and videos showing the currently encouraged best practices with single-spa. Check out ",(0,s.jsx)(n.a,{href:"/docs/recommended-setup/",children:"these docs"})," for more information."]}),"\n",(0,s.jsx)(n.h2,{id:"how-hard-will-it-be-to-use-single-spa",children:"How hard will it be to use single-spa?"}),"\n",(0,s.jsxs)(n.p,{children:["single-spa works with ES5, ES6+, TypeScript, Webpack, SystemJS, Gulp, Grunt, Bower, ember-cli, or really any build system available. You can npm install it or even just use a ",(0,s.jsx)(n.code,{children:" - - + +
Skip to main content

A Case for SOA in the Browser

· 6 min read

So you are a web-developer. You write a lot of JavaScript. You have a large single-page application (SPA) with features to add and bugs to maintain. Over time the application grows in size and complexity. It becomes more difficult to modify one portion of the SPA without breaking another portion.

@@ -43,6 +43,6 @@

Introducing

Obviously not all front-end code should be a service. Services have their own challenges. Specifically your code has to stay backwards compatible. But code can’t always be backwards compatible. Sometimes there needs to be breaking changes. The same problem exists for back-end services. A back-end API has to stay backwards compatible. Breaking changes on the back-end are generally solved by either creating an entirely new (versioned) API or implementing feature toggles within the API itself. The same solution applies to sofe services. An entirely new sofe service can be deployed or feature toggles can exist inside the front-end service. However it is solved, the key point is that services exist outside your application within their own distributable.

Another potential problem for sofe services is performance. Because they are loaded at run-time, performance can become a concern if you synchronously load too many services during bootstrap. Performance degradation can be mitigated by asynchronously loading larger services after the application bootstraps. Despite these challenges, there are many benefits to services on the front-end. The most exciting thing about sofe is there is now an option for services in the browser. You can decide what should and shouldn’t be a service.

Getting started with sofe requires only System.js. But to help you get started we have built sofe to work with a variety of technologies, including webpack, Babel, jspm, and the Chrome Developer Tools. Sofe is also actively used in production at Canopy Tax. We would love feedback on sofe and a number of open source projects that have been built around it. As you approach your next front-end project or look to improve your existing app, consider how it might benefit from service oriented architecture.

-

Read more about how to get started with sofe here.

+

Read more about how to get started with sofe here.

\ No newline at end of file diff --git a/blog/2016/12/16/a-step-by-step-guide-to-single-spa/index.html b/blog/2016/12/16/a-step-by-step-guide-to-single-spa/index.html index 465e4c229..cadf87466 100644 --- a/blog/2016/12/16/a-step-by-step-guide-to-single-spa/index.html +++ b/blog/2016/12/16/a-step-by-step-guide-to-single-spa/index.html @@ -14,8 +14,8 @@ - - + +
Skip to main content

A step-by-step guide to single-spa

· 10 min read

Running Angular 1, React, Angular 2, and Vue.js side by side sounds pretty cool. And it seems appealing to have multiple applications coexisting on the same page, each lazily loaded.

@@ -79,6 +79,6 @@

Step F

Conclusion

As you get your feet wet, you’ll probably run into some (hopefully small) hiccups setting things up. When this tutorial is not enough, there are other resources on Github and here in the docs.

Single-spa is still a relatively new thing, and we’d love to hear your feedback and questions. We welcome contributions from everyone.

-

If you’re excited about the possibilities, feel free to contact me on twitter (@joelbdenning). And if you are not excited, then still feel free to contact me, but only after you leave some nasty comments :)

+

If you’re excited about the possibilities, feel free to contact me on twitter (@joelbdenning). And if you are not excited, then still feel free to contact me, but only after you leave some nasty comments :)

\ No newline at end of file diff --git a/blog/2018/06/19/single-spa-parcels-explained/index.html b/blog/2018/06/19/single-spa-parcels-explained/index.html index 8f477bd5e..406afdf25 100644 --- a/blog/2018/06/19/single-spa-parcels-explained/index.html +++ b/blog/2018/06/19/single-spa-parcels-explained/index.html @@ -14,8 +14,8 @@ - - + +
Skip to main content

single-spa parcels, explained

· 4 min read

Ever since single-spa@1.0.0, the single-spa team has been dedicated to bringing microservices to the frontend. We have made it possible for AngularJS, React, Angular, Vue, and other frameworks to coexist side by side in the same page.

@@ -57,6 +57,6 @@

Let us know what you think!

We’d love to get your feedback on parcels. What do you think of this new way of framework interop? Is the implementation easy to understand? Are parcels useful for you or do they not quite fit into what you’re trying to accomplish?How hard was it for you to try out?

Check out the official docs for more examples, explanations, and api documentation.

-

And let us know your thoughts in the single-spa Slack channel, a Github issue, or on Twitter!

+

And let us know your thoughts in the single-spa Slack channel, a Github issue, or on Twitter!

\ No newline at end of file diff --git a/blog/2019/02/20/single-spa-inspector/index.html b/blog/2019/02/20/single-spa-inspector/index.html index 85f75fd5f..b55028845 100644 --- a/blog/2019/02/20/single-spa-inspector/index.html +++ b/blog/2019/02/20/single-spa-inspector/index.html @@ -14,8 +14,8 @@ - - + +
Skip to main content

single-spa Inspector and 4.1

· 2 min read

Background

@@ -42,6 +42,6 @@

single-spa 4.1

Help Wanted!

If you would like to suggest a new feature for single-spa Inspector, report a bug, improve our (admittedly horrible and hopefully temporary) UI/UX, or add features, please see the github repo and hack away!

We also hope to update some of our example repos to the lastest single-spa so that anyone with the extension installed can test out the features and see how to implement overlays. But this process will go faster if someone wants to help out. :)

-

Thank you!

+

Thank you!

\ No newline at end of file diff --git a/blog/2020/02/24/single-spa-5/index.html b/blog/2020/02/24/single-spa-5/index.html index 8d0e65cfa..4d7da7029 100644 --- a/blog/2020/02/24/single-spa-5/index.html +++ b/blog/2020/02/24/single-spa-5/index.html @@ -14,8 +14,8 @@ - - + +
Skip to main content
+

Please contribute to our code and ecosystem, join our single-spa slack channel, follow our official Twitter account, and contribute to our open collective. The single-spa core team all have full-time jobs and maintain this project on a volunteer basis.

\ No newline at end of file diff --git a/blog/2023/08/22/single-spa-core-is-expanding/index.html b/blog/2023/08/22/single-spa-core-is-expanding/index.html index a9f20a432..2f7c1b1b5 100644 --- a/blog/2023/08/22/single-spa-core-is-expanding/index.html +++ b/blog/2023/08/22/single-spa-core-is-expanding/index.html @@ -14,8 +14,8 @@ - - + +
Skip to main content

The single-spa core team is expanding

· 2 min read

We are happy to announce that the single-spa core team is opening applications for two new members! As a core team member, you will help us maintain and guide the growing single-spa ecosystem by responding to Github and Slack issues, implementing new features, and helping to create the roadmap for the future of single-spa.

@@ -23,6 +23,6 @@

Single-spa owes its success to the people and companies who support it. If you want to contribute but aren’t able to join the core team, consider applying to be a maintainer. Maintainers are volunteers who receive Github write access to specific subprojects within the ecosystem. If you’re a manager at a company that uses single-spa, we encourage you to allow your developers to volunteer their time as maintainers or core team members so that the project can continue to grow and develop.

The single-spa core team and maintenance are unpaid volunteer positions. Looking ahead, if any core team members or maintainers are interested in new paid roles, Convex Cooperative (the company Joel works for) will be considering hiring new developers from the single-spa team. It’s important to state that Convex will not poach developers away from companies who allow their developers to help us maintain single-spa—our priority is nurturing the growth and development of the single-spa ecosystem.

If interested in applying to be a single-spa maintainer or core team member, please fill out the following Google Form before September 1, 2023:

-

https://docs.google.com/forms/d/1zIfP2kYjNBCi-qjKf9T1-sNT1VLSXTB9twwX_mxKYxU/edit

+

https://docs.google.com/forms/d/1zIfP2kYjNBCi-qjKf9T1-sNT1VLSXTB9twwX_mxKYxU/edit

\ No newline at end of file diff --git a/blog/2023/10/11/introducing-single-spa-new-core-team-members/index.html b/blog/2023/10/11/introducing-single-spa-new-core-team-members/index.html index 842d3d5f5..63807fa0a 100644 --- a/blog/2023/10/11/introducing-single-spa-new-core-team-members/index.html +++ b/blog/2023/10/11/introducing-single-spa-new-core-team-members/index.html @@ -14,8 +14,8 @@ - - + +
Skip to main content

Introducing Single-Spa's New Core Team Members

· 2 min read

Please welcome the latest additions to the Single-Spa core team. These talented individuals bring fresh energy and a wealth of expertise and are poised to revitalize and expand the Single-Spa project.

@@ -28,6 +28,6 @@

Meet the Team<

Milan Kovacic is a seasoned software consultant with deep expertise in various development domains. On the frontend side, his work is marked by proficiency in React, TypeScript, and the integration of microfrontends. For backend solutions, he mostly relies on the .NET framework, C#—often utilizing microservices architecture. Additionally, Milan is experienced with cloud technologies, regularly working with platforms like AWS and Azure. Beyond traditional development, he places great emphasis on ensuring a smooth developer experience and promotes the use of automation and efficient DevOps practices to streamline development workflows.

These three new members will be joining current members Joel Denning, Carlos Filoteo, and Anthony Frehner to manage GitHub and Slack issues and actively develop new features. We’d also like to give special recognition to contributors from Qiankun for their extensive support over the years.

As part of this team update, we’ll also be creating a public roadmap, providing transparency about Single-Spa's future direction. To maintain transparency and encourage collaboration, we're establishing monthly meetings where the core team will discuss progress, challenges, and ideas. Meeting notes will be publicly available, ensuring that the community is well-informed and able to participate in our discussions.

-

So stay tuned and join us on this journey shaping the future of microfrontends.

+

So stay tuned and join us on this journey shaping the future of microfrontends.

\ No newline at end of file diff --git a/blog/2023/11/07/core-team-meeting-notes/index.html b/blog/2023/11/07/core-team-meeting-notes/index.html index 992848505..2dafa58e9 100644 --- a/blog/2023/11/07/core-team-meeting-notes/index.html +++ b/blog/2023/11/07/core-team-meeting-notes/index.html @@ -14,8 +14,8 @@ - - + +
Skip to main content

November 2023 Core Team Meeting

· One min read

Attendees: Joel Denning, Milan Kovacic, Jake Hayes

@@ -54,6 +54,6 @@

Roadmap B
  • Feature voting
  • Automated integration tests for popular frameworks
  • Update create-single-spa dependencies
  • -

    +
    \ No newline at end of file diff --git a/blog/2023/11/27/single-spa-6/index.html b/blog/2023/11/27/single-spa-6/index.html index 06126ab3b..3e9a6bb61 100644 --- a/blog/2023/11/27/single-spa-6/index.html +++ b/blog/2023/11/27/single-spa-6/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content

    single-spa 6

    · 10 min read

    We have released single-spa@6! The single-spa core team is committed to a stable single-spa runtime with very few breaking changes. We expect over 95% of single-spa users can upgrade easily without altering their changes!

    @@ -106,6 +106,6 @@

    MaintenanceUpgrade to new package names for all rollup plugins. (@rollup/plugin-node-resolve instead of rollup-plugin-node-resolve) Github link
  • Remove file size impact workflow since it's broken. by @joeldenning in #879
  • Remove console.log in test by @joeldenning in #878
  • -

    +
    \ No newline at end of file diff --git a/blog/2023/12/12/core-team-meeting-notes/index.html b/blog/2023/12/12/core-team-meeting-notes/index.html index 2a3e6bd34..1b1c8bf78 100644 --- a/blog/2023/12/12/core-team-meeting-notes/index.html +++ b/blog/2023/12/12/core-team-meeting-notes/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content

    December 2023 Core Team Meeting

    · One min read

    Attendees: Artur Androsovych, Ian Bacher, Jake Hayes, Milan Kovacic

    @@ -47,6 +47,6 @@

    Initia
  • Feature voting
  • Automated integration tests for popular frameworks
  • Update create-single-spa dependencies 🚧
  • -

    +
    \ No newline at end of file diff --git a/blog/2024/01/03/core-team-meeting-notes/index.html b/blog/2024/01/03/core-team-meeting-notes/index.html index 5a74db47f..d2163e9ff 100644 --- a/blog/2024/01/03/core-team-meeting-notes/index.html +++ b/blog/2024/01/03/core-team-meeting-notes/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content

    January 2024 Core Team Meeting

    · One min read

    Attendees: Joel Denning Jake Hayes, Milan Kovacic

    @@ -51,6 +51,6 @@

    Initia
  • Feature voting
  • Automated integration tests for popular frameworks
  • Update create-single-spa dependencies 🚧
  • -

    +
    \ No newline at end of file diff --git a/blog/2024/02/14/core-team-meeting-notes/index.html b/blog/2024/02/14/core-team-meeting-notes/index.html index 8f7adf064..784b04473 100644 --- a/blog/2024/02/14/core-team-meeting-notes/index.html +++ b/blog/2024/02/14/core-team-meeting-notes/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content

    February 2024 Core Team Meeting

    · One min read

    Attendees: Joel Denning, Milan Kovacic, Ian Bacher, Jake Hayes

    @@ -60,6 +60,6 @@

    Roadmap Items<

    Blog posts

    • Potentially adding Baseplate specific blog posts to single-spa
    • -
    +
    \ No newline at end of file diff --git a/blog/2024/03/12/core-team-meeting-notes/index.html b/blog/2024/03/12/core-team-meeting-notes/index.html index 5ba34bc65..d733370c8 100644 --- a/blog/2024/03/12/core-team-meeting-notes/index.html +++ b/blog/2024/03/12/core-team-meeting-notes/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content

    March 2024 Core Team Meeting

    · 2 min read

    Attendees: Joel Denning, Milan Kovacic

    @@ -37,6 +37,6 @@

    single-spa CL

    See single-spa issue 1205 for Milan's proposal. Joel has hesitations about abstracting away bundler config and configuration files, but we decided to proceed with Milan's proposal, since developer experience is one of the main barriers to entry for developers and corporations who are used to managed configuration in other projects (NextJS, Vite, etc etc). The main concern is how to do it in a way where single-spa users don't have to go digging in node_modules regularly to be able to do what they need to do to their projects.

    Shared dependencies management

    Baseplate Cloud plans to use JSPM CDN for native ES module shared dependencies. Managing the dependencies in the import map over time is important to do in a sensible way that avoids accidentally breaking production, while still allowing for incremental migration of dependencies on microfrontend at a time.

    -

    We didn't decide on anything concrete - just brainstormed solutions. Ideally the open source ecosystem can self-host shared dependencies as well.

    +

    We didn't decide on anything concrete - just brainstormed solutions. Ideally the open source ecosystem can self-host shared dependencies as well.

    \ No newline at end of file diff --git a/blog/2024/03/18/top-5-microfrontend-hosting-solutions/index.html b/blog/2024/03/18/top-5-microfrontend-hosting-solutions/index.html index 1d756a478..5b3b452ea 100644 --- a/blog/2024/03/18/top-5-microfrontend-hosting-solutions/index.html +++ b/blog/2024/03/18/top-5-microfrontend-hosting-solutions/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content

    Top 5 Microfrontend Hosting Solutions

    · 8 min read

    With rapid growth in recent years, microfrontends have become a popular solution with many companies, from large software organizations to small independent dev teams. Microfrontend hosting can get complicated quickly but it is a crucial aspect of scaling software organizations' development cycle. Whether companies are using single-spa, module federation, or any other microfrontends tools, the management of CI/CD pipelines, deployments, CDNs, and service discovery is something all companies will have to solve.

    @@ -67,6 +67,6 @@

    3. AWS

    4. GCP Storage + Cloud CDN

    Google Cloud Platform provides equivalent low-level cloud services to AWS. The same technical details that apply to AWS S3 + Cloudfront also apply to GCP Cloud Storage and GCP Cloud CDN.

    5. Azure Storage + CDN

    -

    Azure Storage provides equivalent low-level cloud services to AWS. The same technical details that apply to AWS S3 + Cloudfront also apply to Azure Storage and GCP Cloud CDN.

    +

    Azure Storage provides equivalent low-level cloud services to AWS. The same technical details that apply to AWS S3 + Cloudfront also apply to Azure Storage and GCP Cloud CDN.

    \ No newline at end of file diff --git a/blog/2024/04/10/core-team-meeting-notes/index.html b/blog/2024/04/10/core-team-meeting-notes/index.html index 17ba792f7..a2baffca1 100644 --- a/blog/2024/04/10/core-team-meeting-notes/index.html +++ b/blog/2024/04/10/core-team-meeting-notes/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content

    April 2024 Core Team Meeting

    · 2 min read

    Attendees: Ian, Milan Kovacic

    @@ -32,6 +32,6 @@

    https://github.com/single-spa/import-map-injector should be used, since it doesn't parse JS in the browser.

    Regarding shared dependencies, I think we should discuss whether to support self hosting or just JSPM proxies. I imagine some users will insist on self-hosting, which means we could check if JSPM is open source or if there is a similar tool for converting npm packages to ES modules.

    -

    Regarding module federation, I discussed it with Zack and module federation is still moving towards a runtime rather than native import maps. There might be possible collaboration on a service worker for module federation + native modules. I personally prefer no runtime whatsoever - just what the browser natively supports.

    +

    Regarding module federation, I discussed it with Zack and module federation is still moving towards a runtime rather than native import maps. There might be possible collaboration on a service worker for module federation + native modules. I personally prefer no runtime whatsoever - just what the browser natively supports.

    \ No newline at end of file diff --git a/blog/2024/06/08/core-team-meeting-notes/index.html b/blog/2024/06/08/core-team-meeting-notes/index.html index 6c1eb50d4..65fd79dfd 100644 --- a/blog/2024/06/08/core-team-meeting-notes/index.html +++ b/blog/2024/06/08/core-team-meeting-notes/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    +
    \ No newline at end of file diff --git a/blog/2024/09/30/core-team-meeting-notes/index.html b/blog/2024/09/30/core-team-meeting-notes/index.html index 8d0bfc6f4..49728adab 100644 --- a/blog/2024/09/30/core-team-meeting-notes/index.html +++ b/blog/2024/09/30/core-team-meeting-notes/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content

    September 2024 Core Team Meeting

    · One min read

    Held via Slack

    @@ -42,6 +42,6 @@

    Meeting Agend
  • Develop a new project or extend and existing one (like jspm) that assembles the files needed for self-hosting esm shared dependencies, and create all the CI/CD tooling necessary to upload the files to a corporate CDN.
  • -

    +
    \ No newline at end of file diff --git a/blog/archive/index.html b/blog/archive/index.html index b7a57a7ed..c375b1686 100644 --- a/blog/archive/index.html +++ b/blog/archive/index.html @@ -14,10 +14,10 @@ - - + + -
    Skip to main content

    Archive

    Archive

    +
    Skip to main content

    Archive

    Archive

    \ No newline at end of file diff --git a/blog/atom.xml b/blog/atom.xml index 1214c95e2..22f57283f 100644 --- a/blog/atom.xml +++ b/blog/atom.xml @@ -542,7 +542,7 @@

    This change does not mean anything drastic for single-spa. Its license was and is MIT, and we have no plans to do anything with the project besides make it better.

    Where next?

    We are actively translating the single-spa documentation to Chinese, and hope to add other languages soon. We will add full Angular 9 support soon, and hope to add server rendering in an upcoming release.

    -

    Please contribute to our code and ecosystem, join our single-spa slack channel, follow our official Twitter account, and contribute to our open collective. The single-spa core team all have full-time jobs and maintain this project on a volunteer basis.

    ]]> +

    Please contribute to our code and ecosystem, join our single-spa slack channel, follow our official Twitter account, and contribute to our open collective. The single-spa core team all have full-time jobs and maintain this project on a volunteer basis.

    ]]> Joel Denning https://twitter.com/joelbdenning @@ -629,7 +629,7 @@

    Let us know what you think!

    We’d love to get your feedback on parcels. What do you think of this new way of framework interop? Is the implementation easy to understand? Are parcels useful for you or do they not quite fit into what you’re trying to accomplish?How hard was it for you to try out?

    Check out the official docs for more examples, explanations, and api documentation.

    -

    And let us know your thoughts in the single-spa Slack channel, a Github issue, or on Twitter!

    ]]> +

    And let us know your thoughts in the single-spa Slack channel, a Github issue, or on Twitter!

    ]]> Joel Denning https://twitter.com/joelbdenning diff --git a/blog/index.html b/blog/index.html index 5314c00fa..e8fad35df 100644 --- a/blog/index.html +++ b/blog/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/blog/page/2/index.html b/blog/page/2/index.html index 568c5b8c0..ab74e1ecd 100644 --- a/blog/page/2/index.html +++ b/blog/page/2/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content

    · 2 min read

    Please welcome the latest additions to the Single-Spa core team. These talented individuals bring fresh energy and a wealth of expertise and are poised to revitalize and expand the Single-Spa project.

    @@ -91,7 +91,7 @@

    GovernanceThis change does not mean anything drastic for single-spa. Its license was and is MIT, and we have no plans to do anything with the project besides make it better.

    Where next?

    We are actively translating the single-spa documentation to Chinese, and hope to add other languages soon. We will add full Angular 9 support soon, and hope to add server rendering in an upcoming release.

    -

    Please contribute to our code and ecosystem, join our single-spa slack channel, follow our official Twitter account, and contribute to our open collective. The single-spa core team all have full-time jobs and maintain this project on a volunteer basis.

    · 2 min read

    Background

    For a long time, Canopy has had the benefit of using a tool called sofe inspector (note: this is an out-of-date version of it) to list, override, and interact with single-spa applications. There has always been a desire to figure out how to share this tool so others can benefit as well.

    With that in mind, I'm proud to announce an initial release for single-spa Inspector! single-spa Inspector is a Firefox and Chrome extension, much like React/Vue devtools, that allows you see and interact with your single-spa applications and configuration.

    Current Inspector Features

    @@ -154,7 +154,7 @@

    Let us know what you think!

    We’d love to get your feedback on parcels. What do you think of this new way of framework interop? Is the implementation easy to understand? Are parcels useful for you or do they not quite fit into what you’re trying to accomplish?How hard was it for you to try out?

    Check out the official docs for more examples, explanations, and api documentation.

    -

    And let us know your thoughts in the single-spa Slack channel, a Github issue, or on Twitter!

    · 10 min read

    Running Angular 1, React, Angular 2, and Vue.js side by side sounds pretty cool. And it seems appealing to have multiple applications coexisting on the same page, each lazily loaded.

    But using single-spa for the first time can be tricky because you’ll come across terms like “application lifecycles”, “root application”, “loading function”, “child application”, and “activity function.”

    This blog post will take you through setting things up and what choices you have when using single-spa. It’s based on what I’ve seen at Canopy Tax where we went from an Angular 1 monolith to an Angular 1, React, and Svelte polyglot.

    If you’d like to jump straight to a fully working, self contained code example, check out this webpack single-spa starter project.

    @@ -240,6 +240,6 @@

    Introducing

    Obviously not all front-end code should be a service. Services have their own challenges. Specifically your code has to stay backwards compatible. But code can’t always be backwards compatible. Sometimes there needs to be breaking changes. The same problem exists for back-end services. A back-end API has to stay backwards compatible. Breaking changes on the back-end are generally solved by either creating an entirely new (versioned) API or implementing feature toggles within the API itself. The same solution applies to sofe services. An entirely new sofe service can be deployed or feature toggles can exist inside the front-end service. However it is solved, the key point is that services exist outside your application within their own distributable.

    Another potential problem for sofe services is performance. Because they are loaded at run-time, performance can become a concern if you synchronously load too many services during bootstrap. Performance degradation can be mitigated by asynchronously loading larger services after the application bootstraps. Despite these challenges, there are many benefits to services on the front-end. The most exciting thing about sofe is there is now an option for services in the browser. You can decide what should and shouldn’t be a service.

    Getting started with sofe requires only System.js. But to help you get started we have built sofe to work with a variety of technologies, including webpack, Babel, jspm, and the Chrome Developer Tools. Sofe is also actively used in production at Canopy Tax. We would love feedback on sofe and a number of open source projects that have been built around it. As you approach your next front-end project or look to improve your existing app, consider how it might benefit from service oriented architecture.

    -

    Read more about how to get started with sofe here.

    +

    Read more about how to get started with sofe here.

    \ No newline at end of file diff --git a/blog/rss.xml b/blog/rss.xml index ac6afda5a..ece98f772 100644 --- a/blog/rss.xml +++ b/blog/rss.xml @@ -539,7 +539,7 @@

    This change does not mean anything drastic for single-spa. Its license was and is MIT, and we have no plans to do anything with the project besides make it better.

    Where next?

    We are actively translating the single-spa documentation to Chinese, and hope to add other languages soon. We will add full Angular 9 support soon, and hope to add server rendering in an upcoming release.

    -

    Please contribute to our code and ecosystem, join our single-spa slack channel, follow our official Twitter account, and contribute to our open collective. The single-spa core team all have full-time jobs and maintain this project on a volunteer basis.

    ]]> +

    Please contribute to our code and ecosystem, join our single-spa slack channel, follow our official Twitter account, and contribute to our open collective. The single-spa core team all have full-time jobs and maintain this project on a volunteer basis.

    ]]> <![CDATA[single-spa Inspector and 4.1]]> @@ -618,7 +618,7 @@

    Let us know what you think!

    We’d love to get your feedback on parcels. What do you think of this new way of framework interop? Is the implementation easy to understand? Are parcels useful for you or do they not quite fit into what you’re trying to accomplish?How hard was it for you to try out?

    Check out the official docs for more examples, explanations, and api documentation.

    -

    And let us know your thoughts in the single-spa Slack channel, a Github issue, or on Twitter!

    ]]> +

    And let us know your thoughts in the single-spa Slack channel, a Github issue, or on Twitter!

    ]]>
    <![CDATA[A step-by-step guide to single-spa]]> diff --git a/code-of-conduct/index.html b/code-of-conduct/index.html index 73e82efb9..7c880e30c 100644 --- a/code-of-conduct/index.html +++ b/code-of-conduct/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content

    single-spa Code of Conduct

    @@ -57,6 +57,6 @@

    Direct Messa

    Direct messages with others within single-spa spaces should remain appropriate. Communication in single-spa related online spaces should aim to be safe for software developers of any age.

    Reporting and Arbitration

    To report harassment, contact a single-spa core team member, community manager, or single-spa's creator. This can be done in Slack, over email (singlespa.info@gmail.com or joeldenning@gmail.com), or send a DM to a single-spa social media account.

    -

    Single-spa's creator and community managers will review the report. Witnesses or experts who can help understand the situation may be brought in to evaluate the situation. Community members found to have harassed or discriminated against another member may be warned, limited, or banned. To the extent possible, the single-spa community aims to be a safe place.

    +

    Single-spa's creator and community managers will review the report. Witnesses or experts who can help understand the situation may be brought in to evaluate the situation. Community members found to have harassed or discriminated against another member may be warned, limited, or banned. To the extent possible, the single-spa community aims to be a safe place.

    \ No newline at end of file diff --git a/contributors/index.html b/contributors/index.html index 0eefbb180..6fe24e331 100644 --- a/contributors/index.html +++ b/contributors/index.html @@ -14,10 +14,10 @@ - - + + - + \ No newline at end of file diff --git a/docs/4.x/api/index.html b/docs/4.x/api/index.html index 5009bf4a5..b11364def 100644 --- a/docs/4.x/api/index.html +++ b/docs/4.x/api/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 4.x

    Applications API

    single-spa exports named functions and variables rather than a single default export. @@ -175,6 +175,6 @@

    before-fi

    first-mount

    window.addEventListener("single-spa:first-mount", () => {
    console.log("single-spa just mounted the very first application");
    });

    After the first of any single-spa applications is mounted, single-spa fires a single-spa:first-mount event; therefore it will only be fired once ever.

    -
    Suggested use case:

    log the time it took before the user sees any of the apps mounted.

    +
    Suggested use case:

    log the time it took before the user sees any of the apps mounted.

    \ No newline at end of file diff --git a/docs/4.x/building-applications/index.html b/docs/4.x/building-applications/index.html index 678f4925d..616548d39 100644 --- a/docs/4.x/building-applications/index.html +++ b/docs/4.x/building-applications/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 4.x

    Building single-spa applications

    A single-spa registered application is everything that a normal SPA is, except that it doesn't have an HTML page. In a single-spa world, your SPA contains many registered applications, where each has its own framework. Registered applications have their own client-side routing and their own frameworks/libraries. They render their own HTML and have full freedom to do whatever they want, whenever they are mounted. The concept of being mounted refers to whether a registered application is putting content on the DOM or not. What determines if a registered application is mounted is its activity function. Whenever a registered application is not mounted, it should remain completely dormant until mounted.

    @@ -81,6 +81,6 @@

    Timeouts
    app-1.js
    export function bootstrap(props) {...}
    export function mount(props) {...}
    export function unmount(props) {...}

    export const timeouts = {
    bootstrap: {
    millis: 5000,
    dieOnTimeout: true,
    },
    mount: {
    millis: 5000,
    dieOnTimeout: false,
    },
    unmount: {
    millis: 5000,
    dieOnTimeout: true,
    },
    unload: {
    millis: 5000,
    dieOnTimeout: true,
    },
    };

    Transitioning between applications

    If you find yourself wanting to add transitions as applications are mounted and unmounted, then you'll probably want to tie into the bootstrap, mount, and unmount lifecycle methods. This single-spa transitions repo is a small proof-of-concept of how you can tie into these lifecycle methods to add transitions as your apps mount and unmount.

    -

    Transitions for pages within a mounted application can be handled entirely by the application itself. For example, using react-transition-group for React-based projects.

    +

    Transitions for pages within a mounted application can be handled entirely by the application itself. For example, using react-transition-group for React-based projects.

    \ No newline at end of file diff --git a/docs/4.x/code-of-conduct/index.html b/docs/4.x/code-of-conduct/index.html index d8f7e53b8..14f71db6c 100644 --- a/docs/4.x/code-of-conduct/index.html +++ b/docs/4.x/code-of-conduct/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 4.x

    Code of Conduct

    This code of conduct outlines our expectations for participants within the single-spa community, as well as steps to reporting unacceptable behavior. We are committed to providing a welcoming and inspiring community for all and expect our code of conduct to be honored. Anyone who violates this code of conduct may be banned from the community.

    @@ -53,6 +53,6 @@

    Reporting I

    After filing a report, a representative will contact you personally. If the person who is harassing you is part of the response team, they will recuse themselves from handling your incident. A representative will then review the incident, follow up with any additional questions, and make a decision as to how to respond. We will respect confidentiality requests for the purpose of protecting victims of abuse.

    Anyone asked to stop unacceptable behavior is expected to comply immediately. If an individual engages in unacceptable behavior, the representative may take any action they deem appropriate, up to and including a permanent ban from our community without warning.

    -

    This Code Of Conduct follows the template established by the TODO Group.

    +

    This Code Of Conduct follows the template established by the TODO Group.

    \ No newline at end of file diff --git a/docs/4.x/configuration/index.html b/docs/4.x/configuration/index.html index 0bbda9fce..3c4db9826 100644 --- a/docs/4.x/configuration/index.html +++ b/docs/4.x/configuration/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 4.x

    Configuring single-spa

    The single-spa root config consists of the following:

    @@ -74,6 +74,6 @@

    Calli

    Two registered applications simultaneously??

    Yep, it's possible. And it's actually not that scary if you do it right. And once you do, it's really really powerful. One approach to do this is to create a <div id="app-name"></div> for each app, -so that they never try to modify the same DOM at the same time.

    +so that they never try to modify the same DOM at the same time.

    \ No newline at end of file diff --git a/docs/4.x/contributing-overview/index.html b/docs/4.x/contributing-overview/index.html index 43d31dd5e..8a5bcda6f 100644 --- a/docs/4.x/contributing-overview/index.html +++ b/docs/4.x/contributing-overview/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 4.x

    Contributing to Single-spa

    Thanks for checking out single-spa! We're excited to hear and learn from you.

    @@ -85,7 +85,7 @@

    Push itCommunity

    -

    Discussions about single-spa take place on the single-spa repository's Issues and Pull Requests sections. Anybody is welcome to join these conversations. There is also a slack community for regular updates.

    -

    Wherever possible, do not take these conversations to private channels, including contacting the maintainers directly. Keeping communication public means everybody can benefit and learn from the conversation.

    +

    Discussions about single-spa take place on the single-spa repository's Issues and Pull Requests sections. Anybody is welcome to join these conversations. There is also a slack community for regular updates.

    +

    Wherever possible, do not take these conversations to private channels, including contacting the maintainers directly. Keeping communication public means everybody can benefit and learn from the conversation.

    \ No newline at end of file diff --git a/docs/4.x/ecosystem-angular/index.html b/docs/4.x/ecosystem-angular/index.html index d567bc548..325909862 100644 --- a/docs/4.x/ecosystem-angular/index.html +++ b/docs/4.x/ecosystem-angular/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 4.x

    single-spa-angular

    Introduction

    @@ -25,7 +25,7 @@ web page where one or more single-spa applications is active at any time.

    The documentation here is extensive, so use the sidenav on the right. 👉👉👉

    Community

    -

    Join the #angular channel in single-spa's Slack workspace.

    +

    Join the #angular channel in single-spa's Slack workspace.

    Demo

    https://coexisting-angular-microfrontends.surge.sh

    Starter repo

    @@ -276,6 +276,6 @@

    Internet E
  • Remove arrow functions from index.html (example)
  • Change angular.json target to es5 (example)
  • -

    Full example commit to get IE11 support

    +

    Full example commit to get IE11 support

    \ No newline at end of file diff --git a/docs/4.x/ecosystem-angularjs/index.html b/docs/4.x/ecosystem-angularjs/index.html index 33f1308bd..b2b9dba08 100644 --- a/docs/4.x/ecosystem-angularjs/index.html +++ b/docs/4.x/ecosystem-angularjs/index.html @@ -14,8 +14,8 @@ - - + + +

    Check out this example repo

    \ No newline at end of file diff --git a/docs/4.x/ecosystem-backbone/index.html b/docs/4.x/ecosystem-backbone/index.html index 0ff6b2d27..258072cc8 100644 --- a/docs/4.x/ecosystem-backbone/index.html +++ b/docs/4.x/ecosystem-backbone/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 4.x

    single-spa-backbone

    A single-spa helper library which provides lifecycle events for building single-spa applications using Backbone.

    @@ -82,6 +82,6 @@

    OptionsNote : Out of AppWithRequire, AppWithBackboneJs and App only one is required

    • DomElementSetter (optional) : This is an optional parameter and can be mostly used to create a dom element, whose id can be later used in the backbone app to load the application. However, you can freely use this callback for any other purpose. It is called before anything else.
    • -
    + \ No newline at end of file diff --git a/docs/4.x/ecosystem-cycle/index.html b/docs/4.x/ecosystem-cycle/index.html index 707c38096..01bbe398e 100644 --- a/docs/4.x/ecosystem-cycle/index.html +++ b/docs/4.x/ecosystem-cycle/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/docs/4.x/ecosystem-ember/index.html b/docs/4.x/ecosystem-ember/index.html index a8c134b8f..2e124e142 100644 --- a/docs/4.x/ecosystem-ember/index.html +++ b/docs/4.x/ecosystem-ember/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 4.x

    single-spa-ember

    single-spa-ember is a helper library that helps implement single-spa registered application lifecycle functions (bootstrap, mount and unmount) for for use with Ember.js. Check out the single-spa-ember github.

    @@ -55,6 +55,6 @@

    Usage w

    In your single-spa root application (which is separate from anything generated by ember cli):

    // root-application.js
    import * as singleSpa from "single-spa";
    import { loadEmberApp } from "single-spa-ember";

    singleSpa.registerApplication("ember-app", loadingFunction, activityFunction);

    function activityFunction(location) {
    // Only render the ember app when the url hash starts with ember
    return location.hash.startsWith("ember");
    }

    // single-spa-ember helps us load the script tags and give the ember app module to single-spa.
    function loadingFunction() {
    const appName = "ember-app";
    const appUrl = "/dist/ember-app/assets/ember-app.js";
    const vendorUrl = "/dist/ember-app/assets/vendor.js"; // Optional if you have one vendor bundle used for many different ember apps
    return loadEmberApp(appName, appUrl, vendorUrl);
    }

    In your app.js file (that is generated by ember cli)

    -
    // app.js (the ember application)
    import Ember from "ember";
    import Resolver from "./resolver";
    import loadInitializers from "ember-load-initializers";
    import config from "./config/environment";
    import singleSpaEmber from "single-spa-ember";

    // This part is generated by the ember cli
    const App = Ember.Application.extend({
    modulePrefix: config.modulePrefix,
    podModulePrefix: config.podModulePrefix,
    Resolver,
    });

    loadInitializers(App, config.modulePrefix);

    export default App;

    // This is the single-spa part
    const emberLifecycles = singleSpaEmber({
    App, // required
    appName: "ember-app", // required
    createOpts: {
    // optional
    rootElement: "#ember-app",
    },
    });

    // Single-spa lifecycles.
    export const bootstrap = emberLifecycles.bootstrap;
    export const mount = emberLifecycles.mount;
    export const unmount = emberLifecycles.unmount;

    +
    // app.js (the ember application)
    import Ember from "ember";
    import Resolver from "./resolver";
    import loadInitializers from "ember-load-initializers";
    import config from "./config/environment";
    import singleSpaEmber from "single-spa-ember";

    // This part is generated by the ember cli
    const App = Ember.Application.extend({
    modulePrefix: config.modulePrefix,
    podModulePrefix: config.podModulePrefix,
    Resolver,
    });

    loadInitializers(App, config.modulePrefix);

    export default App;

    // This is the single-spa part
    const emberLifecycles = singleSpaEmber({
    App, // required
    appName: "ember-app", // required
    createOpts: {
    // optional
    rootElement: "#ember-app",
    },
    });

    // Single-spa lifecycles.
    export const bootstrap = emberLifecycles.bootstrap;
    export const mount = emberLifecycles.mount;
    export const unmount = emberLifecycles.unmount;
    \ No newline at end of file diff --git a/docs/4.x/ecosystem-html-web-components/index.html b/docs/4.x/ecosystem-html-web-components/index.html index a3949fae7..020647de6 100644 --- a/docs/4.x/ecosystem-html-web-components/index.html +++ b/docs/4.x/ecosystem-html-web-components/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/docs/4.x/ecosystem-inferno/index.html b/docs/4.x/ecosystem-inferno/index.html index 09e856aa3..0bd1d9db9 100644 --- a/docs/4.x/ecosystem-inferno/index.html +++ b/docs/4.x/ecosystem-inferno/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/docs/4.x/ecosystem-leaked-globals/index.html b/docs/4.x/ecosystem-leaked-globals/index.html index 6cce2a3bf..2f9786e3e 100644 --- a/docs/4.x/ecosystem-leaked-globals/index.html +++ b/docs/4.x/ecosystem-leaked-globals/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/docs/4.x/ecosystem-preact/index.html b/docs/4.x/ecosystem-preact/index.html index 49c17059a..2e04370f6 100644 --- a/docs/4.x/ecosystem-preact/index.html +++ b/docs/4.x/ecosystem-preact/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/docs/4.x/ecosystem-react/index.html b/docs/4.x/ecosystem-react/index.html index c15e0ae62..15375abc2 100644 --- a/docs/4.x/ecosystem-react/index.html +++ b/docs/4.x/ecosystem-react/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 4.x

    single-spa-react

    Build Status

    @@ -70,6 +70,6 @@

    Parcel propsExamples

    import Parcel from 'single-spa-react/parcel'
    import * as parcelConfig from './my-parcel.js'

    // config is required. The parcel will be mounted inside of the
    // of a div inside of the react component tree
    <Parcel
    config={parcelConfig}

    wrapWith="div"
    handleError={err => console.error(err)}

    customProp1="customPropValue2"
    customProp2="customPropValue2"
    />

    // If you pass in an appendTo prop, the parcel will be mounted there instead of
    // to a dom node inside of the current react component tree
    <Parcel>
    config={parcelConfig}
    wrapWith="div"
    appendTo={document.body}
    />

    // You can also pass in a "loading function" as the config.
    // The loading function must return a promise that resolves with the parcel config.
    // The parcel will be mounted once the promise resolves.
    <Parcel
    config={() => import('./my-parcel.js')}
    wrapWith="div"
    />

    // If you are rendering the Parcel component from a single-spa application, you do not need to pass a mountParcel prop.
    // But if you have a separate react component tree that is not rendered by single-spa-react, you **must** pass in a mountParcel prop
    // In general, it is preferred to use an application's mountParcel function instead of the single-spa's root mountParcel function,
    // so that single-spa can keep track of the parent-child relationship and automatically unmount the application's parcels when the application
    // unmounts
    <Parcel
    mountParcel={singleSpa.mountParcel}
    config={parcelConfig}
    wrapWith="div"
    />

    Create React App

    -

    See FAQ for CRA

    +

    See FAQ for CRA

    \ No newline at end of file diff --git a/docs/4.x/ecosystem-riot/index.html b/docs/4.x/ecosystem-riot/index.html index 07746dc2e..086f4530e 100644 --- a/docs/4.x/ecosystem-riot/index.html +++ b/docs/4.x/ecosystem-riot/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/docs/4.x/ecosystem-svelte/index.html b/docs/4.x/ecosystem-svelte/index.html index 07e6b8c3e..843adee8f 100644 --- a/docs/4.x/ecosystem-svelte/index.html +++ b/docs/4.x/ecosystem-svelte/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 4.x

    single-spa-svelte

    single-spa-svelte is a helper library that helps implement single-spa registered application lifecycle functions (bootstrap, mount and unmount) for for use with svelte. Check out the single-spa-svelte github.

    @@ -34,6 +34,6 @@

    OptionsCreating a component documentation
  • intro: (optional) If true, will play transitions on initial render, rather than waiting for subsequent state changes
  • props: (optional) An object of properties to supply to the component
  • -

    + \ No newline at end of file diff --git a/docs/4.x/ecosystem-vue/index.html b/docs/4.x/ecosystem-vue/index.html index f9549cfd1..2f06b5a13 100644 --- a/docs/4.x/ecosystem-vue/index.html +++ b/docs/4.x/ecosystem-vue/index.html @@ -14,8 +14,8 @@ - - + + +for more information on appOptions.data.

    \ No newline at end of file diff --git a/docs/4.x/ecosystem/index.html b/docs/4.x/ecosystem/index.html index c1c408a33..d47e68959 100644 --- a/docs/4.x/ecosystem/index.html +++ b/docs/4.x/ecosystem/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 4.x

    The single-spa ecosystem

    The single-spa ecosystem is quickly growing to support as many frameworks and build tools as possible.

    @@ -49,6 +49,6 @@

    SystemJSWebpack 1

    With webpack 1, there is no support for Promise-based code splitting. Instead, we have to either wrap a require.ensure in a Promise, or just give up on lazy loading completely.

    -
    import { registerApplication } from "single-spa";
    import app1 from "./app1"; // Not lazy loading with code splitting :(

    // Giving up on lazy loading and code splitting :(
    registerApplication("app-1", () => Promise.resolve(app1), activeWhen);

    // Still doing code splitting! But verbose :(
    registerApplication("app-2", app2InPromise, activeWhen);

    /* Unfortunately, this logic cannot be abstracted into a generic
    * function that handles wrapping require.ensure in a promise for
    * any dynamically imported module. This is because webpack needs to
    * be able to statically analyze the code and find all of the require.ensure
    * calls at build-time, so you can't pass variables into require.ensure.
    */
    function app2InPromise() {
    return new Promise((resolve, reject) => {
    require.ensure(["./app-2.js"], (require) => {
    try {
    resolve(require("./app-2.js"));
    } catch (err) {
    reject(err);
    }
    });
    });
    }

    function activeWhen() {
    return window.location.pathname.indexOf("/my-app") === 0;
    }
    +
    import { registerApplication } from "single-spa";
    import app1 from "./app1"; // Not lazy loading with code splitting :(

    // Giving up on lazy loading and code splitting :(
    registerApplication("app-1", () => Promise.resolve(app1), activeWhen);

    // Still doing code splitting! But verbose :(
    registerApplication("app-2", app2InPromise, activeWhen);

    /* Unfortunately, this logic cannot be abstracted into a generic
    * function that handles wrapping require.ensure in a promise for
    * any dynamically imported module. This is because webpack needs to
    * be able to statically analyze the code and find all of the require.ensure
    * calls at build-time, so you can't pass variables into require.ensure.
    */
    function app2InPromise() {
    return new Promise((resolve, reject) => {
    require.ensure(["./app-2.js"], (require) => {
    try {
    resolve(require("./app-2.js"));
    } catch (err) {
    reject(err);
    }
    });
    });
    }

    function activeWhen() {
    return window.location.pathname.indexOf("/my-app") === 0;
    }
    \ No newline at end of file diff --git a/docs/4.x/examples/index.html b/docs/4.x/examples/index.html index c0e6507e8..a2a2e202d 100644 --- a/docs/4.x/examples/index.html +++ b/docs/4.x/examples/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 4.x

    Single-spa Examples

    There are a variety of single-spa example repositories, each for different use cases:

    @@ -29,6 +29,6 @@
  • single-spa-parcel-example is an example of one Vue and one React microfrontend, containing a React and a Vue parcel respectively and two Node.js microservices running in 6 different Docker VMs seamlessly working together in a single web app located in a 7th VM.
  • single-spa-login-example-with-npm-packages is a single-spa application example which imports registered applications from NPM packages and manages authentication features as login.
  • -

    Have your own starter repo? Submit a PR to add yours to this list.

    +

    Have your own starter repo? Submit a PR to add yours to this list.

    \ No newline at end of file diff --git a/docs/4.x/faq/index.html b/docs/4.x/faq/index.html index ac395103a..a21420c3c 100644 --- a/docs/4.x/faq/index.html +++ b/docs/4.x/faq/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/docs/4.x/getting-started-overview/index.html b/docs/4.x/getting-started-overview/index.html index b36de8db7..95d471b68 100644 --- a/docs/4.x/getting-started-overview/index.html +++ b/docs/4.x/getting-started-overview/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 4.x

    Getting Started with single-spa

    JavaScript Microfrontends

    @@ -97,6 +97,6 @@

    contributing guide to learn about our development process, how to propose bugfixes and improvements, and how to build and test your changes to single-spa.

    Who's Using This?

    See user showcase.

    -

    Is your company or project using single-spa? Let us know by submitting a PR to this section!

    +

    Is your company or project using single-spa? Let us know by submitting a PR to this section!

    \ No newline at end of file diff --git a/docs/4.x/glossary/index.html b/docs/4.x/glossary/index.html index bbcd562a6..3dd0c4f83 100644 --- a/docs/4.x/glossary/index.html +++ b/docs/4.x/glossary/index.html @@ -14,10 +14,10 @@ - - + + -
    Skip to main content
    Version: 4.x

    Glossary

    Activity Function
    Application
    Application
    Helpers
    are a library that already implements single-spa lifecycle functions for a specific framework.
    Lifecycles
    module loader
    Microservices
    registerApplication
    +
    Skip to main content
    Version: 4.x

    Glossary

    Activity Function
    Application
    Application
    Helpers
    are a library that already implements single-spa lifecycle functions for a specific framework.
    Lifecycles
    module loader
    Microservices
    registerApplication
    \ No newline at end of file diff --git a/docs/4.x/migrating-angularJS-tutorial/index.html b/docs/4.x/migrating-angularJS-tutorial/index.html index a5e392561..c45c51677 100644 --- a/docs/4.x/migrating-angularJS-tutorial/index.html +++ b/docs/4.x/migrating-angularJS-tutorial/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 4.x

    Migrating an Existing AngularJS Project

    Project Setup

    @@ -81,6 +81,6 @@

    c) Crea

    That's it

    Head back to the console and start up the server on http://localhost:8080 by running grunt from the root directory.

    Inspect the page and notice that our drum-machine app is now being rendered inside of the <div id="drum-machine"/> we created. Technically, we are back to square one, with a fully functioning SPA. However, now that our SPA is a registered single-spa application we can take advantage of single-spa's functionality by building additional applications to mount side by side with our current AngularJS SPA.

    -

    Feel free to start using that new JavaScript framework everyone has been talking about.

    +

    Feel free to start using that new JavaScript framework everyone has been talking about.

    \ No newline at end of file diff --git a/docs/4.x/migrating-existing-spas/index.html b/docs/4.x/migrating-existing-spas/index.html index 9863cd5cd..a3444719c 100644 --- a/docs/4.x/migrating-existing-spas/index.html +++ b/docs/4.x/migrating-existing-spas/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 4.x

    Migrating existing SPAs

    If you're interested in migrating existing SPAs into a single-spa, you'll @@ -45,6 +45,6 @@

    application. It is best to try to put all that you can into the JavaScript bundle, but your escape hatch is to put the things -you need into your single spa config.

    +you need into your single spa config.

    \ No newline at end of file diff --git a/docs/4.x/migrating-react-tutorial/index.html b/docs/4.x/migrating-react-tutorial/index.html index 3126b4265..8f6c294a2 100644 --- a/docs/4.x/migrating-react-tutorial/index.html +++ b/docs/4.x/migrating-react-tutorial/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 4.x

    Migrating an Existing React Project

    Project Setup

    @@ -54,6 +54,6 @@

    http://localhost:3000 by running yarn start from the root directory.

    Inspect the page and notice that our SPA is now being rendered inside of the <div id="root"/>. Technically, we are back to square one, with a fully functioning SPA. However, now that our SPA is a registered single-spa application we can take advantage of single-spa's functionality by building additional applications to mount side by side with our current React SPA.

    -

    Feel free to start using that new Javacript framework everyone has been talking about.

    +

    Feel free to start using that new Javacript framework everyone has been talking about.

    \ No newline at end of file diff --git a/docs/4.x/parcels-api/index.html b/docs/4.x/parcels-api/index.html index bb82694c0..2dfc8bb60 100644 --- a/docs/4.x/parcels-api/index.html +++ b/docs/4.x/parcels-api/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 4.x

    Parcels API

    Most parcel methods will be called on the parcel itself, with the exception being around mounting.

    @@ -70,6 +70,6 @@

    bootstrapPr

    mountPromise

    parcel.mountPromise() returns a promise that will resolve once the parcel has been mounted. This is helpful for knowing exactly when a parcel has been appended to the DOM

    unmountPromise

    -

    parcel.unmountPromise() returns a promise that will resolve once the parcel has been unmounted.

    +

    parcel.unmountPromise() returns a promise that will resolve once the parcel has been unmounted.

    \ No newline at end of file diff --git a/docs/4.x/parcels-overview/index.html b/docs/4.x/parcels-overview/index.html index 3b34d8315..a1492c528 100644 --- a/docs/4.x/parcels-overview/index.html +++ b/docs/4.x/parcels-overview/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 4.x

    Parcels

    A single-spa parcel is a framework agnostic component. It is a chunk of functionality meant to be mounted manually by an application, without having to worry about which framework was used to implement the parcel or application. Parcels use similar methodology as registered applications but are mounted by a manual function call rather than the activity function. @@ -78,6 +78,6 @@

    lifecycle prop. You will need to store and manage that function yourself in your application.

    Example of storing the application specific mountParcel API:

    // App1
    let mountParcel
    export const bootstrap = [
    (props) => {
    mountParcel = props.mountParcel
    return Promise.resolve()
    },
    // more bootstrap lifecycles if necessary
    ]
    ...
    -

    note: some libraries (such as react) support a framework specific context that makes it easy to store/manage. In those cases we've written some helper methods to abstract away the need to manage and store the mountParcel method.

    +

    note: some libraries (such as react) support a framework specific context that makes it easy to store/manage. In those cases we've written some helper methods to abstract away the need to manage and store the mountParcel method.

    \ No newline at end of file diff --git a/docs/4.x/separating-applications/index.html b/docs/4.x/separating-applications/index.html index 02cb091b9..845aa89f7 100644 --- a/docs/4.x/separating-applications/index.html +++ b/docs/4.x/separating-applications/index.html @@ -14,8 +14,8 @@ - - + + +
    Comparison of front-end system architectures
    MonorepoNPM modulesModule loading
    Difficulty to set upEasyMediumHard
    Separate code repositoriesNoNo
    Separate buildsNo
    Separate deploymentsNo
    Examples
    \ No newline at end of file diff --git a/docs/4.x/starting-from-scratch/index.html b/docs/4.x/starting-from-scratch/index.html index 5dbb47c6a..c5f6499aa 100644 --- a/docs/4.x/starting-from-scratch/index.html +++ b/docs/4.x/starting-from-scratch/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 4.x

    Starting From Scratch

    single-spa allows you to build micro frontends that coexist and can each be written with their own framework. This will allow you and your team to:

    @@ -32,7 +32,7 @@
  • angularJS: an AngularJS app using angular-ui-router
  • The complete code for this example is in the single-spa-simple-example repository.

    -
    note

    We encourage you to read through all the single-spa docs to become familiar with the entire single-spa setup. Visit the single-spa Github, the help section, or our community Slack channel for more support.

    +
    note

    We encourage you to read through all the single-spa docs to become familiar with the entire single-spa setup. Visit the single-spa Github, the help section, or our community Slack channel for more support.

    1. Initial setup

    info

    For this tutorial, we will be using yarn but npm has its own equivalent commands and can be used almost interchangibly.

    Create a new folder for this project and navigate into it. Initialize a new project using your package manager, and then install single-spa as a dependency. Then create a src/ folder to hold all of our micro-service applications, with each in their own folder.

    @@ -162,6 +162,6 @@

    6.e

    Finished!

    From the root directory run yarn start to check out your new single-spa project.

    We hope this tutorial gives you experience building and implementing micro frontends using single-spa. Review this guide periodically and use it as a reference in your projects. If you still have questions about how to use single-spa with your specific build, check out the migration tutorials: for AngularJS and React.

    -

    As always, there is more to be learned. If you want to learn how to use single-spa with Angular, Vue, or other frameworks/build systems, checkout the single-spa-examples repo. Lastly, you may also want to study how to separate applications using single-spa.

    +

    As always, there is more to be learned. If you want to learn how to use single-spa with Angular, Vue, or other frameworks/build systems, checkout the single-spa-examples repo. Lastly, you may also want to study how to separate applications using single-spa.

    \ No newline at end of file diff --git a/docs/5.x/api/index.html b/docs/5.x/api/index.html index f617467ed..7f999766c 100644 --- a/docs/5.x/api/index.html +++ b/docs/5.x/api/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 5.x

    Applications API

    Single-spa exports named functions and variables rather than a single default export. @@ -238,6 +238,6 @@

    no-app-c

    When no applications were loaded, bootstrapped, mounted, unmounted, or unloaded, single-spa fires a single-spa:no-app-change event. This is the inverse of the single-spa:app-change event. Only one will be fired for each routing event.

    routing-event

    window.addEventListener("single-spa:routing-event", (evt) => {
    console.log("single-spa finished mounting/unmounting applications!");
    console.log(evt.detail.originalEvent); // PopStateEvent
    console.log(evt.detail.newAppStatuses); // { app1: MOUNTED, app2: NOT_MOUNTED }
    console.log(evt.detail.appsByNewStatus); // { MOUNTED: ['app1'], NOT_MOUNTED: ['app2'] }
    console.log(evt.detail.totalAppChanges); // 2
    });
    -

    A single-spa:routing-event event is fired every time that a routing event has occurred, which is after each hashchange, popstate, or triggerAppChange, even if no changes to registered applications were necessary; and after single-spa verified that all apps were correctly loaded, bootstrapped, mounted, and unmounted.

    +

    A single-spa:routing-event event is fired every time that a routing event has occurred, which is after each hashchange, popstate, or triggerAppChange, even if no changes to registered applications were necessary; and after single-spa verified that all apps were correctly loaded, bootstrapped, mounted, and unmounted.

    \ No newline at end of file diff --git a/docs/5.x/building-applications/index.html b/docs/5.x/building-applications/index.html index 7c5ab054a..b808c64d1 100644 --- a/docs/5.x/building-applications/index.html +++ b/docs/5.x/building-applications/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 5.x

    Building single-spa applications

    A single-spa registered application is everything that a normal SPA is, except that it doesn't have an HTML page. In a single-spa world, your SPA contains many registered applications, where each has its own framework. Registered applications have their own client-side routing and their own frameworks/libraries. They render their own HTML and have full freedom to do whatever they want, whenever they are mounted. The concept of being mounted refers to whether a registered application is putting content on the DOM or not. What determines if a registered application is mounted is its activity function. Whenever a registered application is not mounted, it should remain completely dormant until mounted.

    @@ -82,6 +82,6 @@

    TimeoutsTransitioning between applications

    If you find yourself wanting to add transitions as applications are mounted and unmounted, then you'll probably want to tie into the bootstrap, mount, and unmount lifecycle methods. This single-spa transitions repo is a small proof-of-concept of how you can tie into these lifecycle methods to add transitions as your apps mount and unmount.

    -

    Transitions for pages within a mounted application can be handled entirely by the application itself. For example, using react-transition-group for React-based projects.

    +

    Transitions for pages within a mounted application can be handled entirely by the application itself. For example, using react-transition-group for React-based projects.

    \ No newline at end of file diff --git a/docs/5.x/code-of-conduct/index.html b/docs/5.x/code-of-conduct/index.html index d3fbdb87b..848880b58 100644 --- a/docs/5.x/code-of-conduct/index.html +++ b/docs/5.x/code-of-conduct/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 5.x

    Code of Conduct

    This code of conduct outlines our expectations for participants within the single-spa community, as well as steps to reporting unacceptable behavior. We are committed to providing a welcoming and inspiring community for all and expect our code of conduct to be honored. Anyone who violates this code of conduct may be banned from the community.

    @@ -53,6 +53,6 @@

    Reporting I

    After filing a report, a representative will contact you personally. If the person who is harassing you is part of the response team, they will recuse themselves from handling your incident. A representative will then review the incident, follow up with any additional questions, and make a decision as to how to respond. We will respect confidentiality requests for the purpose of protecting victims of abuse.

    Anyone asked to stop unacceptable behavior is expected to comply immediately. If an individual engages in unacceptable behavior, the representative may take any action they deem appropriate, up to and including a permanent ban from our community without warning.

    -

    This Code Of Conduct follows the template established by the TODO Group.

    +

    This Code Of Conduct follows the template established by the TODO Group.

    \ No newline at end of file diff --git a/docs/5.x/configuration/index.html b/docs/5.x/configuration/index.html index 70ec9dc09..83b6f969a 100644 --- a/docs/5.x/configuration/index.html +++ b/docs/5.x/configuration/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 5.x

    Configuring single-spa

    The single-spa root config consists of the following:

    @@ -98,6 +98,6 @@

    <div id="single-spa-application:app-name"></div>
    <div id="single-spa-application:other-app"></div>

    +
    <div id="single-spa-application:app-name"></div>
    <div id="single-spa-application:other-app"></div>
    \ No newline at end of file diff --git a/docs/5.x/contributing-overview/index.html b/docs/5.x/contributing-overview/index.html index cbf41f1e8..07b19c905 100644 --- a/docs/5.x/contributing-overview/index.html +++ b/docs/5.x/contributing-overview/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 5.x

    Contributing to Single-spa

    List of current contributors

    @@ -86,7 +86,7 @@

    Push itCommunity

    -

    Discussions about single-spa take place on the single-spa repository's Issues and Pull Requests sections. Anybody is welcome to join these conversations. There is also a Slack workspace for regular updates.

    -

    Wherever possible, do not take these conversations to private channels, including contacting the maintainers directly. Keeping communication public means everybody can benefit and learn from the conversation.

    +

    Discussions about single-spa take place on the single-spa repository's Issues and Pull Requests sections. Anybody is welcome to join these conversations. There is also a Slack workspace for regular updates.

    +

    Wherever possible, do not take these conversations to private channels, including contacting the maintainers directly. Keeping communication public means everybody can benefit and learn from the conversation.

    \ No newline at end of file diff --git a/docs/5.x/create-single-spa/index.html b/docs/5.x/create-single-spa/index.html index 36b75e2c9..ba58bad59 100644 --- a/docs/5.x/create-single-spa/index.html +++ b/docs/5.x/create-single-spa/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 5.x

    create-single-spa

    Single-spa offers a CLI for those who prefer autogenerated and managed configurations for webpack, babel, jest, etc. You do not have to use the CLI in order to use single-spa.

    @@ -69,6 +69,6 @@

    clearAllIn
    import { clearAllIntervals } from "single-spa-web-server-utils";

    clearAllIntervals();

    reset

    This clears all intervals (see clearAllIntervals), and also clears the in-memory cache of all import maps. In other words, after reset() is called, getImportMaps() will always result in a new network request to fetch the import map.

    -
    import { reset } from "single-spa-web-server-utils";

    reset();
    +
    import { reset } from "single-spa-web-server-utils";

    reset();
    \ No newline at end of file diff --git a/docs/5.x/devtools/index.html b/docs/5.x/devtools/index.html index 24095b18c..d7ae149fa 100644 --- a/docs/5.x/devtools/index.html +++ b/docs/5.x/devtools/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 5.x

    single-spa-inspector

    The single-spa-inspector is a Firefox/Chrome devtools extension to provide utilities for helping with single-spa applications. Github project.

    @@ -40,6 +40,6 @@

    Con
    // must be called "devtools"
    export const devtools = {
    overlays: {
    // selectors is required for overlays to work
    selectors: [
    // an array of CSS selector strings, meant to be unique ways to identify the outermost container of your app
    // you can have more than one, for cases like parcels or different containers for differet views
    "#my-app",
    ".some-container .app",
    ],
    // options is optional
    options: {
    // these options allow you some control over how the overlay div looks/behaves
    // the listed values below are the defaults

    width: "100%",
    height: "100%",
    zIndex: 40,
    position: "absolute",
    top: 0,
    left: 0,
    color: "#000", // the default for this is actually based on the app's name, so it's dynamic. can be a hex or a CSS color name
    background: "#000", // the default for this is actually based on the app's name, so it's dynamic. can be a hex or a CSS color name
    textBlocks: [
    // allows you to add additional text to the overlay. for example, you can add the name of the team/squad that owns this app
    // each string in this array will be in a new div
    // 'blue squad', 'is awesome'
    // turns into:
    // <div>blue squad</div><div>is awesome</div>
    ],
    },
    },
    };

    import-map-overrides

    If your environment uses import-maps, single-spa Inspector provides an interface for adding import-map overrides when utilizing the import-map-overrides library. Once the installation requirements for import-map-overrides are completed, you can add, remove, and refresh the page with your overrides.

    -

    Example of single-spa Inspector extension with import-maps overrides

    +

    Example of single-spa Inspector extension with import-maps overrides

    \ No newline at end of file diff --git a/docs/5.x/ecosystem-alpinejs/index.html b/docs/5.x/ecosystem-alpinejs/index.html index f8f9b3dff..fd12bbe5e 100644 --- a/docs/5.x/ecosystem-alpinejs/index.html +++ b/docs/5.x/ecosystem-alpinejs/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/docs/5.x/ecosystem-angular/index.html b/docs/5.x/ecosystem-angular/index.html index 0a5f895e0..bea198fb2 100644 --- a/docs/5.x/ecosystem-angular/index.html +++ b/docs/5.x/ecosystem-angular/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 5.x

    single-spa-angular

    Project Status

    @@ -27,7 +27,7 @@

    Introduction

    The documentation here is extensive, so use the sidenav on the right. 👉👉👉

    Community

    -

    Join the #angular channel in single-spa's Slack workspace.

    +

    Join the #angular channel in single-spa's Slack workspace.

    Demo

    https://coexisting-angular-microfrontends.surge.sh

    Starter repo

    @@ -463,6 +463,6 @@

    const singleSpaAngularWebpack =
    require("single-spa-angular/lib/webpack").default;

    module.exports = (config, options) => {
    const singleSpaWebpackConfig = singleSpaAngularWebpack(config, options);
    singleSpaWebpackConfig.externals = [/^@org\/api$/];
    return singleSpaWebpackConfig;
    };

    But this library should be part of root application bundle and shared with import maps, for example:

    -
    {
    "imports": {
    "@org/api": "http://localhost:8080/api.js"
    }
    }
    +
    {
    "imports": {
    "@org/api": "http://localhost:8080/api.js"
    }
    }
    \ No newline at end of file diff --git a/docs/5.x/ecosystem-angularjs/index.html b/docs/5.x/ecosystem-angularjs/index.html index 587a93326..d9f8b80e0 100644 --- a/docs/5.x/ecosystem-angularjs/index.html +++ b/docs/5.x/ecosystem-angularjs/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    + \ No newline at end of file diff --git a/docs/5.x/ecosystem-backbone/index.html b/docs/5.x/ecosystem-backbone/index.html index 42f7d8aea..58ca0f548 100644 --- a/docs/5.x/ecosystem-backbone/index.html +++ b/docs/5.x/ecosystem-backbone/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 5.x

    single-spa-backbone

    A single-spa helper library which provides lifecycle events for building single-spa applications using Backbone.

    @@ -82,6 +82,6 @@

    OptionsNote : Out of AppWithRequire, AppWithBackboneJs and App only one is required

    • DomElementSetter (optional) : This is an optional parameter and can be mostly used to create a dom element, whose id can be later used in the backbone app to load the application. However, you can freely use this callback for any other purpose. It is called before anything else.
    • -
    + \ No newline at end of file diff --git a/docs/5.x/ecosystem-css/index.html b/docs/5.x/ecosystem-css/index.html index 2d6ba367d..bb4b30a5d 100644 --- a/docs/5.x/ecosystem-css/index.html +++ b/docs/5.x/ecosystem-css/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 5.x

    CSS

    In a microfrontends architecture, it's important to have both shared CSS and microfrontend-specific CSS. There should only be one copy of all shared CSS, and CSS specific to a microfrontend should be scoped so that class names do not collide between microfrontends.

    @@ -125,6 +125,6 @@

    Webpack Plugi

    single-spa-css includes a Webpack plugin that integrates with mini-css-extract-plugin, which allows you to load CSS files that are extracted and otherwise would not be loaded. The Webpack plugin exposes the names of the extracted CSS files to your bundle under the __webpack_require__.cssAssets and __webpack_require__.cssAssetFileName variables. The cssAssets variable contains the name of the Webpack chunk, and the cssAssetFileName function converts the chunk name into the extracted CSS asset's file name. These can be used manually, or you can specify the webpackExtractedCss option in single-spa-css to have it automatically mount and unmount those CSS files.

    Usage

    In your Webpack config, add the following:

    -
    const MiniCssExtractPlugin = require("mini-css-extract-plugin");
    const ExposeRuntimeCssAssetsPlugin = require("single-spa-css/ExposeRuntimeCssAssetsPlugin.cjs");

    module.exports = {
    plugins: [
    new MiniCssExtractPlugin({
    filename: "[name].css",
    }),
    new ExposeRuntimeCssAssetsPlugin({
    // The filename here must match the filename for the MiniCssExtractPlugin
    filename: "[name].css",
    }),
    ],
    };
    +
    const MiniCssExtractPlugin = require("mini-css-extract-plugin");
    const ExposeRuntimeCssAssetsPlugin = require("single-spa-css/ExposeRuntimeCssAssetsPlugin.cjs");

    module.exports = {
    plugins: [
    new MiniCssExtractPlugin({
    filename: "[name].css",
    }),
    new ExposeRuntimeCssAssetsPlugin({
    // The filename here must match the filename for the MiniCssExtractPlugin
    filename: "[name].css",
    }),
    ],
    };
    \ No newline at end of file diff --git a/docs/5.x/ecosystem-cycle/index.html b/docs/5.x/ecosystem-cycle/index.html index 604936bea..b1e5105b5 100644 --- a/docs/5.x/ecosystem-cycle/index.html +++ b/docs/5.x/ecosystem-cycle/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/docs/5.x/ecosystem-dojo/index.html b/docs/5.x/ecosystem-dojo/index.html index d4fecf40f..60d511b1d 100644 --- a/docs/5.x/ecosystem-dojo/index.html +++ b/docs/5.x/ecosystem-dojo/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/docs/5.x/ecosystem-ember/index.html b/docs/5.x/ecosystem-ember/index.html index d3556e096..c1e690c8e 100644 --- a/docs/5.x/ecosystem-ember/index.html +++ b/docs/5.x/ecosystem-ember/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 5.x

    single-spa-ember

    single-spa-ember is a helper library that helps implement single-spa registered application lifecycle functions (bootstrap, mount and unmount) for use with Ember.js. Check out the single-spa-ember github.

    @@ -58,6 +58,6 @@

    Usage w

    In your single-spa root application (which is separate from anything generated by ember cli):

    // root-application.js
    import * as singleSpa from "single-spa";
    import { loadEmberApp } from "single-spa-ember";

    singleSpa.registerApplication("ember-app", loadingFunction, activityFunction);

    function activityFunction(location) {
    // Only render the ember app when the url hash starts with ember
    return location.hash.startsWith("ember");
    }

    // single-spa-ember helps us load the script tags and give the ember app module to single-spa.
    function loadingFunction() {
    const appName = "ember-app";
    const appUrl = "/dist/ember-app/assets/ember-app.js";
    const vendorUrl = "/dist/ember-app/assets/vendor.js"; // Optional if you have one vendor bundle used for many different ember apps
    return loadEmberApp(appName, appUrl, vendorUrl);
    }

    In your app.js file (that is generated by ember cli)

    -
    // app.js (the ember application)
    import Ember from "ember";
    import Resolver from "./resolver";
    import loadInitializers from "ember-load-initializers";
    import config from "./config/environment";
    import singleSpaEmber from "single-spa-ember";

    // This part is generated by the ember cli
    const App = Ember.Application.extend({
    modulePrefix: config.modulePrefix,
    podModulePrefix: config.podModulePrefix,
    Resolver,
    });

    loadInitializers(App, config.modulePrefix);

    export default App;

    // This is the single-spa part
    const emberLifecycles = singleSpaEmber({
    App, // required
    appName: "ember-app", // required
    createOpts: {
    // optional
    rootElement: "#ember-app",
    },
    });

    // Single-spa lifecycles.
    export const bootstrap = emberLifecycles.bootstrap;
    export const mount = emberLifecycles.mount;
    export const unmount = emberLifecycles.unmount;

    +
    // app.js (the ember application)
    import Ember from "ember";
    import Resolver from "./resolver";
    import loadInitializers from "ember-load-initializers";
    import config from "./config/environment";
    import singleSpaEmber from "single-spa-ember";

    // This part is generated by the ember cli
    const App = Ember.Application.extend({
    modulePrefix: config.modulePrefix,
    podModulePrefix: config.podModulePrefix,
    Resolver,
    });

    loadInitializers(App, config.modulePrefix);

    export default App;

    // This is the single-spa part
    const emberLifecycles = singleSpaEmber({
    App, // required
    appName: "ember-app", // required
    createOpts: {
    // optional
    rootElement: "#ember-app",
    },
    });

    // Single-spa lifecycles.
    export const bootstrap = emberLifecycles.bootstrap;
    export const mount = emberLifecycles.mount;
    export const unmount = emberLifecycles.unmount;
    \ No newline at end of file diff --git a/docs/5.x/ecosystem-html-web-components/index.html b/docs/5.x/ecosystem-html-web-components/index.html index 5ed49760f..ce76d6523 100644 --- a/docs/5.x/ecosystem-html-web-components/index.html +++ b/docs/5.x/ecosystem-html-web-components/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    + \ No newline at end of file diff --git a/docs/5.x/ecosystem-inferno/index.html b/docs/5.x/ecosystem-inferno/index.html index 22608adcc..78f8cc677 100644 --- a/docs/5.x/ecosystem-inferno/index.html +++ b/docs/5.x/ecosystem-inferno/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/docs/5.x/ecosystem-leaked-globals/index.html b/docs/5.x/ecosystem-leaked-globals/index.html index b0fd8c136..9f753353c 100644 --- a/docs/5.x/ecosystem-leaked-globals/index.html +++ b/docs/5.x/ecosystem-leaked-globals/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/docs/5.x/ecosystem-preact/index.html b/docs/5.x/ecosystem-preact/index.html index a776c95c6..3823ced2c 100644 --- a/docs/5.x/ecosystem-preact/index.html +++ b/docs/5.x/ecosystem-preact/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/docs/5.x/ecosystem-react/index.html b/docs/5.x/ecosystem-react/index.html index 09ce9f2d7..1bb30a09c 100644 --- a/docs/5.x/ecosystem-react/index.html +++ b/docs/5.x/ecosystem-react/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 5.x

    single-spa-react

    Build Status

    @@ -75,6 +75,6 @@

    Parcel propsExamples

    // Use this import path in environments that support package.json exports
    // See https://nodejs.org/dist/latest-v14.x/docs/api/packages.html#packages_package_entry_points
    // and see https://github.com/single-spa/single-spa-react/releases/tag/v3.0.0
    // Use this in Webpack 5 and recent versions of Node
    import Parcel from 'single-spa-react/parcel'

    // Use this import path in environments that don't support package.json exports
    // See https://nodejs.org/dist/latest-v14.x/docs/api/packages.html#packages_package_entry_points
    // and see https://github.com/single-spa/single-spa-react/releases/tag/v3.0.0
    // Use this in Webpack 4 and older versions of Node
    import Parcel from 'single-spa-react/lib/esm/parcel'


    import * as parcelConfig from './my-parcel.js'

    // config is required. The parcel will be mounted inside of the
    // of a div inside of the react component tree
    <Parcel
    config={parcelConfig}

    wrapWith="div"
    handleError={err => console.error(err)}

    customProp1="customPropValue2"
    customProp2="customPropValue2"
    />

    // If you pass in an appendTo prop, the parcel will be mounted there instead of
    // to a dom node inside of the current react component tree
    <Parcel
    config={parcelConfig}
    wrapWith="div"
    appendTo={document.body}
    />

    // You can also pass in a "loading function" as the config.
    // The loading function must return a promise that resolves with the parcel config.
    // The parcel will be mounted once the promise resolves.
    <Parcel
    config={() => import('./my-parcel.js')}
    wrapWith="div"
    />

    // If you are rendering the Parcel component from a single-spa application, you do not need to pass a mountParcel prop.
    // But if you have a separate react component tree that is not rendered by single-spa-react, you **must** pass in a mountParcel prop
    // In general, it is preferred to use an application's mountParcel function instead of the single-spa's root mountParcel function,
    // so that single-spa can keep track of the parent-child relationship and automatically unmount the application's parcels when the application
    // unmounts
    <Parcel
    mountParcel={singleSpa.mountParcel}
    config={parcelConfig}
    wrapWith="div"
    />

    // Add styles to wrapWith element.
    <Parcel
    config={parcelConfig}
    wrapWith="div"
    wrapStyle={{ background: 'black' }}
    />

    // Add classNames to wrapWith element.
    <Parcel
    config={parcelConfig}
    wrapWith="div"
    wrapClassName="wrapper"
    />

    Create React App

    -

    See FAQ for CRA.

    +

    See FAQ for CRA.

    \ No newline at end of file diff --git a/docs/5.x/ecosystem-riot/index.html b/docs/5.x/ecosystem-riot/index.html index 5f5dbdd3e..81af48d9b 100644 --- a/docs/5.x/ecosystem-riot/index.html +++ b/docs/5.x/ecosystem-riot/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/docs/5.x/ecosystem-snowpack/index.html b/docs/5.x/ecosystem-snowpack/index.html index 93bedc46b..11e4567a8 100644 --- a/docs/5.x/ecosystem-snowpack/index.html +++ b/docs/5.x/ecosystem-snowpack/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 5.x

    Snowpack

    Snowpack is a tool for both local development and the building of applications. It uses in-browser ES modules during development, and then bundles with webpack (or other build tools) for production.

    @@ -36,6 +36,6 @@

    N
    • The browser and SystemJS maintain separate module registries. This means that you can't share imports between SystemJS and native modules. So if you are doing an import map override for a Snowpack application on a page that also uses SystemJS, you may end up with multiple instances of Vue or React (and other shared libraries), which is different than how things will work in production. This is generally okay, except for situations where the Vue instance is modified via Vue.use().
    • This PR to SystemJS shows how you can populate native modules into the SystemJS registry, allowing for one-way sharing of modules between the two registries. The PR was closed due to some edge cases, but it generally works. Even though the PR is closed, you can paste the ESM extra into your root config and it will work. If you have interest in driving forward better SystemJS + ESM compatibility, comment on Github or Slack with your interest.
    • -

    + \ No newline at end of file diff --git a/docs/5.x/ecosystem-svelte/index.html b/docs/5.x/ecosystem-svelte/index.html index 0f3b510fe..ca28b355c 100644 --- a/docs/5.x/ecosystem-svelte/index.html +++ b/docs/5.x/ecosystem-svelte/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    +

    All single-spa props are passed to the svelte component as props. The props provided to singleSpaSvelte({props: {...}}) are merged with the single-spa props.

    \ No newline at end of file diff --git a/docs/5.x/ecosystem-vite/index.html b/docs/5.x/ecosystem-vite/index.html index a7ce192aa..2b4e45026 100644 --- a/docs/5.x/ecosystem-vite/index.html +++ b/docs/5.x/ecosystem-vite/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 5.x

    Vite

    Vite is a tool for both local development and the building of applications. It was created within the Vue ecosystem, but can be used with other UI frameworks, too.

    @@ -52,6 +52,6 @@

    Main Features<

    IMPORTANT: The author of this plug-in does not believe in creating dedicated root config projects. Furthermore, this package will, by default, create import maps for native modules. We at single-spa recommend SystemJS modules. Yes, single-spa is perfectly capable of working with native modules as well.

    -

    The opinions of the author of this plug-in in no way represent those of single-spa, and it is an independent work. We present it here as one more option in the Vite ecosystem.

    +

    The opinions of the author of this plug-in in no way represent those of single-spa, and it is an independent work. We present it here as one more option in the Vite ecosystem.

    \ No newline at end of file diff --git a/docs/5.x/ecosystem-vue/index.html b/docs/5.x/ecosystem-vue/index.html index e5df53525..5ad92e420 100644 --- a/docs/5.x/ecosystem-vue/index.html +++ b/docs/5.x/ecosystem-vue/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 5.x

    single-spa-vue

    single-spa-vue is a helper library that helps implement single-spa registered application lifecycle functions (bootstrap, mount and unmount) for use with Vue.js. Check out the single-spa-vue github.

    @@ -101,6 +101,6 @@

    Webpack

    vue-cli-plugin-single-spa sets the webpack public path via SystemJSPublicPathWebpackPlugin. By default, the public path is set to match the following output directory structure:

    dist/
    js/
    app.js
    css/
    main.css

    With this directory structure (which is the Vue CLI default), the public path should not include the js folder. This is accomplished by setting rootDirectoryLevel to be 2. If this doesn't match your directory structure or setup, you can change the rootDirectoryLevel with the following code in your vue.config.js or webpack.config.js:

    -
    // vue.config.js
    module.exports = {
    chainWebpack(config) {
    config.plugin("SystemJSPublicPathWebpackPlugin").tap((args) => {
    args[0].rootDirectoryLevel = 1;
    return args;
    });
    },
    };

    +
    // vue.config.js
    module.exports = {
    chainWebpack(config) {
    config.plugin("SystemJSPublicPathWebpackPlugin").tap((args) => {
    args[0].rootDirectoryLevel = 1;
    return args;
    });
    },
    };
    \ No newline at end of file diff --git a/docs/5.x/ecosystem/index.html b/docs/5.x/ecosystem/index.html index a1a1f3804..67667437a 100644 --- a/docs/5.x/ecosystem/index.html +++ b/docs/5.x/ecosystem/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/docs/5.x/examples/index.html b/docs/5.x/examples/index.html index e80e0f466..27a192238 100644 --- a/docs/5.x/examples/index.html +++ b/docs/5.x/examples/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 5.x

    Single-spa Examples

    Core team examples

    @@ -63,6 +63,6 @@

    Community
  • single-spa-react-angular a multi-framework example with React and Angular. This app uses routes to render the React and Angular apps.
  • vite-ts-single-spa-root-config: Create a root config example of single-spa using vite and typescript.
  • -

    Have your own example or starter repo? Submit a PR to add yours to this list.

    +

    Have your own example or starter repo? Submit a PR to add yours to this list.

    \ No newline at end of file diff --git a/docs/5.x/faq/index.html b/docs/5.x/faq/index.html index d5c9f2aeb..6272da391 100644 --- a/docs/5.x/faq/index.html +++ b/docs/5.x/faq/index.html @@ -14,8 +14,8 @@ - - + + +

    See the documentation for unit and E2E tests.

    \ No newline at end of file diff --git a/docs/5.x/getting-started-overview/index.html b/docs/5.x/getting-started-overview/index.html index 0dd8ec925..0b9eb7df8 100644 --- a/docs/5.x/getting-started-overview/index.html +++ b/docs/5.x/getting-started-overview/index.html @@ -14,12 +14,12 @@ - - + +
    Skip to main content
    Version: 5.x

    Getting Started with single-spa

    JavaScript Microfrontends

    -

    Join the chat on Slack

    +

    Join the chat on Slack

    single-spa is a framework for bringing together multiple JavaScript microfrontends in a frontend application. Architecting your frontend using single-spa enables many benefits, such as:

    +

    Is your company or project using single-spa? Let us know by submitting a PR to this section!

    \ No newline at end of file diff --git a/docs/5.x/glossary/index.html b/docs/5.x/glossary/index.html index 76d7f6429..6c48e9580 100644 --- a/docs/5.x/glossary/index.html +++ b/docs/5.x/glossary/index.html @@ -14,10 +14,10 @@ - - + + -
    Skip to main content
    Version: 5.x

    Glossary

    Activity Function
    Application
    Application
    Helpers
    are a library that already implements single-spa lifecycle functions for a specific framework.
    Lifecycles
    module loader
    Microservices
    registerApplication
    +
    Skip to main content
    Version: 5.x

    Glossary

    Activity Function
    Application
    Application
    Helpers
    are a library that already implements single-spa lifecycle functions for a specific framework.
    Lifecycles
    module loader
    Microservices
    registerApplication
    \ No newline at end of file diff --git a/docs/5.x/layout-api/index.html b/docs/5.x/layout-api/index.html index b00d9027d..0f2f25522 100644 --- a/docs/5.x/layout-api/index.html +++ b/docs/5.x/layout-api/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 5.x

    Layout Engine API

    The single-spa-layout library exposes several javascript functions as a public API.

    @@ -106,6 +106,6 @@

    sendL
  • nonce (optional): A string nonce that is added to the <script> sent with the singleSpaLayoutData global variable.
  • Return Value

    -

    A promise that resolves when headers (but not necessarily HTTP response body) are sent.

    +

    A promise that resolves when headers (but not necessarily HTTP response body) are sent.

    \ No newline at end of file diff --git a/docs/5.x/layout-definition/index.html b/docs/5.x/layout-definition/index.html index 2d55d2b9f..98cf3e23f 100644 --- a/docs/5.x/layout-definition/index.html +++ b/docs/5.x/layout-definition/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    +
    const myErrorParcel = singleSpaReact({...})

    const routes = constructRoutes(document.querySelector('#single-spa-layout'), {
    errors: {
    navError: myErrorParcel
    // alternatively:
    // navError: "<h1>Oops! The navbar isn't working right now</h1>"
    }
    })
    \ No newline at end of file diff --git a/docs/5.x/layout-overview/index.html b/docs/5.x/layout-overview/index.html index f7923014d..8aca32cbc 100644 --- a/docs/5.x/layout-overview/index.html +++ b/docs/5.x/layout-overview/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    +
    import { registerApplication, start } from "single-spa";
    import {
    constructApplications,
    constructRoutes,
    constructLayoutEngine,
    } from "single-spa-layout";

    const routes = constructRoutes(document.querySelector("#single-spa-layout"));
    const applications = constructApplications({
    routes,
    loadApp({ name }) {
    return System.import(name);
    },
    });
    const layoutEngine = constructLayoutEngine({ routes, applications });

    applications.forEach(registerApplication);
    start();
    \ No newline at end of file diff --git a/docs/5.x/microfrontends-concept/index.html b/docs/5.x/microfrontends-concept/index.html index ded03b0a7..188d79755 100644 --- a/docs/5.x/microfrontends-concept/index.html +++ b/docs/5.x/microfrontends-concept/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 5.x

    Concept: Microfrontends

    @@ -43,6 +43,6 @@

    Relationship to single-spa

    single-spa is a small, 5kb (gzipped) npm package that orchestrates the mounting and unmounting of your microfrontends. It knows when to mount the applications based on activity functions and can do so in a framework agnostic way with the help of small adapter libraries.

    Performance

    -

    Microfrontends are often more performant than the monoliths from which they originate. This is due to built-in lazy loading (via loading functions) and other performance-related best practices. Your monolith likely has "skeletons in its closet" - microfrontends gives you a migration path that will expose and resolve the problems caused by those skeletons. One important performance consideration is to share a single instance of large libraries (such as React, Vue, or Angular), which is highly encouraged. To do so, see our recommended setup.

    +

    Microfrontends are often more performant than the monoliths from which they originate. This is due to built-in lazy loading (via loading functions) and other performance-related best practices. Your monolith likely has "skeletons in its closet" - microfrontends gives you a migration path that will expose and resolve the problems caused by those skeletons. One important performance consideration is to share a single instance of large libraries (such as React, Vue, or Angular), which is highly encouraged. To do so, see our recommended setup.

    \ No newline at end of file diff --git a/docs/5.x/migrating-existing-spas/index.html b/docs/5.x/migrating-existing-spas/index.html index 3ff14def7..98da49b46 100644 --- a/docs/5.x/migrating-existing-spas/index.html +++ b/docs/5.x/migrating-existing-spas/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 5.x

    Migrating existing SPAs

    If you're interested in migrating existing SPAs into a single-spa, you'll @@ -46,6 +46,6 @@

    application. It is best to try to put all that you can into the JavaScript bundle, but your escape hatch is to put the things -you need into your single spa config.

    +you need into your single spa config.

    \ No newline at end of file diff --git a/docs/5.x/module-types/index.html b/docs/5.x/module-types/index.html index 16f12f4df..da2cbc944 100644 --- a/docs/5.x/module-types/index.html +++ b/docs/5.x/module-types/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/docs/5.x/parcels-api/index.html b/docs/5.x/parcels-api/index.html index 0e68c7b5f..d9184bc62 100644 --- a/docs/5.x/parcels-api/index.html +++ b/docs/5.x/parcels-api/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 5.x

    Parcels API

    Most parcel methods will be called on the parcel itself, with the exception being around mounting.

    @@ -70,6 +70,6 @@

    bootstrapPr

    mountPromise

    parcel.mountPromise() returns a promise that will resolve once the parcel has been mounted. This is helpful for knowing exactly when a parcel has been appended to the DOM

    unmountPromise

    -

    parcel.unmountPromise() returns a promise that will resolve once the parcel has been unmounted.

    +

    parcel.unmountPromise() returns a promise that will resolve once the parcel has been unmounted.

    \ No newline at end of file diff --git a/docs/5.x/parcels-overview/index.html b/docs/5.x/parcels-overview/index.html index 5ccc14215..412f69599 100644 --- a/docs/5.x/parcels-overview/index.html +++ b/docs/5.x/parcels-overview/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 5.x

    Parcels

    Parcels are an advanced feature of single-spa. We recommend that you use applications as the primary type of microfrontend in your architecture. See this explanation for more details

    @@ -80,6 +80,6 @@

    lifecycle prop. You will need to store and manage that function yourself in your application.

    Example of storing the application specific mountParcel API:

    // App1
    let mountParcel
    export const bootstrap = [
    (props) => {
    mountParcel = props.mountParcel
    return Promise.resolve()
    },
    // more bootstrap lifecycles if necessary
    ]
    ...
    -

    note: some libraries (such as react) support a framework specific context that makes it easy to store/manage. In those cases we've written some helper methods to abstract away the need to manage and store the mountParcel method.

    +

    note: some libraries (such as react) support a framework specific context that makes it easy to store/manage. In those cases we've written some helper methods to abstract away the need to manage and store the mountParcel method.

    \ No newline at end of file diff --git a/docs/5.x/recommended-setup/index.html b/docs/5.x/recommended-setup/index.html index b1ca3f10e..9895ccf17 100644 --- a/docs/5.x/recommended-setup/index.html +++ b/docs/5.x/recommended-setup/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 5.x

    The Recommended Setup

    The single-spa npm package is not opinionated about your build tools, CI process, or local development workflow. However, to implement single-spa you will have to figure all of those things out (and more). To help you decide how to approach these problems, the single-spa core team has put together a "recommended setup" that gives an opinionated approach to solving the practical problems of microfrontends.

    @@ -190,6 +190,6 @@

    UI StateState management

    The single-spa core team cautions against using redux, mobx, and other global state management libraries. However, if you'd like to use a state management library, we recommend keeping the state management tool specific to a single repository / microfrontend instead of a single store for all of your microfrontends. The reason is that microfrontends are not truly decoupled or framework agnostic if they all must use a global store. You cannot independently deploy a microfrontend if it relies on the global store's state to be a specific shape or have specific actions fired by other microfrontends - to do so you'd have to think really hard about whether your changes to the global store are backwards and forwards compatible with all other microfrontends. Additionally, managing global state during route transitions is hard enough without the complexity of multiple microfrontends contributing to and consuming the global state.

    -

    Instead of a global store, the single-spa core team recommends using local component state for your components, or a store for each of your microfrontends. See the above section "Inter-app communication" for more related information.

    +

    Instead of a global store, the single-spa core team recommends using local component state for your components, or a store for each of your microfrontends. See the above section "Inter-app communication" for more related information.

    \ No newline at end of file diff --git a/docs/5.x/separating-applications/index.html b/docs/5.x/separating-applications/index.html index 9f7c7f541..5beca0d60 100644 --- a/docs/5.x/separating-applications/index.html +++ b/docs/5.x/separating-applications/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 5.x

    Splitting up applications

    In a large, microserviced system, your root single-spa configuration and each of the applications should probably have its own git repository. How to do that in a JavaScript project isn't necessarily clear, so some options are listed below.

    @@ -60,6 +60,6 @@

    module loader such as SystemJS that can download and execute JavaScript code in the browser from dynamic urls.

    Comparison

    -
    Separate code repositories possibleIndependent CI buildsSeparate deploymentsExamples
    NPM Packages1
    Monorepo 1 11
    Module loading1 2 3
    +
    Separate code repositories possibleIndependent CI buildsSeparate deploymentsExamples
    NPM Packages1
    Monorepo 1 11
    Module loading1 2 3
    \ No newline at end of file diff --git a/docs/5.x/shared-webpack-configs/index.html b/docs/5.x/shared-webpack-configs/index.html index 286e01ebe..4192c0f12 100644 --- a/docs/5.x/shared-webpack-configs/index.html +++ b/docs/5.x/shared-webpack-configs/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 5.x

    Shared Webpack configs

    single-spa also publishes a few shared Webpack config packages that include basics needed for creating single-spa applications. These configs are used by applications generated with create-single-spa, and can be used as a starting point to extend/modify a custom configuration for your organization/team.

    @@ -68,6 +68,6 @@

    Replacing

    Use webpack-merge's mergeWithCustomize to resolve duplicate plugins or replace instances. Duplicate plugins often result in cryptic errors!

    When referencing a loader that is installed as a dependency of webpack-config-single-spa, use require.resolve to ensure its path is resolved correctly.

    Example: replace HtmlWebpackPlugin instance

    -
    const { mergeWithCustomize, unique } = require("webpack-merge");
    const singleSpaDefaults = require("webpack-config-single-spa");
    const HtmlWebpackPlugin = require("html-webpack-plugin");

    const merge = mergeWithCustomize({
    customizeArray: unique(
    "plugins",
    ["HtmlWebpackPlugin"],
    (plugin) => plugin.constructor && plugin.constructor.name,
    ),
    });

    module.exports = (env, argv) => {
    const orgName = "example";
    const myEnv = process.env.NODE_ENV || "development";

    const defaultConfig = singleSpaDefaults({
    orgName,
    projectName: "custom-root-config",
    webpackConfigEnv: env,
    argv,
    });

    const config = merge(defaultConfig, {
    plugins: [
    new HtmlWebpackPlugin({
    inject: false,
    template: "src/custom.ejs",
    templateParameters: {
    isLocal: env?.isLocal,
    // additional templateParameters can now be supplied
    orgName,
    environment: myEnv,
    },
    }),
    ],
    });

    // console.dir(config, null, 2) // useful for debugging
    return config;
    };
    +
    const { mergeWithCustomize, unique } = require("webpack-merge");
    const singleSpaDefaults = require("webpack-config-single-spa");
    const HtmlWebpackPlugin = require("html-webpack-plugin");

    const merge = mergeWithCustomize({
    customizeArray: unique(
    "plugins",
    ["HtmlWebpackPlugin"],
    (plugin) => plugin.constructor && plugin.constructor.name,
    ),
    });

    module.exports = (env, argv) => {
    const orgName = "example";
    const myEnv = process.env.NODE_ENV || "development";

    const defaultConfig = singleSpaDefaults({
    orgName,
    projectName: "custom-root-config",
    webpackConfigEnv: env,
    argv,
    });

    const config = merge(defaultConfig, {
    plugins: [
    new HtmlWebpackPlugin({
    inject: false,
    template: "src/custom.ejs",
    templateParameters: {
    isLocal: env?.isLocal,
    // additional templateParameters can now be supplied
    orgName,
    environment: myEnv,
    },
    }),
    ],
    });

    // console.dir(config, null, 2) // useful for debugging
    return config;
    };
    \ No newline at end of file diff --git a/docs/5.x/single-spa-playground/index.html b/docs/5.x/single-spa-playground/index.html index 062e7bf45..e785924c5 100644 --- a/docs/5.x/single-spa-playground/index.html +++ b/docs/5.x/single-spa-playground/index.html @@ -14,12 +14,12 @@ - - + + +

    The single-spa playground is an interactive tutorial that lets you test your code live in the browser to verify it can work with single-spa.

    \ No newline at end of file diff --git a/docs/5.x/ssr-overview/index.html b/docs/5.x/ssr-overview/index.html index ca7945fd9..afe75ebff 100644 --- a/docs/5.x/ssr-overview/index.html +++ b/docs/5.x/ssr-overview/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 5.x

    Server Side Rendering

    Intro to SSR

    @@ -79,6 +79,6 @@

    5. HydrateHydration (or rehydration) refers to browser Javascript initializing and attaching event listeners to the HTML sent by the server. There are several variants, including progressive rehydration and partial rehydration.

    In the context of microfrontends, hydration is done by the underlying UI framework of the microfrontend (React, Vue, Angular, etc). For example, in React, this is done by calling ReactDOM.hydrate(). The single-spa adapter libraries allow you to specify whether you are hydrating or mounting for the first time (see single-spa-react's renderType option).

    -

    The role of single-spa-layout is to determine which microfrontends should hydrate which parts of the DOM. This is done automatically when you call constructLayoutEngine and singleSpa.start(). If using TailorX instead of single-spa-layout, the Isomorphic Layout Composer Project serves a similar purpose as constructLayoutEngine.

    +

    The role of single-spa-layout is to determine which microfrontends should hydrate which parts of the DOM. This is done automatically when you call constructLayoutEngine and singleSpa.start(). If using TailorX instead of single-spa-layout, the Isomorphic Layout Composer Project serves a similar purpose as constructLayoutEngine.

    \ No newline at end of file diff --git a/docs/5.x/testing/e2e/index.html b/docs/5.x/testing/e2e/index.html index 12b7d418f..066b1fbe6 100644 --- a/docs/5.x/testing/e2e/index.html +++ b/docs/5.x/testing/e2e/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/docs/5.x/testing/units/index.html b/docs/5.x/testing/units/index.html index da11124f4..6d4297b67 100644 --- a/docs/5.x/testing/units/index.html +++ b/docs/5.x/testing/units/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 5.x

    Unit testing

    info

    As microfrontends gain widespread adoption, testing tools will catch up and the testing story will improve.

    @@ -50,6 +50,6 @@

    mocks direct
    .
    ├── __mocks__
    │ └── styleguide.js
    ├── src
    │ ├── react-mf-people.js
    │ └── ...
    ├── node_modules
    ├── jest.setup.js
    ├── ...
    └── jest.config.js

    setup file

    Jest uses a setup file to create globals mocks that can be utilized by every test or otherwise configure the test environment. If you were mocking localStorage or SystemJS this is a good place to configure those mocks. See more use-cases for a set-up file on Jest's offical documentation

    -
    // jest.setup.js
    // import Mocks for SystemJS mock below
    import peopleApplication from "@react-mf/people";
    // Mock SystemJS
    global.System = {
    import: jest.fn(mockImport),
    };

    function mockImport(importName) {
    // What you do in mock import will depend a lot on how you use SystemJS in the project and components you wish to test

    /* If I had already created a mock for `@react-mf/people` and I wanted to test this component:
    * https://github.com/react-microfrontends/planets/blob/main/src/planets-page/selected-planet/selected-planet.component.js#L5
    * I would want `System.import('@react-mf/people')` to resovle to my mock one way to accomplish this would be the following
    */
    if (importName === "@react-mf/people") {
    return Promise.resolve(peopleApplication);
    } else {
    console.warn("No mock module found");
    return Promise.resolve({});
    }
    }
    +
    // jest.setup.js
    // import Mocks for SystemJS mock below
    import peopleApplication from "@react-mf/people";
    // Mock SystemJS
    global.System = {
    import: jest.fn(mockImport),
    };

    function mockImport(importName) {
    // What you do in mock import will depend a lot on how you use SystemJS in the project and components you wish to test

    /* If I had already created a mock for `@react-mf/people` and I wanted to test this component:
    * https://github.com/react-microfrontends/planets/blob/main/src/planets-page/selected-planet/selected-planet.component.js#L5
    * I would want `System.import('@react-mf/people')` to resovle to my mock one way to accomplish this would be the following
    */
    if (importName === "@react-mf/people") {
    return Promise.resolve(peopleApplication);
    } else {
    console.warn("No mock module found");
    return Promise.resolve({});
    }
    }
    \ No newline at end of file diff --git a/docs/5.x/videos/index.html b/docs/5.x/videos/index.html index 7e0609e15..cef219a25 100644 --- a/docs/5.x/videos/index.html +++ b/docs/5.x/videos/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 5.x

    Video Tutorials

    A variety of video tutorials exist from both the single-spa core team and other community members.

    @@ -25,6 +25,6 @@

    From the

    Feel free to add your tutorial videos to this list!

    + \ No newline at end of file diff --git a/docs/api/index.html b/docs/api/index.html index e4be2c59e..cea17aa01 100644 --- a/docs/api/index.html +++ b/docs/api/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 6.x

    Applications API

    Single-spa exports named functions and variables rather than a single default export. @@ -239,6 +239,6 @@

    no-app-c

    When no applications were loaded, bootstrapped, mounted, unmounted, or unloaded, single-spa fires a single-spa:no-app-change event. This is the inverse of the single-spa:app-change event. Only one will be fired for each routing event.

    routing-event

    window.addEventListener("single-spa:routing-event", (evt) => {
    console.log("single-spa finished mounting/unmounting applications!");
    console.log(evt.detail.originalEvent); // PopStateEvent
    console.log(evt.detail.newAppStatuses); // { app1: MOUNTED, app2: NOT_MOUNTED }
    console.log(evt.detail.appsByNewStatus); // { MOUNTED: ['app1'], NOT_MOUNTED: ['app2'] }
    console.log(evt.detail.totalAppChanges); // 2
    });
    -

    A single-spa:routing-event event is fired every time that a routing event has occurred, which is after each hashchange, popstate, or triggerAppChange, even if no changes to registered applications were necessary; and after single-spa verified that all apps were correctly loaded, bootstrapped, mounted, and unmounted.

    +

    A single-spa:routing-event event is fired every time that a routing event has occurred, which is after each hashchange, popstate, or triggerAppChange, even if no changes to registered applications were necessary; and after single-spa verified that all apps were correctly loaded, bootstrapped, mounted, and unmounted.

    \ No newline at end of file diff --git a/docs/building-applications/index.html b/docs/building-applications/index.html index dcd91bfb1..7fb006aa8 100644 --- a/docs/building-applications/index.html +++ b/docs/building-applications/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 6.x

    Building single-spa applications

    A single-spa registered application is everything that a normal SPA is, except that it doesn't have an HTML page. In a single-spa world, your SPA contains many registered applications, where each has its own framework. Registered applications have their own client-side routing and their own frameworks/libraries. They render their own HTML and have full freedom to do whatever they want, whenever they are mounted. The concept of being mounted refers to whether a registered application is putting content on the DOM or not. What determines if a registered application is mounted is its activity function. Whenever a registered application is not mounted, it should remain completely dormant until mounted.

    @@ -82,6 +82,6 @@

    TimeoutsTransitioning between applications

    If you find yourself wanting to add transitions as applications are mounted and unmounted, then you'll probably want to tie into the bootstrap, mount, and unmount lifecycle methods. This single-spa transitions repo is a small proof-of-concept of how you can tie into these lifecycle methods to add transitions as your apps mount and unmount.

    -

    Transitions for pages within a mounted application can be handled entirely by the application itself. For example, using react-transition-group for React-based projects.

    +

    Transitions for pages within a mounted application can be handled entirely by the application itself. For example, using react-transition-group for React-based projects.

    \ No newline at end of file diff --git a/docs/code-of-conduct/index.html b/docs/code-of-conduct/index.html index 7b9d32576..1a025aac1 100644 --- a/docs/code-of-conduct/index.html +++ b/docs/code-of-conduct/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 6.x

    Code of Conduct

    This code of conduct outlines our expectations for participants within the single-spa community, as well as steps to reporting unacceptable behavior. We are committed to providing a welcoming and inspiring community for all and expect our code of conduct to be honored. Anyone who violates this code of conduct may be banned from the community.

    @@ -53,6 +53,6 @@

    Reporting I

    After filing a report, a representative will contact you personally. If the person who is harassing you is part of the response team, they will recuse themselves from handling your incident. A representative will then review the incident, follow up with any additional questions, and make a decision as to how to respond. We will respect confidentiality requests for the purpose of protecting victims of abuse.

    Anyone asked to stop unacceptable behavior is expected to comply immediately. If an individual engages in unacceptable behavior, the representative may take any action they deem appropriate, up to and including a permanent ban from our community without warning.

    -

    This Code Of Conduct follows the template established by the TODO Group.

    +

    This Code Of Conduct follows the template established by the TODO Group.

    \ No newline at end of file diff --git a/docs/configuration/index.html b/docs/configuration/index.html index f828952e3..4b191b633 100644 --- a/docs/configuration/index.html +++ b/docs/configuration/index.html @@ -14,8 +14,8 @@ - - + + +
    <div id="single-spa-application:app-name"></div>
    <div id="single-spa-application:other-app"></div>
    \ No newline at end of file diff --git a/docs/contributing-overview/index.html b/docs/contributing-overview/index.html index c5fd2843d..b99ae328c 100644 --- a/docs/contributing-overview/index.html +++ b/docs/contributing-overview/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 6.x

    Contributing to Single-spa

    List of current contributors

    @@ -86,7 +86,7 @@

    Push itCommunity

    -

    Discussions about single-spa take place on the single-spa repository's Issues and Pull Requests sections. Anybody is welcome to join these conversations. There is also a Slack workspace for regular updates.

    -

    Wherever possible, do not take these conversations to private channels, including contacting the maintainers directly. Keeping communication public means everybody can benefit and learn from the conversation.

    +

    Discussions about single-spa take place on the single-spa repository's Issues and Pull Requests sections. Anybody is welcome to join these conversations. There is also a Slack workspace for regular updates.

    +

    Wherever possible, do not take these conversations to private channels, including contacting the maintainers directly. Keeping communication public means everybody can benefit and learn from the conversation.

    \ No newline at end of file diff --git a/docs/create-single-spa/index.html b/docs/create-single-spa/index.html index e2cdceeef..f423d77af 100644 --- a/docs/create-single-spa/index.html +++ b/docs/create-single-spa/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 6.x

    create-single-spa

    Single-spa offers a CLI for those who prefer autogenerated and managed configurations for webpack, babel, jest, etc. You do not have to use the CLI in order to use single-spa.

    @@ -69,6 +69,6 @@

    clearAllIn
    import { clearAllIntervals } from "single-spa-web-server-utils";

    clearAllIntervals();

    reset

    This clears all intervals (see clearAllIntervals), and also clears the in-memory cache of all import maps. In other words, after reset() is called, getImportMaps() will always result in a new network request to fetch the import map.

    -
    import { reset } from "single-spa-web-server-utils";

    reset();
    +
    import { reset } from "single-spa-web-server-utils";

    reset();
    \ No newline at end of file diff --git a/docs/devtools/index.html b/docs/devtools/index.html index f68928d82..7117bed20 100644 --- a/docs/devtools/index.html +++ b/docs/devtools/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 6.x

    single-spa-inspector

    The single-spa-inspector is a Firefox/Chrome devtools extension to provide utilities for helping with single-spa applications. Github project.

    @@ -40,6 +40,6 @@

    Con
    // must be called "devtools"
    export const devtools = {
    overlays: {
    // selectors is required for overlays to work
    selectors: [
    // an array of CSS selector strings, meant to be unique ways to identify the outermost container of your app
    // you can have more than one, for cases like parcels or different containers for differet views
    "#my-app",
    ".some-container .app",
    ],
    // options is optional
    options: {
    // these options allow you some control over how the overlay div looks/behaves
    // the listed values below are the defaults

    width: "100%",
    height: "100%",
    zIndex: 40,
    position: "absolute",
    top: 0,
    left: 0,
    color: "#000", // the default for this is actually based on the app's name, so it's dynamic. can be a hex or a CSS color name
    background: "#000", // the default for this is actually based on the app's name, so it's dynamic. can be a hex or a CSS color name
    textBlocks: [
    // allows you to add additional text to the overlay. for example, you can add the name of the team/squad that owns this app
    // each string in this array will be in a new div
    // 'blue squad', 'is awesome'
    // turns into:
    // <div>blue squad</div><div>is awesome</div>
    ],
    },
    },
    };

    import-map-overrides

    If your environment uses import-maps, single-spa Inspector provides an interface for adding import-map overrides when utilizing the import-map-overrides library. Once the installation requirements for import-map-overrides are completed, you can add, remove, and refresh the page with your overrides.

    -

    Example of single-spa Inspector extension with import-maps overrides

    +

    Example of single-spa Inspector extension with import-maps overrides

    \ No newline at end of file diff --git a/docs/ecosystem-alpinejs/index.html b/docs/ecosystem-alpinejs/index.html index a17c1b27b..d001aa3e8 100644 --- a/docs/ecosystem-alpinejs/index.html +++ b/docs/ecosystem-alpinejs/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/docs/ecosystem-angular/index.html b/docs/ecosystem-angular/index.html index 2ba270dc2..4c6d2d878 100644 --- a/docs/ecosystem-angular/index.html +++ b/docs/ecosystem-angular/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 6.x

    single-spa-angular

    Project Status

    @@ -27,7 +27,7 @@

    Introduction

    The documentation here is extensive, so use the sidenav on the right. 👉👉👉

    Community

    -

    Join the #angular channel in single-spa's Slack workspace.

    +

    Join the #angular channel in single-spa's Slack workspace.

    Demo

    https://coexisting-angular-microfrontends.surge.sh

    Starter repo

    @@ -479,6 +479,6 @@

    const singleSpaAngularWebpack =
    require("single-spa-angular/lib/webpack").default;

    module.exports = (config, options) => {
    const singleSpaWebpackConfig = singleSpaAngularWebpack(config, options);
    singleSpaWebpackConfig.externals = [/^@org\/api$/];
    return singleSpaWebpackConfig;
    };

    But this library should be part of root application bundle and shared with import maps, for example:

    -
    {
    "imports": {
    "@org/api": "http://localhost:8080/api.js"
    }
    }
    +
    {
    "imports": {
    "@org/api": "http://localhost:8080/api.js"
    }
    }
    \ No newline at end of file diff --git a/docs/ecosystem-angularjs/index.html b/docs/ecosystem-angularjs/index.html index bf1b19322..b85941f61 100644 --- a/docs/ecosystem-angularjs/index.html +++ b/docs/ecosystem-angularjs/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    + \ No newline at end of file diff --git a/docs/ecosystem-backbone/index.html b/docs/ecosystem-backbone/index.html index 0096d1792..61c9471f6 100644 --- a/docs/ecosystem-backbone/index.html +++ b/docs/ecosystem-backbone/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    + \ No newline at end of file diff --git a/docs/ecosystem-css/index.html b/docs/ecosystem-css/index.html index 0fa1301fb..60d5cd4f7 100644 --- a/docs/ecosystem-css/index.html +++ b/docs/ecosystem-css/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 6.x

    CSS

    In a microfrontends architecture, it's important to have both shared CSS and microfrontend-specific CSS. There should only be one copy of all shared CSS, and CSS specific to a microfrontend should be scoped so that class names do not collide between microfrontends.

    @@ -125,6 +125,6 @@

    Webpack Plugi

    single-spa-css includes a Webpack plugin that integrates with mini-css-extract-plugin, which allows you to load CSS files that are extracted and otherwise would not be loaded. The Webpack plugin exposes the names of the extracted CSS files to your bundle under the __webpack_require__.cssAssets and __webpack_require__.cssAssetFileName variables. The cssAssets variable contains the name of the Webpack chunk, and the cssAssetFileName function converts the chunk name into the extracted CSS asset's file name. These can be used manually, or you can specify the webpackExtractedCss option in single-spa-css to have it automatically mount and unmount those CSS files.

    Usage

    In your Webpack config, add the following:

    -
    const MiniCssExtractPlugin = require("mini-css-extract-plugin");
    const ExposeRuntimeCssAssetsPlugin = require("single-spa-css/ExposeRuntimeCssAssetsPlugin.cjs");

    module.exports = {
    plugins: [
    new MiniCssExtractPlugin({
    filename: "[name].css",
    }),
    new ExposeRuntimeCssAssetsPlugin({
    // The filename here must match the filename for the MiniCssExtractPlugin
    filename: "[name].css",
    }),
    ],
    };
    +
    const MiniCssExtractPlugin = require("mini-css-extract-plugin");
    const ExposeRuntimeCssAssetsPlugin = require("single-spa-css/ExposeRuntimeCssAssetsPlugin.cjs");

    module.exports = {
    plugins: [
    new MiniCssExtractPlugin({
    filename: "[name].css",
    }),
    new ExposeRuntimeCssAssetsPlugin({
    // The filename here must match the filename for the MiniCssExtractPlugin
    filename: "[name].css",
    }),
    ],
    };
    \ No newline at end of file diff --git a/docs/ecosystem-cycle/index.html b/docs/ecosystem-cycle/index.html index b047d3541..39321a245 100644 --- a/docs/ecosystem-cycle/index.html +++ b/docs/ecosystem-cycle/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/docs/ecosystem-dojo/index.html b/docs/ecosystem-dojo/index.html index d8fb06875..481a942d4 100644 --- a/docs/ecosystem-dojo/index.html +++ b/docs/ecosystem-dojo/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/docs/ecosystem-ember/index.html b/docs/ecosystem-ember/index.html index bac681976..1c72f4009 100644 --- a/docs/ecosystem-ember/index.html +++ b/docs/ecosystem-ember/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 6.x

    single-spa-ember

    single-spa-ember is a helper library that helps implement single-spa registered application lifecycle functions (bootstrap, mount and unmount) for use with Ember.js. Check out the single-spa-ember github.

    @@ -58,6 +58,6 @@

    Usage w

    In your single-spa root application (which is separate from anything generated by ember cli):

    // root-application.js
    import * as singleSpa from "single-spa";
    import { loadEmberApp } from "single-spa-ember";

    singleSpa.registerApplication("ember-app", loadingFunction, activityFunction);

    function activityFunction(location) {
    // Only render the ember app when the url hash starts with ember
    return location.hash.startsWith("ember");
    }

    // single-spa-ember helps us load the script tags and give the ember app module to single-spa.
    function loadingFunction() {
    const appName = "ember-app";
    const appUrl = "/dist/ember-app/assets/ember-app.js";
    const vendorUrl = "/dist/ember-app/assets/vendor.js"; // Optional if you have one vendor bundle used for many different ember apps
    return loadEmberApp(appName, appUrl, vendorUrl);
    }

    In your app.js file (that is generated by ember cli)

    -
    // app.js (the ember application)
    import Ember from "ember";
    import Resolver from "./resolver";
    import loadInitializers from "ember-load-initializers";
    import config from "./config/environment";
    import singleSpaEmber from "single-spa-ember";

    // This part is generated by the ember cli
    const App = Ember.Application.extend({
    modulePrefix: config.modulePrefix,
    podModulePrefix: config.podModulePrefix,
    Resolver,
    });

    loadInitializers(App, config.modulePrefix);

    export default App;

    // This is the single-spa part
    const emberLifecycles = singleSpaEmber({
    App, // required
    appName: "ember-app", // required
    createOpts: {
    // optional
    rootElement: "#ember-app",
    },
    });

    // Single-spa lifecycles.
    export const bootstrap = emberLifecycles.bootstrap;
    export const mount = emberLifecycles.mount;
    export const unmount = emberLifecycles.unmount;

    +
    // app.js (the ember application)
    import Ember from "ember";
    import Resolver from "./resolver";
    import loadInitializers from "ember-load-initializers";
    import config from "./config/environment";
    import singleSpaEmber from "single-spa-ember";

    // This part is generated by the ember cli
    const App = Ember.Application.extend({
    modulePrefix: config.modulePrefix,
    podModulePrefix: config.podModulePrefix,
    Resolver,
    });

    loadInitializers(App, config.modulePrefix);

    export default App;

    // This is the single-spa part
    const emberLifecycles = singleSpaEmber({
    App, // required
    appName: "ember-app", // required
    createOpts: {
    // optional
    rootElement: "#ember-app",
    },
    });

    // Single-spa lifecycles.
    export const bootstrap = emberLifecycles.bootstrap;
    export const mount = emberLifecycles.mount;
    export const unmount = emberLifecycles.unmount;
    \ No newline at end of file diff --git a/docs/ecosystem-html-web-components/index.html b/docs/ecosystem-html-web-components/index.html index c6f2b33c8..485a9d353 100644 --- a/docs/ecosystem-html-web-components/index.html +++ b/docs/ecosystem-html-web-components/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    + \ No newline at end of file diff --git a/docs/ecosystem-inferno/index.html b/docs/ecosystem-inferno/index.html index 3d9b5a022..8297f4f93 100644 --- a/docs/ecosystem-inferno/index.html +++ b/docs/ecosystem-inferno/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/docs/ecosystem-leaked-globals/index.html b/docs/ecosystem-leaked-globals/index.html index 0c8290ca7..b65407570 100644 --- a/docs/ecosystem-leaked-globals/index.html +++ b/docs/ecosystem-leaked-globals/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/docs/ecosystem-preact/index.html b/docs/ecosystem-preact/index.html index 51be1fc5e..e4bbb8660 100644 --- a/docs/ecosystem-preact/index.html +++ b/docs/ecosystem-preact/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/docs/ecosystem-react/index.html b/docs/ecosystem-react/index.html index f9797d6c5..12b42ec05 100644 --- a/docs/ecosystem-react/index.html +++ b/docs/ecosystem-react/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 6.x

    single-spa-react

    Build Status

    @@ -75,6 +75,6 @@

    Parcel propsExamples

    // Use this import path in environments that support package.json exports
    // See https://nodejs.org/dist/latest-v14.x/docs/api/packages.html#packages_package_entry_points
    // and see https://github.com/single-spa/single-spa-react/releases/tag/v3.0.0
    // Use this in Webpack 5 and recent versions of Node
    import Parcel from 'single-spa-react/parcel'

    // Use this import path in environments that don't support package.json exports
    // See https://nodejs.org/dist/latest-v14.x/docs/api/packages.html#packages_package_entry_points
    // and see https://github.com/single-spa/single-spa-react/releases/tag/v3.0.0
    // Use this in Webpack 4 and older versions of Node
    import Parcel from 'single-spa-react/lib/esm/parcel'


    import * as parcelConfig from './my-parcel.js'

    // config is required. The parcel will be mounted inside of the
    // of a div inside of the react component tree
    <Parcel
    config={parcelConfig}

    wrapWith="div"
    handleError={err => console.error(err)}

    customProp1="customPropValue2"
    customProp2="customPropValue2"
    />

    // If you pass in an appendTo prop, the parcel will be mounted there instead of
    // to a dom node inside of the current react component tree
    <Parcel
    config={parcelConfig}
    wrapWith="div"
    appendTo={document.body}
    />

    // You can also pass in a "loading function" as the config.
    // The loading function must return a promise that resolves with the parcel config.
    // The parcel will be mounted once the promise resolves.
    <Parcel
    config={() => import('./my-parcel.js')}
    wrapWith="div"
    />

    // If you are rendering the Parcel component from a single-spa application, you do not need to pass a mountParcel prop.
    // But if you have a separate react component tree that is not rendered by single-spa-react, you **must** pass in a mountParcel prop
    // In general, it is preferred to use an application's mountParcel function instead of the single-spa's root mountParcel function,
    // so that single-spa can keep track of the parent-child relationship and automatically unmount the application's parcels when the application
    // unmounts
    <Parcel
    mountParcel={singleSpa.mountParcel}
    config={parcelConfig}
    wrapWith="div"
    />

    // Add styles to wrapWith element.
    <Parcel
    config={parcelConfig}
    wrapWith="div"
    wrapStyle={{ background: 'black' }}
    />

    // Add classNames to wrapWith element.
    <Parcel
    config={parcelConfig}
    wrapWith="div"
    wrapClassName="wrapper"
    />

    Create React App

    -

    See FAQ for CRA.

    +

    See FAQ for CRA.

    \ No newline at end of file diff --git a/docs/ecosystem-riot/index.html b/docs/ecosystem-riot/index.html index a6bdc1ea1..b98838276 100644 --- a/docs/ecosystem-riot/index.html +++ b/docs/ecosystem-riot/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/docs/ecosystem-snowpack/index.html b/docs/ecosystem-snowpack/index.html index 680fc5c43..dc24f640a 100644 --- a/docs/ecosystem-snowpack/index.html +++ b/docs/ecosystem-snowpack/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 6.x

    Snowpack

    Snowpack is a tool for both local development and the building of applications. It uses in-browser ES modules during development, and then bundles with webpack (or other build tools) for production.

    @@ -36,6 +36,6 @@

    N
    • The browser and SystemJS maintain separate module registries. This means that you can't share imports between SystemJS and native modules. So if you are doing an import map override for a Snowpack application on a page that also uses SystemJS, you may end up with multiple instances of Vue or React (and other shared libraries), which is different than how things will work in production. This is generally okay, except for situations where the Vue instance is modified via Vue.use().
    • This PR to SystemJS shows how you can populate native modules into the SystemJS registry, allowing for one-way sharing of modules between the two registries. The PR was closed due to some edge cases, but it generally works. Even though the PR is closed, you can paste the ESM extra into your root config and it will work. If you have interest in driving forward better SystemJS + ESM compatibility, comment on Github or Slack with your interest.
    • -

    + \ No newline at end of file diff --git a/docs/ecosystem-svelte/index.html b/docs/ecosystem-svelte/index.html index c7ade7341..00c97a1a9 100644 --- a/docs/ecosystem-svelte/index.html +++ b/docs/ecosystem-svelte/index.html @@ -14,8 +14,8 @@ - - + + +

    All single-spa props are passed to the svelte component as props. The props provided to singleSpaSvelte({props: {...}}) are merged with the single-spa props.

    \ No newline at end of file diff --git a/docs/ecosystem-vite/index.html b/docs/ecosystem-vite/index.html index 2adc4b09c..458ce36f0 100644 --- a/docs/ecosystem-vite/index.html +++ b/docs/ecosystem-vite/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 6.x

    Vite

    Vite is a tool for both local development and the building of applications. It was created within the Vue ecosystem, but can be used with other UI frameworks, too.

    @@ -85,6 +85,6 @@

    Micr

    To convert a Vite project to a micro-frontend project, very little configuration is needed, plus a file that exports the single-spa lifecycle functions.

    // vite.config.ts for a Vite + React project

    import react from "@vitejs/plugin-react";
    import vitePluginSingleSpa from "vite-plugin-single-spa";

    // https://vitejs.dev/config/
    export default defineConfig({
    plugins: [
    react(),
    vitePluginSingleSpa({
    serverPort: 4101,
    spaEntryPoints: "src/spa.tsx",
    }),
    ],
    });
    // src/spa.tsx

    import React from 'react';
    import ReactDOMClient from 'react-dom/client';
    // @ts-expect-error
    import singleSpaReact from 'single-spa-react';
    import App from './App';
    import { cssLifecycleFactory } from 'vite-plugin-single-spa/ex';

    const lc = singleSpaReact({
    React,
    ReactDOMClient,
    rootComponent: App,
    errorBoundary(err: any, _info: any, _props: any) {
    return <div>Error: {err}</div>
    }
    });

    // IMPORTANT: The argument passed here depends on the file name.
    const cssLc = cssLifecycleFactory('spa');

    export const bootstrap = [cssLc.bootstrap, lc.bootstrap];
    export const mount = [cssLc.mount, lc.mount];
    export const unmount = [cssLc.unmount, lc.unmount];
    -

    Using cssLifecycleFactory is not required. You may use your own or a third-party CSS mounting algorithm if you want.

    +

    Using cssLifecycleFactory is not required. You may use your own or a third-party CSS mounting algorithm if you want.

    \ No newline at end of file diff --git a/docs/ecosystem-vue/index.html b/docs/ecosystem-vue/index.html index 1a4ebe4c7..904bd4e0d 100644 --- a/docs/ecosystem-vue/index.html +++ b/docs/ecosystem-vue/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 6.x

    single-spa-vue

    single-spa-vue is a helper library that helps implement single-spa registered application lifecycle functions (bootstrap, mount and unmount) for use with Vue.js. Check out the single-spa-vue github.

    @@ -101,6 +101,6 @@

    Webpack

    vue-cli-plugin-single-spa sets the webpack public path via SystemJSPublicPathWebpackPlugin. By default, the public path is set to match the following output directory structure:

    dist/
    js/
    app.js
    css/
    main.css

    With this directory structure (which is the Vue CLI default), the public path should not include the js folder. This is accomplished by setting rootDirectoryLevel to be 2. If this doesn't match your directory structure or setup, you can change the rootDirectoryLevel with the following code in your vue.config.js or webpack.config.js:

    -
    // vue.config.js
    module.exports = {
    chainWebpack(config) {
    config.plugin("SystemJSPublicPathWebpackPlugin").tap((args) => {
    args[0].rootDirectoryLevel = 1;
    return args;
    });
    },
    };

    +
    // vue.config.js
    module.exports = {
    chainWebpack(config) {
    config.plugin("SystemJSPublicPathWebpackPlugin").tap((args) => {
    args[0].rootDirectoryLevel = 1;
    return args;
    });
    },
    };
    \ No newline at end of file diff --git a/docs/ecosystem/index.html b/docs/ecosystem/index.html index d46852533..3bfbb74f1 100644 --- a/docs/ecosystem/index.html +++ b/docs/ecosystem/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/docs/examples/index.html b/docs/examples/index.html index d9a87b758..3a5efa682 100644 --- a/docs/examples/index.html +++ b/docs/examples/index.html @@ -14,8 +14,8 @@ - - + + +

    Have your own example or starter repo? Submit a PR to add yours to this list.

    \ No newline at end of file diff --git a/docs/faq/index.html b/docs/faq/index.html index 5c96f5746..8ff25550d 100644 --- a/docs/faq/index.html +++ b/docs/faq/index.html @@ -14,8 +14,8 @@ - - + + +

    See the documentation for unit and E2E tests.

    \ No newline at end of file diff --git a/docs/getting-started-overview/index.html b/docs/getting-started-overview/index.html index 9a117fc7e..8d57241f6 100644 --- a/docs/getting-started-overview/index.html +++ b/docs/getting-started-overview/index.html @@ -14,12 +14,12 @@ - - + +
    Skip to main content
    Version: 6.x

    Getting Started with single-spa

    JavaScript Microfrontends

    -

    Join the chat on Slack

    +

    Join the chat on Slack

    single-spa is a framework for bringing together multiple JavaScript microfrontends in a frontend application. Architecting your frontend using single-spa enables many benefits, such as:

    +

    Is your company or project using single-spa? Let us know by submitting a PR to this section!

    \ No newline at end of file diff --git a/docs/glossary/index.html b/docs/glossary/index.html index 500e345e8..4aa63e568 100644 --- a/docs/glossary/index.html +++ b/docs/glossary/index.html @@ -14,10 +14,10 @@ - - + + -
    Skip to main content
    Version: 6.x

    Glossary

    Activity Function
    Application
    Application
    Helpers
    are a library that already implements single-spa lifecycle functions for a specific framework.
    Lifecycles
    module loader
    Microservices
    registerApplication
    +
    Skip to main content
    Version: 6.x

    Glossary

    Activity Function
    Application
    Application
    Helpers
    are a library that already implements single-spa lifecycle functions for a specific framework.
    Lifecycles
    module loader
    Microservices
    registerApplication
    \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index 30fd07211..367dc65d6 100644 --- a/docs/index.html +++ b/docs/index.html @@ -14,8 +14,8 @@ - - + +
    diff --git a/docs/layout-api/index.html b/docs/layout-api/index.html index d7852e435..fb2c078b4 100644 --- a/docs/layout-api/index.html +++ b/docs/layout-api/index.html @@ -14,8 +14,8 @@ - - + + +

    A promise that resolves when headers (but not necessarily HTTP response body) are sent.

    \ No newline at end of file diff --git a/docs/layout-definition/index.html b/docs/layout-definition/index.html index eaeb8adb4..112f0f4e1 100644 --- a/docs/layout-definition/index.html +++ b/docs/layout-definition/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    +
    const myErrorParcel = singleSpaReact({...})

    const routes = constructRoutes(document.querySelector('#single-spa-layout'), {
    errors: {
    navError: myErrorParcel
    // alternatively:
    // navError: "<h1>Oops! The navbar isn't working right now</h1>"
    }
    })
    \ No newline at end of file diff --git a/docs/layout-overview/index.html b/docs/layout-overview/index.html index 882d4303c..838cd1365 100644 --- a/docs/layout-overview/index.html +++ b/docs/layout-overview/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    +
    import { registerApplication, start } from "single-spa";
    import {
    constructApplications,
    constructRoutes,
    constructLayoutEngine,
    } from "single-spa-layout";

    const routes = constructRoutes(document.querySelector("#single-spa-layout"));
    const applications = constructApplications({
    routes,
    loadApp({ name }) {
    return System.import(name);
    },
    });
    const layoutEngine = constructLayoutEngine({ routes, applications });

    applications.forEach(registerApplication);
    start();
    \ No newline at end of file diff --git a/docs/microfrontends-concept/index.html b/docs/microfrontends-concept/index.html index ce3ea5d8f..333e233e1 100644 --- a/docs/microfrontends-concept/index.html +++ b/docs/microfrontends-concept/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 6.x

    Concept: Microfrontends

    @@ -43,6 +43,6 @@

    Relationship to single-spa

    single-spa is a small, 5kb (gzipped) npm package that orchestrates the mounting and unmounting of your microfrontends. It knows when to mount the applications based on activity functions and can do so in a framework agnostic way with the help of small adapter libraries.

    Performance

    -

    Microfrontends are often more performant than the monoliths from which they originate. This is due to built-in lazy loading (via loading functions) and other performance-related best practices. Your monolith likely has "skeletons in its closet" - microfrontends gives you a migration path that will expose and resolve the problems caused by those skeletons. One important performance consideration is to share a single instance of large libraries (such as React, Vue, or Angular), which is highly encouraged. To do so, see our recommended setup.

    +

    Microfrontends are often more performant than the monoliths from which they originate. This is due to built-in lazy loading (via loading functions) and other performance-related best practices. Your monolith likely has "skeletons in its closet" - microfrontends gives you a migration path that will expose and resolve the problems caused by those skeletons. One important performance consideration is to share a single instance of large libraries (such as React, Vue, or Angular), which is highly encouraged. To do so, see our recommended setup.

    \ No newline at end of file diff --git a/docs/migrating-existing-spas/index.html b/docs/migrating-existing-spas/index.html index b5c8e65ad..d9e5c70ab 100644 --- a/docs/migrating-existing-spas/index.html +++ b/docs/migrating-existing-spas/index.html @@ -14,8 +14,8 @@ - - + + +you need into your single spa config.

    \ No newline at end of file diff --git a/docs/module-types/index.html b/docs/module-types/index.html index 6c58b2d6c..e8b4067a1 100644 --- a/docs/module-types/index.html +++ b/docs/module-types/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/docs/next/index.html b/docs/next/index.html index 0c63026a3..04bb8479b 100644 --- a/docs/next/index.html +++ b/docs/next/index.html @@ -14,10 +14,10 @@ - - + + - + \ No newline at end of file diff --git a/docs/parcels-api/index.html b/docs/parcels-api/index.html index 7b251c2a3..b266082e6 100644 --- a/docs/parcels-api/index.html +++ b/docs/parcels-api/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 6.x

    Parcels API

    Most parcel methods will be called on the parcel itself, with the exception being around mounting.

    @@ -70,6 +70,6 @@

    bootstrapPr

    mountPromise

    parcel.mountPromise() returns a promise that will resolve once the parcel has been mounted. This is helpful for knowing exactly when a parcel has been appended to the DOM

    unmountPromise

    -

    parcel.unmountPromise() returns a promise that will resolve once the parcel has been unmounted.

    +

    parcel.unmountPromise() returns a promise that will resolve once the parcel has been unmounted.

    \ No newline at end of file diff --git a/docs/parcels-overview/index.html b/docs/parcels-overview/index.html index 43766e931..60acfe610 100644 --- a/docs/parcels-overview/index.html +++ b/docs/parcels-overview/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 6.x

    Parcels

    Parcels are an advanced feature of single-spa. We recommend that you use applications as the primary type of microfrontend in your architecture. See this explanation for more details

    @@ -80,6 +80,6 @@

    lifecycle prop. You will need to store and manage that function yourself in your application.

    Example of storing the application specific mountParcel API:

    // App1
    let mountParcel
    export const bootstrap = [
    (props) => {
    mountParcel = props.mountParcel
    return Promise.resolve()
    },
    // more bootstrap lifecycles if necessary
    ]
    ...
    -

    note: some libraries (such as react) support a framework specific context that makes it easy to store/manage. In those cases we've written some helper methods to abstract away the need to manage and store the mountParcel method.

    +

    note: some libraries (such as react) support a framework specific context that makes it easy to store/manage. In those cases we've written some helper methods to abstract away the need to manage and store the mountParcel method.

    \ No newline at end of file diff --git a/docs/recommended-setup/index.html b/docs/recommended-setup/index.html index edfdd701b..42a39488f 100644 --- a/docs/recommended-setup/index.html +++ b/docs/recommended-setup/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 6.x

    The Recommended Setup

    The single-spa npm package is not opinionated about your build tools, CI process, or local development workflow. However, to implement single-spa you will have to figure all of those things out (and more). To help you decide how to approach these problems, the single-spa core team has put together a "recommended setup" that gives an opinionated approach to solving the practical problems of microfrontends.

    @@ -190,6 +190,6 @@

    UI StateState management

    The single-spa core team cautions against using redux, mobx, and other global state management libraries. However, if you'd like to use a state management library, we recommend keeping the state management tool specific to a single repository / microfrontend instead of a single store for all of your microfrontends. The reason is that microfrontends are not truly decoupled or framework agnostic if they all must use a global store. You cannot independently deploy a microfrontend if it relies on the global store's state to be a specific shape or have specific actions fired by other microfrontends - to do so you'd have to think really hard about whether your changes to the global store are backwards and forwards compatible with all other microfrontends. Additionally, managing global state during route transitions is hard enough without the complexity of multiple microfrontends contributing to and consuming the global state.

    -

    Instead of a global store, the single-spa core team recommends using local component state for your components, or a store for each of your microfrontends. See the above section "Inter-app communication" for more related information.

    +

    Instead of a global store, the single-spa core team recommends using local component state for your components, or a store for each of your microfrontends. See the above section "Inter-app communication" for more related information.

    \ No newline at end of file diff --git a/docs/separating-applications/index.html b/docs/separating-applications/index.html index a7bbb455f..f8764df35 100644 --- a/docs/separating-applications/index.html +++ b/docs/separating-applications/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 6.x

    Splitting up applications

    In a large, microserviced system, your root single-spa configuration and each of the applications should probably have its own git repository. How to do that in a JavaScript project isn't necessarily clear, so some options are listed below.

    @@ -60,6 +60,6 @@

    module loader such as SystemJS that can download and execute JavaScript code in the browser from dynamic urls.

    Comparison

    -
    Separate code repositories possibleIndependent CI buildsSeparate deploymentsExamples
    NPM Packages1
    Monorepo 1 11
    Module loading1 2 3
    +
    Separate code repositories possibleIndependent CI buildsSeparate deploymentsExamples
    NPM Packages1
    Monorepo 1 11
    Module loading1 2 3
    \ No newline at end of file diff --git a/docs/shared-webpack-configs/index.html b/docs/shared-webpack-configs/index.html index 1f1e91427..2032f95a3 100644 --- a/docs/shared-webpack-configs/index.html +++ b/docs/shared-webpack-configs/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 6.x

    Shared Webpack configs

    single-spa also publishes a few shared Webpack config packages that include basics needed for creating single-spa applications. These configs are used by applications generated with create-single-spa, and can be used as a starting point to extend/modify a custom configuration for your organization/team.

    @@ -68,6 +68,6 @@

    Replacing

    Use webpack-merge's mergeWithCustomize to resolve duplicate plugins or replace instances. Duplicate plugins often result in cryptic errors!

    When referencing a loader that is installed as a dependency of webpack-config-single-spa, use require.resolve to ensure its path is resolved correctly.

    Example: replace HtmlWebpackPlugin instance

    -
    const { mergeWithCustomize, unique } = require("webpack-merge");
    const singleSpaDefaults = require("webpack-config-single-spa");
    const HtmlWebpackPlugin = require("html-webpack-plugin");

    const merge = mergeWithCustomize({
    customizeArray: unique(
    "plugins",
    ["HtmlWebpackPlugin"],
    (plugin) => plugin.constructor && plugin.constructor.name,
    ),
    });

    module.exports = (env, argv) => {
    const orgName = "example";
    const myEnv = process.env.NODE_ENV || "development";

    const defaultConfig = singleSpaDefaults({
    orgName,
    projectName: "custom-root-config",
    webpackConfigEnv: env,
    argv,
    });

    const config = merge(defaultConfig, {
    plugins: [
    new HtmlWebpackPlugin({
    inject: false,
    template: "src/custom.ejs",
    templateParameters: {
    isLocal: env?.isLocal,
    // additional templateParameters can now be supplied
    orgName,
    environment: myEnv,
    },
    }),
    ],
    });

    // console.dir(config, null, 2) // useful for debugging
    return config;
    };
    +
    const { mergeWithCustomize, unique } = require("webpack-merge");
    const singleSpaDefaults = require("webpack-config-single-spa");
    const HtmlWebpackPlugin = require("html-webpack-plugin");

    const merge = mergeWithCustomize({
    customizeArray: unique(
    "plugins",
    ["HtmlWebpackPlugin"],
    (plugin) => plugin.constructor && plugin.constructor.name,
    ),
    });

    module.exports = (env, argv) => {
    const orgName = "example";
    const myEnv = process.env.NODE_ENV || "development";

    const defaultConfig = singleSpaDefaults({
    orgName,
    projectName: "custom-root-config",
    webpackConfigEnv: env,
    argv,
    });

    const config = merge(defaultConfig, {
    plugins: [
    new HtmlWebpackPlugin({
    inject: false,
    template: "src/custom.ejs",
    templateParameters: {
    isLocal: env?.isLocal,
    // additional templateParameters can now be supplied
    orgName,
    environment: myEnv,
    },
    }),
    ],
    });

    // console.dir(config, null, 2) // useful for debugging
    return config;
    };
    \ No newline at end of file diff --git a/docs/single-spa-playground/index.html b/docs/single-spa-playground/index.html index 21735691a..3f0cecc92 100644 --- a/docs/single-spa-playground/index.html +++ b/docs/single-spa-playground/index.html @@ -14,12 +14,12 @@ - - + + +

    The single-spa playground is an interactive tutorial that lets you test your code live in the browser to verify it can work with single-spa.

    \ No newline at end of file diff --git a/docs/ssr-overview/index.html b/docs/ssr-overview/index.html index 4a43eceaa..c3933cf43 100644 --- a/docs/ssr-overview/index.html +++ b/docs/ssr-overview/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 6.x

    Server Side Rendering

    Intro to SSR

    @@ -79,6 +79,6 @@

    5. HydrateHydration (or rehydration) refers to browser Javascript initializing and attaching event listeners to the HTML sent by the server. There are several variants, including progressive rehydration and partial rehydration.

    In the context of microfrontends, hydration is done by the underlying UI framework of the microfrontend (React, Vue, Angular, etc). For example, in React, this is done by calling ReactDOM.hydrate(). The single-spa adapter libraries allow you to specify whether you are hydrating or mounting for the first time (see single-spa-react's renderType option).

    -

    The role of single-spa-layout is to determine which microfrontends should hydrate which parts of the DOM. This is done automatically when you call constructLayoutEngine and singleSpa.start(). If using TailorX instead of single-spa-layout, the Isomorphic Layout Composer Project serves a similar purpose as constructLayoutEngine.

    +

    The role of single-spa-layout is to determine which microfrontends should hydrate which parts of the DOM. This is done automatically when you call constructLayoutEngine and singleSpa.start(). If using TailorX instead of single-spa-layout, the Isomorphic Layout Composer Project serves a similar purpose as constructLayoutEngine.

    \ No newline at end of file diff --git a/docs/testing/e2e/index.html b/docs/testing/e2e/index.html index 24108ef96..c29c378a9 100644 --- a/docs/testing/e2e/index.html +++ b/docs/testing/e2e/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/docs/testing/units/index.html b/docs/testing/units/index.html index 4b3145829..ff57c08db 100644 --- a/docs/testing/units/index.html +++ b/docs/testing/units/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    Version: 6.x

    Unit testing

    info

    As microfrontends gain widespread adoption, testing tools will catch up and the testing story will improve.

    @@ -50,6 +50,6 @@

    mocks direct
    .
    ├── __mocks__
    │ └── styleguide.js
    ├── src
    │ ├── react-mf-people.js
    │ └── ...
    ├── node_modules
    ├── jest.setup.js
    ├── ...
    └── jest.config.js

    setup file

    Jest uses a setup file to create globals mocks that can be utilized by every test or otherwise configure the test environment. If you were mocking localStorage or SystemJS this is a good place to configure those mocks. See more use-cases for a set-up file on Jest's offical documentation

    -
    // jest.setup.js
    // import Mocks for SystemJS mock below
    import peopleApplication from "@react-mf/people";
    // Mock SystemJS
    global.System = {
    import: jest.fn(mockImport),
    };

    function mockImport(importName) {
    // What you do in mock import will depend a lot on how you use SystemJS in the project and components you wish to test

    /* If I had already created a mock for `@react-mf/people` and I wanted to test this component:
    * https://github.com/react-microfrontends/planets/blob/main/src/planets-page/selected-planet/selected-planet.component.js#L5
    * I would want `System.import('@react-mf/people')` to resovle to my mock one way to accomplish this would be the following
    */
    if (importName === "@react-mf/people") {
    return Promise.resolve(peopleApplication);
    } else {
    console.warn("No mock module found");
    return Promise.resolve({});
    }
    }
    +
    // jest.setup.js
    // import Mocks for SystemJS mock below
    import peopleApplication from "@react-mf/people";
    // Mock SystemJS
    global.System = {
    import: jest.fn(mockImport),
    };

    function mockImport(importName) {
    // What you do in mock import will depend a lot on how you use SystemJS in the project and components you wish to test

    /* If I had already created a mock for `@react-mf/people` and I wanted to test this component:
    * https://github.com/react-microfrontends/planets/blob/main/src/planets-page/selected-planet/selected-planet.component.js#L5
    * I would want `System.import('@react-mf/people')` to resovle to my mock one way to accomplish this would be the following
    */
    if (importName === "@react-mf/people") {
    return Promise.resolve(peopleApplication);
    } else {
    console.warn("No mock module found");
    return Promise.resolve({});
    }
    }
    \ No newline at end of file diff --git a/docs/videos/index.html b/docs/videos/index.html index 8aaaadbc3..38e78dc85 100644 --- a/docs/videos/index.html +++ b/docs/videos/index.html @@ -14,8 +14,8 @@ - - + + + \ No newline at end of file diff --git a/error/index.html b/error/index.html index d5d0775db..e477ea1c0 100644 --- a/error/index.html +++ b/error/index.html @@ -14,10 +14,10 @@ - - + + - + \ No newline at end of file diff --git a/governance/index.html b/governance/index.html index ea83ff2ba..d2b33fd38 100644 --- a/governance/index.html +++ b/governance/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content

    Single-spa governance

    @@ -44,6 +44,6 @@

    Technic

    The single-spa core team, maintainers, and creator may periodically hold meetings to discuss the current status and roadmap of single-spa. The creator has final say over all technical decisions. The core team helps out in day-to-day maintenance of the project, new feature initiatives, and roadmap.

    For transparency to the broader community, meeting notes are published on the single-spa blog.

    Funding

    -

    The single-spa project accepts voluntary donations via single-spa’s Open Collective. Single-spa’s creator accepts donations via Github sponsors. Budgeting and dispensing of single-spa Open Collective funds is controlled by single-spa’s creator, including paying the creator, core team, and maintainers for their labor.

    +

    The single-spa project accepts voluntary donations via single-spa’s Open Collective. Single-spa’s creator accepts donations via Github sponsors. Budgeting and dispensing of single-spa Open Collective funds is controlled by single-spa’s creator, including paying the creator, core team, and maintainers for their labor.

    \ No newline at end of file diff --git a/help/index.html b/help/index.html index 35b517d4e..c96a27196 100644 --- a/help/index.html +++ b/help/index.html @@ -14,10 +14,10 @@ - - + + -
    Skip to main content

    Need help?

    If you need help with single-spa, you can try one of the mechanisms below.

    Browse Docs

    Learn more about single-spa using the official docs

    Slack

    You can join the conversation on Slack on one of our channels: #general for user help and #maintainers for contributing help.

    Github

    At our GitHub repo Browse and submit issues or pull requests for bugs you find or any new features you may want implemented. Be sure to also check out our contributing information.

    Phone call / Consulting

    Paid, hands-on consulting with a single-spa core team member is available. Our core team members have done this before and can help you set up single-spa. Services range from a one hour debugging session to an ongoing relationship while you're seeing your project to completion. Inquire at singlespa.info@gmail.com.

    Stack Overflow

    Use the single-spa tag on StackOverflow.

    Twitter

    You can follow and contact us on Twitter.

    +
    Skip to main content

    Need help?

    If you need help with single-spa, you can try one of the mechanisms below.

    Browse Docs

    Learn more about single-spa using the official docs

    Slack

    You can join the conversation on Slack on one of our channels: #general for user help and #maintainers for contributing help.

    Github

    At our GitHub repo Browse and submit issues or pull requests for bugs you find or any new features you may want implemented. Be sure to also check out our contributing information.

    Phone call / Consulting

    Paid, hands-on consulting with a single-spa core team member is available. Our core team members have done this before and can help you set up single-spa. Services range from a one hour debugging session to an ongoing relationship while you're seeing your project to completion. Inquire at singlespa.info@gmail.com.

    Stack Overflow

    Use the single-spa tag on StackOverflow.

    Twitter

    You can follow and contact us on Twitter.

    \ No newline at end of file diff --git a/index.html b/index.html index 0aaf75815..e05d281f9 100644 --- a/index.html +++ b/index.html @@ -14,10 +14,10 @@ - - + + -
    Skip to main content

    single-spa

    A javascript router for front-end microservices

    Framework freedom

    Framework freedom

    Use multiple frameworks in a single-page application, allowing you to split code by functionality and have Angular, React, Vue.js, etc. apps all living in harmony.

    Lazy load applications

    Lazy load applications

    Stand up new apps next to the old one. You write the applications, single-spa makes them work together and won't load them until they're needed.

    Front-end microservices

    Front-end microservices

    Combine many small apps, empowering teams to choose their technology. Stay nimble as your team, product, and tech stack grows and changes over time.

    Who's Using This?

    This project is used by all these organizations

    +
    Skip to main content

    single-spa

    A javascript router for front-end microservices

    Framework freedom

    Framework freedom

    Use multiple frameworks in a single-page application, allowing you to split code by functionality and have Angular, React, Vue.js, etc. apps all living in harmony.

    Lazy load applications

    Lazy load applications

    Stand up new apps next to the old one. You write the applications, single-spa makes them work together and won't load them until they're needed.

    Front-end microservices

    Front-end microservices

    Combine many small apps, empowering teams to choose their technology. Stay nimble as your team, product, and tech stack grows and changes over time.

    Who's Using This?

    This project is used by all these organizations

    \ No newline at end of file diff --git a/languages/index.html b/languages/index.html index a1ece9955..58e08d996 100644 --- a/languages/index.html +++ b/languages/index.html @@ -14,10 +14,10 @@ - - + + - + \ No newline at end of file diff --git a/privacy/single-spa-inspector-privacy-policy/index.html b/privacy/single-spa-inspector-privacy-policy/index.html index 4a46a15ef..f92c22c38 100644 --- a/privacy/single-spa-inspector-privacy-policy/index.html +++ b/privacy/single-spa-inspector-privacy-policy/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content
    This privacy policy was created using Termly's Privacy Policy Generator.
    +
    This privacy policy was created using Termly's Privacy Policy Generator.
    \ No newline at end of file diff --git a/search/index.html b/search/index.html index 7edcf41b8..c740d0bc3 100644 --- a/search/index.html +++ b/search/index.html @@ -14,10 +14,10 @@ - - + + - + \ No newline at end of file diff --git a/sponsors/index.html b/sponsors/index.html index 498fe0901..c32c7c2ae 100644 --- a/sponsors/index.html +++ b/sponsors/index.html @@ -14,10 +14,10 @@ - - + + - + \ No newline at end of file diff --git a/users/index.html b/users/index.html index 13a51b506..a2d2a68ce 100644 --- a/users/index.html +++ b/users/index.html @@ -14,10 +14,10 @@ - - + + - + \ No newline at end of file diff --git a/versions/index.html b/versions/index.html index 1946dd18d..2abd169b6 100644 --- a/versions/index.html +++ b/versions/index.html @@ -14,10 +14,10 @@ - - + + -
    Skip to main content

    single-spa documentation versions

    Latest version (Stable)

    Here you can find the latest documentation.

    6.xDocumentationRelease Notes

    Past Versions

    Here you can find documentation for previous versions of single-spa.

    5.xDocumentationRelease Notes
    4.xDocumentationRelease Notes
    +
    Skip to main content

    single-spa documentation versions

    Latest version (Stable)

    Here you can find the latest documentation.

    6.xDocumentationRelease Notes

    Past Versions

    Here you can find documentation for previous versions of single-spa.

    5.xDocumentationRelease Notes
    4.xDocumentationRelease Notes
    \ No newline at end of file