From 955473602528080ecef2d736c2e12a0160ab6ee3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 23:21:46 +0000 Subject: [PATCH] deploy: 3cc1cb77af75fb09ecc9cbe9c8d7e682b56b6a19 --- 404.html | 6 +++--- .../js/{02af63f8.a718fc16.js => 02af63f8.ced52ba9.js} | 2 +- .../js/{3827c3c6.ad588109.js => 3827c3c6.c3037c1a.js} | 2 +- .../js/{38eb30df.fbec17cb.js => 38eb30df.122fa29d.js} | 2 +- .../js/{5896a7ea.fbfb28b8.js => 5896a7ea.9f9af63b.js} | 2 +- .../js/{674fa9c4.16b34f74.js => 674fa9c4.bcf3cae5.js} | 2 +- .../js/{78e9b454.a10eac35.js => 78e9b454.44bd04d8.js} | 2 +- .../js/{7bb2f638.91b6fd4b.js => 7bb2f638.5b1c5689.js} | 2 +- .../js/{8ac9c664.90265db4.js => 8ac9c664.bdd19a76.js} | 2 +- .../js/{98ffbda8.9517be47.js => 98ffbda8.a66c2c97.js} | 2 +- .../js/{a4df4865.9b76658d.js => a4df4865.f6e9fd27.js} | 2 +- .../js/{b2f554cd.3374d64c.js => b2f554cd.fea55b18.js} | 2 +- .../js/{c4f5d8e4.11f81bd8.js => c4f5d8e4.3c5853db.js} | 2 +- .../js/{daa69925.56cf738f.js => daa69925.86d8d961.js} | 2 +- .../js/{e85cb86b.e9efa13c.js => e85cb86b.47c912e2.js} | 2 +- .../js/{ef491088.cabd5440.js => ef491088.a48ce8d7.js} | 2 +- assets/js/{main.e67e3c9c.js => main.032cefac.js} | 4 ++-- ...c9c.js.LICENSE.txt => main.032cefac.js.LICENSE.txt} | 0 ...ntime~main.c9be4ee5.js => runtime~main.90a25d1c.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/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 | 6 +++--- 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 +++--- 175 files changed, 496 insertions(+), 496 deletions(-) rename assets/js/{02af63f8.a718fc16.js => 02af63f8.ced52ba9.js} (99%) rename assets/js/{3827c3c6.ad588109.js => 3827c3c6.c3037c1a.js} (99%) rename assets/js/{38eb30df.fbec17cb.js => 38eb30df.122fa29d.js} (99%) rename assets/js/{5896a7ea.fbfb28b8.js => 5896a7ea.9f9af63b.js} (98%) rename assets/js/{674fa9c4.16b34f74.js => 674fa9c4.bcf3cae5.js} (98%) rename assets/js/{78e9b454.a10eac35.js => 78e9b454.44bd04d8.js} (75%) rename assets/js/{7bb2f638.91b6fd4b.js => 7bb2f638.5b1c5689.js} (99%) rename assets/js/{8ac9c664.90265db4.js => 8ac9c664.bdd19a76.js} (99%) rename assets/js/{98ffbda8.9517be47.js => 98ffbda8.a66c2c97.js} (98%) rename assets/js/{a4df4865.9b76658d.js => a4df4865.f6e9fd27.js} (99%) rename assets/js/{b2f554cd.3374d64c.js => b2f554cd.fea55b18.js} (99%) rename assets/js/{c4f5d8e4.11f81bd8.js => c4f5d8e4.3c5853db.js} (98%) rename assets/js/{daa69925.56cf738f.js => daa69925.86d8d961.js} (99%) rename assets/js/{e85cb86b.e9efa13c.js => e85cb86b.47c912e2.js} (99%) rename assets/js/{ef491088.cabd5440.js => ef491088.a48ce8d7.js} (99%) rename assets/js/{main.e67e3c9c.js => main.032cefac.js} (99%) rename assets/js/{main.e67e3c9c.js.LICENSE.txt => main.032cefac.js.LICENSE.txt} (100%) rename assets/js/{runtime~main.c9be4ee5.js => runtime~main.90a25d1c.js} (92%) diff --git a/404.html b/404.html index e2e1ec335..b117d649a 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.a718fc16.js b/assets/js/02af63f8.ced52ba9.js similarity index 99% rename from assets/js/02af63f8.a718fc16.js rename to assets/js/02af63f8.ced52ba9.js index 77474badb..0d00892e3 100644 --- a/assets/js/02af63f8.a718fc16.js +++ b/assets/js/02af63f8.ced52ba9.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-2efw13fg4-oJgemeyCUJv4~JrQlYttnA",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-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 diff --git a/assets/js/3827c3c6.ad588109.js b/assets/js/3827c3c6.c3037c1a.js similarity index 99% rename from assets/js/3827c3c6.ad588109.js rename to assets/js/3827c3c6.c3037c1a.js index 483f3e8c1..a7ba635b5 100644 --- a/assets/js/3827c3c6.ad588109.js +++ b/assets/js/3827c3c6.c3037c1a.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-2efw13fg4-oJgemeyCUJv4~JrQlYttnA",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 a6ca69830..2b95e5203 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 82c749a75..89bfc7184 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 769819f19..93178660b 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 dce8edb85..ef00e8a0a 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 087d47b20..003483aaf 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 de6561241..b7db5a9f3 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 c87b62668..23fe7fd63 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 b4925eee7..fc8bc8785 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 5cc162432..77d0633a8 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 8cf49148d..6fbafab1f 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 ead7f40c9..1fd736186 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 f4ba2a01a..42a70de1e 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 972660bc0..9c6ca806f 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 b6f1477ca..933558913 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/archive/index.html b/blog/archive/index.html index 8a9145a92..21f8f7e29 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 8fd0a506c..7e2d26efc 100644 --- a/blog/atom.xml +++ b/blog/atom.xml @@ -480,7 +480,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 @@ -567,7 +567,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 75768dcd3..22fd76be8 100644 --- a/blog/index.html +++ b/blog/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content

    · 2 min read

    Attendees: Ian, Milan Kovacic

    @@ -343,6 +343,6 @@

    Meet the Team<

    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/page/2/index.html b/blog/page/2/index.html index cd42ac487..81427bec4 100644 --- a/blog/page/2/index.html +++ b/blog/page/2/index.html @@ -14,8 +14,8 @@ - - + +
    Skip to main content

    · 5 min read

    Today we released single-spa@5.0.0.

    @@ -76,7 +76,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

    @@ -139,7 +139,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.

    @@ -225,6 +225,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 cb1e89c10..fdb3f5405 100644 --- a/blog/rss.xml +++ b/blog/rss.xml @@ -477,7 +477,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]]> @@ -556,7 +556,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 cd922f117..406450eb5 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 26a823283..84ca3649a 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 cf3bed966..fa952be4f 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 85ba460cf..ae1b45610 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 e51941009..27c14d885 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 63429e761..8dd48080a 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 8d4bc3984..b650ebe51 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.

    @@ -86,6 +86,6 @@

    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.

    +

    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 28e868940..435ffe640 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 debaff33b..486b7bf1d 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 6c3214737..937cad68c 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 8b7d12379..f86a88f8e 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 5f1f16b8b..79a946b3e 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 837e86e18..ce267ae56 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 753e20bd7..d6effe258 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 8be4a9228..bad5a9e7d 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 4c711ff10..e9a5586cd 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 af8dbadc2..e32afcc5b 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 34e5bd28e..f72579db9 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 b465b9a8a..588681781 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 6cb18d717..12fa299be 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 b11010fb1..91fe42ce3 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 8ceacb1e2..160cec9c6 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 a82901d7d..88f82fa1a 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 d81b57709..adbae6135 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 7e2a4601c..46d0e44f8 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 7a46d211d..0417c2f20 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 62026ac6f..6ef051e23 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 68791eef5..ec93aa0be 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 d1fc2c1f7..4503e9312 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 3625b51db..67da8e441 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 2249a3b12..56189ef4b 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 94e5e91fa..65fa5e7eb 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 d7c6f1b54..bf2146e70 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 10730c266..5a177f096 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 951c86915..7c1b1a65b 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 273b050b7..28ef98c59 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 5cf1a3883..9bdbefc2d 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 e58d02e3a..1fe6bbe99 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 67ae6dff7..1fbf41376 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 c01b1ae61..7850a4d17 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 4d8d2326d..cd080797a 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 2be1a0c78..5473f9596 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 acb133ea8..610266ffe 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 8a0e7cfbc..662eeef71 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 322047ebb..70e225a75 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 7e7538374..1b9eec0a9 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 f81db89b5..5c0d53690 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 a3ffb3b23..560d7cf9e 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 1de9d794a..4e1529872 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 96308e36b..e1d3cf380 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 f35f2d89c..197b40d87 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 9ae58fa56..c1e79def5 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 272e44c05..159c8bc0d 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 47ba40cae..9781de6a0 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 ef3a79aa4..c3162a6a1 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 08b48471c..2c8238da3 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 9a3884747..62537fe41 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 744f90065..9634278ca 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 185e7f906..7a9e8c225 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 40f711d54..48cdfe0bb 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 fa32c6906..dbd4e7429 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 3c5313ec6..887116eba 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 c1409199b..33b6b7e99 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 d4e72a352..2e88c57d1 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 532a1efe3..f310e4369 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 dee12e46f..3a724a586 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 a691182d5..76c0fe172 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 45fdc16cb..3ee47ce58 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 f086b17a7..bee4fe461 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 fe750d227..9e5dedf34 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 fc4d34b04..f8395ffd2 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 147f30fad..1264ac59a 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 63c26d958..dbb7647d4 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 fed85b7c4..7ea51e7ab 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 7f0b41718..293a8cef1 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 09823bdaa..b0c812228 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 2a6b6322c..933f525aa 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 f142d2c08..da11604e2 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 6d7eb0fa7..4c99768b2 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 2f9dd690b..f8c193ce1 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 6fe594918..b7227cd64 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 a79c3b44a..59eb67e19 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 aae83ac36..617227ede 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 76a015584..700a0f116 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 9bfe3740b..154d7d5f6 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 7f0115adc..c1b4b3d66 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 d5e9b4e4a..b8dea19b4 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

    @@ -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/ecosystem-angularjs/index.html b/docs/ecosystem-angularjs/index.html index 1d39c1146..bdc68c458 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 3559943c1..8f023e4dd 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 efd19a150..b95e9a36f 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 e6950eba7..212e0056c 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 8fc0ccc22..3e362ecec 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 0e6374b69..f69d770c6 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 9cc162d11..39868b9e8 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 4132c23c5..413bb2a56 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 b3c30e37d..799fe8fb9 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 70e8579ec..5eea9443f 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 070b7b0d8..3d0b6f58d 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 5ba9ba309..5298fbefb 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 475787def..25e7eb2e1 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 5723a9bb2..dfa28d695 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 9cfbe286b..53d343e36 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 287102268..9d1671780 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 a9d01db31..3f970e44e 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 05367af9a..e1f8bf3b1 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 ed6b712bf..4d04d1b3c 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 bcdc4a312..5a3fb6e1c 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 3228a1c7d..4f6e4f73c 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 8ad20c433..836f72220 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 aab71c563..cae34e7b0 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 9f74e4c20..8de561997 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 e1eef6b9c..eaddccff1 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 7029b96eb..6802a58ab 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 ac5705129..e30d7322c 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 a36ff9841..05344e870 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 474576c8d..953f5688c 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 0f7bfa9df..c961fbe9e 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 cb6071c0d..1f40ae7c3 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 a8ab38d23..f616f5cd4 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 327a192ed..d7ea6b73e 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 815b12ad7..63c0b72d9 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 1096d7623..7759b94d9 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 5ce4d963f..0416e4aa8 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 41888d56f..86fc6cefb 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 899884687..4c02f4680 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 da2a35269..dbbc4fe06 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 6867a93b6..81d846215 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 e5729c49a..4486df917 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 44bf96a2c..37a3ed49a 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 b3ecfbbb7..256373451 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 6514220f7..088c2191f 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 77580e66a..ad49894f4 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 961d88ddd..bdc1515ec 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 4080b6ae9..c6c5325eb 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 dbf84d276..91541018a 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 b89ae9b9f..32b40dd97 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