ã¹ã±ãŒã©ãã«ã§ä¿å®æ§ã®é«ããã€ã¯ãããã³ããšã³ãã¢ãŒããã¯ãã£ãæ§ç¯ããããã®single-SPAãã¬ãŒã ã¯ãŒã¯ãæ¢ããŸãããã®å©ç¹ãå®è£ æ¹æ³ãã°ããŒãã«ããŒã åãã®ãã¹ããã©ã¯ãã£ã¹ãåŠã³ãŸãããã
Single-SPAãã¬ãŒã ã¯ãŒã¯ïŒãã€ã¯ãããã³ããšã³ããªãŒã±ã¹ãã¬ãŒã·ã§ã³ã®å æ¬çã¬ã€ã
仿¥ã®æ¥éã«é²åããWebéçºã®äžçã§ã¯ãã¢ããªã·ãã¯ãªããã³ããšã³ãã¯ãå¢å€§ããã¢ããªã±ãŒã·ã§ã³ã®èŠæ±ã忣ããããŒã ã®ããŒã¹ã«ã€ããŠããã®ã«èŠåŽããŠããŸãããã€ã¯ãããã³ããšã³ãã¢ãŒããã¯ãã£ã¯ããããã®èª²é¡ã«å¯Ÿãã匷åãªãœãªã¥ãŒã·ã§ã³ãšããŠç»å Žããéçºè ãç¬ç«ããŠãããã€å¯èœã§ä¿å®æ§ã®é«ãã³ã³ããŒãã³ãã®éåäœãšããŠè€éãªãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹ãæ§ç¯ã§ããããã«ããŸãããã®ã¢ãããŒãã¯ãããŒã ã®èªåŸæ§ãè²ã¿ãã³ãŒãã®åå©çšæ§ãä¿é²ããéçºããã»ã¹å šäœãç°¡çŽ åããŸãããã€ã¯ãããã³ããšã³ãã®ãªãŒã±ã¹ãã¬ãŒã·ã§ã³ã«å©çšã§ããæ§ã ãªãã¬ãŒã ã¯ãŒã¯ã®äžã§ããsingle-SPAã¯å€æ©èœã§å ç¢ãªéžæè¢ãšããŠéç«ã£ãŠããŸãã
ãã€ã¯ãããã³ããšã³ããšã¯ïŒ
ãã€ã¯ãããã³ããšã³ããšã¯ãããã³ããšã³ãã¢ããªã±ãŒã·ã§ã³ãããå°ãããç¬ç«ããèªå·±å®çµãããŠãããïŒãã€ã¯ãããã³ããšã³ãïŒã«åè§£ããã¢ãŒããã¯ãã£ã¹ã¿ã€ã«ã§ããåãã€ã¯ãããã³ããšã³ãã¯ãå¥ã ã®ããŒã ã«ãã£ãŠéçºããããã€ãä¿å®ãå¯èœã§ããããã¯ãè€æ°ã®ããã¢ããªã±ãŒã·ã§ã³ã飿ºããŠããŸãšãŸãã®ãããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ã圢æããæ§æãšèããããšãã§ããŸãã
ãã€ã¯ãããã³ããšã³ãã®äž»ãªç¹åŸŽã¯æ¬¡ã®ãšããã§ãïŒ
- æè¡ã«äŸåããªãïŒ åãã€ã¯ãããã³ããšã³ãã¯ãç°ãªããã¬ãŒã ã¯ãŒã¯ãæè¡ïŒReact, Angular, Vue.jsãªã©ïŒã䜿çšããŠæ§ç¯ã§ããŸãã
- ç¬ç«ãããããã€å¯èœæ§ïŒ ãã€ã¯ãããã³ããšã³ãã¯ãã¢ããªã±ãŒã·ã§ã³ã®ä»ã®éšåã«åœ±é¿ãäžããããšãªããç¬ç«ããŠãããã€ã§ããŸãã
- èªåŸçãªããŒã ïŒ ç°ãªãããŒã ãç°ãªããã€ã¯ãããã³ããšã³ããææã»ä¿å®ããããšã§ãèªåŸæ§ãšããéãéçºãµã€ã¯ã«ãä¿é²ããŸãã
- ã³ãŒãã®åå©çšæ§ïŒ å ±éã®ã³ã³ããŒãã³ããã©ã€ãã©ãªããã€ã¯ãããã³ããšã³ãéã§å ±æã§ããŸãã
- ã¹ã±ãŒã©ããªãã£ãšä¿å®æ§ã®åäžïŒ å°ããç¬ç«ãããŠãããã¯ãå€§èŠæš¡ãªã¢ããªã·ãã¯ã¢ããªã±ãŒã·ã§ã³ãšæ¯èŒããŠãã¹ã±ãŒãªã³ã°ãä¿å®ãæŽæ°ã容æã§ãã
ãªãSingle-SPAãéžã¶ã®ãïŒ
Single-SPAã¯ãåäžã®ãã©ãŠã¶ããŒãžå ã§è€æ°ã®JavaScriptã¢ããªã±ãŒã·ã§ã³ïŒãã€ã¯ãããã³ããšã³ãïŒã®ãªãŒã±ã¹ãã¬ãŒã·ã§ã³ã容æã«ããJavaScriptãã¬ãŒã ã¯ãŒã¯ã§ãããã€ã¯ãããã³ããšã³ãèªäœã«ç¹å®ã®æè¡ã¹ã¿ãã¯ãèŠå®ããªããããããŒã ã¯èªåãã¡ã®ããŒãºã«æãé©ããããŒã«ãéžæã§ããŸãããã®ãã¬ãŒã ã¯ãŒã¯ã¯ã¡ã¿ãã¬ãŒã ã¯ãŒã¯ãšããŠæ©èœããç°ãªããã€ã¯ãããã³ããšã³ãã®èªã¿èŸŒã¿ãã¢ã³ããŒããã©ã€ããµã€ã¯ã«ç®¡çã®ããã®ã€ã³ãã©ã¹ãã©ã¯ãã£ãæäŸããŸãã
single-SPAããã€ã¯ãããã³ããšã³ããªãŒã±ã¹ãã¬ãŒã·ã§ã³ã§äººæ°ã®éžæè¢ã§ããçç±ã¯æ¬¡ã®ãšããã§ãïŒ
- ãã¬ãŒã ã¯ãŒã¯éäŸåïŒ single-SPAã¯ãReact, Angular, Vue.js, Svelteãªã©ãã»ãŒãã¹ãŠã®JavaScriptãã¬ãŒã ã¯ãŒã¯ã§äœ¿çšã§ããŸãããã®æè»æ§ã«ãããããŒã ã¯æ¢åã®ã¢ããªã±ãŒã·ã§ã³ãæžãçŽãããšãªããæ®µéçã«ãã€ã¯ãããã³ããšã³ããå°å ¥ã§ããŸãã
- 段éçãªå°å ¥ïŒ å°ããåé¢ãããæ©èœããå§ããŠãã¢ããªã·ãã¯ãªã¢ããªã±ãŒã·ã§ã³ããã€ã¯ãããã³ããšã³ãã¢ãŒããã¯ãã£ã«åŸã ã«ç§»è¡ã§ããŸãã
- ã³ãŒãå ±æïŒ single-SPAã䜿çšãããšããã€ã¯ãããã³ããšã³ãéã§ã³ãŒããšäŸåé¢ä¿ãå ±æã§ããåé·æ§ãæžãããäžè²«æ§ãåäžãããããšãã§ããŸãã
- é å»¶èªã¿èŸŒã¿ïŒ ãã€ã¯ãããã³ããšã³ãã¯ãªã³ããã³ãã§èªã¿èŸŒãŸãããããåæããŒãžã®èªã¿èŸŒã¿æéãšå šäœçãªããã©ãŒãã³ã¹ãåäžããŸãã
- ç°¡çŽ åããããããã€ïŒ ãã€ã¯ãããã³ããšã³ãã®ç¬ç«ãããããã€ã«ããããªãªãŒã¹ãµã€ã¯ã«ãéããªãããªã¹ã¯ã軜æžãããŸãã
- å ç¢ãªã©ã€ããµã€ã¯ã«ç®¡çïŒ single-SPAã¯åãã€ã¯ãããã³ããšã³ãã«æç¢ºã«å®çŸ©ãããã©ã€ããµã€ã¯ã«ãæäŸããããããé©åã«åæåãããŠã³ããã¢ã³ããŠã³ããç Žæ£ãããããšãä¿èšŒããŸãã
Single-SPAã®äž»èŠãªæŠå¿µ
single-SPAã广çã«äœ¿çšããããã«ã¯ããã®äžæ žãšãªãæŠå¿µãçè§£ããããšãéèŠã§ãïŒ
- Single-SPA ConfigïŒ single-SPAã¢ããªã±ãŒã·ã§ã³ãããŒãã¹ãã©ããããäž»èŠãªJavaScriptãã¡ã€ã«ã§ãããã€ã¯ãããã³ããšã³ãã®ç»é²ãšã«ãŒãã£ã³ã°ããžãã¯ã®å®çŸ©ãæ åœããŸããããã«ã¯ããã¹ãŠã管çããã«ãŒãã³ã³ããŒãã³ããå«ãŸããããšãå€ãã§ãã
- ãã€ã¯ãããã³ããšã³ãïŒ single-SPA configã«ç»é²ãããç¬ç«ããJavaScriptã¢ããªã±ãŒã·ã§ã³ã§ããåãã€ã¯ãããã³ããšã³ãã¯ããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹ã®ç¹å®ã®éšåãã¬ã³ããªã³ã°ãã責任ããããŸãã
- ParcelsïŒããŒã»ã«ïŒïŒ ãã€ã¯ãããã³ããšã³ãéã§å ±æã§ããåå©çšå¯èœãªã³ã³ããŒãã³ãã§ããããŒã»ã«ã¯ãã¢ããªã±ãŒã·ã§ã³ã®è€æ°ã®éšåã§å¿ èŠãšãããå ±éã®UIèŠçŽ ãããžãã¹ããžãã¯ãäœæããã®ã«åœ¹ç«ã¡ãŸãã
- Root ConfigïŒã«ãŒãèšå®ïŒïŒ ãã€ã¯ãããã³ããšã³ããèªã¿èŸŒã¿ããªãŒã±ã¹ãã¬ãŒã·ã§ã³ããã¡ã€ã³ã®ã¢ããªã±ãŒã·ã§ã³ã·ã§ã«ã§ããã«ãŒãã£ã³ã°ãã°ããŒãã«ãªç¶æ 管çããã€ã¯ãããã³ããšã³ãéã®éä¿¡ãæ åœããŸãã
- Activity FunctionsïŒã¢ã¯ãã£ããã£é¢æ°ïŒïŒ ãã€ã¯ãããã³ããšã³ãããã€ã¢ã¯ãã£ãïŒããŠã³ãïŒãŸãã¯éã¢ã¯ãã£ãïŒã¢ã³ããŠã³ãïŒã«ãªãã¹ãããæ±ºå®ããJavaScript颿°ã§ãããããã¯éåžžãURLã®ã«ãŒããä»ã®ã¢ããªã±ãŒã·ã§ã³ã®ç¶æ ã«åºã¥ããŠããŸãã
Single-SPAã®å®è£ ïŒã¹ããããã€ã¹ãããã¬ã€ã
Reactã§æ§ç¯ããããã€ã¯ãããã³ããšã³ããšVue.jsã§æ§ç¯ããããã€ã¯ãããã³ããšã³ãã®2ã€ãæã€single-SPAã¢ããªã±ãŒã·ã§ã³ãã»ããã¢ããããåºæ¬çãªäŸãèŠãŠãããŸãããã
ã¹ããã1ïŒSingle-SPA Configã®ã»ããã¢ãã
ãŸããsingle-SPAã¢ããªã±ãŒã·ã§ã³çšã®æ°ãããã£ã¬ã¯ããªãäœæããNode.jsãããžã§ã¯ããåæåããŸãïŒ
mkdir single-spa-example
cd single-spa-example
npm init -y
次ã«ãå¿ èŠãªäŸåé¢ä¿ãã€ã³ã¹ããŒã«ããŸãïŒ
npm install single-spa import-map-overrides
ã«ãŒããã£ã¬ã¯ããªã«`index.html`ãã¡ã€ã«ãäœæããŸãïŒ
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Single-SPA Example</title>
<meta name="importmap-type" content="systemjs-importmap">
<script type="systemjs-importmap">
{
"imports": {
"single-spa": "https://cdn.jsdelivr.net/npm/single-spa@5.9.0/lib/single-spa.min.js",
"react": "https://cdn.jsdelivr.net/npm/react@16.13.1/umd/react.production.min.js",
"react-dom": "https://cdn.jsdelivr.net/npm/react-dom@16.13.1/umd/react-dom.production.min.js",
"vue": "https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.min.js"
}
}
</script>
<script src="https://cdn.jsdelivr.net/npm/import-map-overrides@2.2.0/dist/import-map-overrides.js"></script>
<script src="https://cdn.jsdelivr.net/npm/systemjs@6.8.3/dist/system.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/systemjs@6.8.3/dist/extras/named-exports.js"></script>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<script>
System.import('single-spa-config');
</script>
<import-map-overrides-full show-when-local-storage="devtools"></import-map-overrides-full>
</body>
</html>
ãã®`index.html`ãã¡ã€ã«ã¯ãSystemJSã¢ãžã¥ãŒã«ããŒããŒãã€ã³ããŒãããããããã³single-SPA configãã»ããã¢ããããŸããã€ã³ããŒããããã¯ããã€ã¯ãããã³ããšã³ãã§äœ¿çšãããäŸåé¢ä¿ã®URLãå®çŸ©ããŸãã
`single-spa-config.js`ãã¡ã€ã«ãäœæããŸãïŒ
import * as singleSpa from 'single-spa';
singleSpa.registerApplication(
'react-app',
() => System.import('react-app'),
location => location.pathname.startsWith('/react')
);
singleSpa.registerApplication(
'vue-app',
() => System.import('vue-app'),
location => location.pathname.startsWith('/vue')
);
singleSpa.start();
ãã®ãã¡ã€ã«ã¯`react-app`ãš`vue-app`ã®2ã€ã®ãã€ã¯ãããã³ããšã³ããç»é²ããŸãã`activityFunction`ã¯ãURLã«åºã¥ããŠåãã€ã¯ãããã³ããšã³ãããã€ã¢ã¯ãã£ãã«ãªãããæ±ºå®ããŸãã
ã¹ããã2ïŒReactãã€ã¯ãããã³ããšã³ãã®äœæ
Reactãã€ã¯ãããã³ããšã³ãçšã®æ°ãããã£ã¬ã¯ããªãäœæããŸãïŒ
mkdir react-app
cd react-app
npx create-react-app .
npm install single-spa-react
`src/index.js`ãã¡ã€ã«ã倿ŽããŠ`single-spa-react`ã䜿çšããããã«ããŸãïŒ
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import singleSpaReact from 'single-spa-react';
const lifecycles = singleSpaReact({
React,
ReactDOM,
rootComponent: App,
errorBoundary(err, info, props) {
// Customize the root error boundary for your microfrontend here.
return (<h1>Error</h1>);
},
});
export const { bootstrap, mount, unmount } = lifecycles;
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
`public/index.html`ãã¡ã€ã«ãäœæãïŒååšããªãå ŽåïŒã`root` divãååšããããšã確èªããŸãïŒ
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
`App.js`ã倿ŽããŠãäœæ¥ãç°¡åã«ç¢ºèªã§ããããã«ã«ã¹ã¿ã ããã¹ãã衚瀺ããŸãïŒ
import React from 'react';
import logo from './logo.svg';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
This is the <b>React Micro-Frontend</b>!
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
Reactãã€ã¯ãããã³ããšã³ãããã«ãããŸãïŒ
npm run build
`build`ãã£ã¬ã¯ããªã`react-app`ã«åå倿Žããsingle-SPAã¢ããªã±ãŒã·ã§ã³ã®ã«ãŒãã«é 眮ããŸããæ¬¡ã«ã`react-app`ãã£ã¬ã¯ããªå ã«`react-app.js`ãã¡ã€ã«ãäœæãã`build/static/js`ãã¡ã€ã«ã®å 容ã貌ãä»ããŸãã`static/js`ãã£ã¬ã¯ããªã«ä»ã®JSãã¡ã€ã«ãããå Žåã¯ãããããå«ããŠãã ããã
`index.html`ã®ã€ã³ããŒãããããæŽæ°ããŠãReactãã€ã¯ãããã³ããšã³ããæãããã«ããŸãïŒ
{
"imports": {
"single-spa": "https://cdn.jsdelivr.net/npm/single-spa@5.9.0/lib/single-spa.min.js",
"react": "https://cdn.jsdelivr.net/npm/react@16.13.1/umd/react.production.min.js",
"react-dom": "https://cdn.jsdelivr.net/npm/react-dom@16.13.1/umd/react-dom.production.min.js",
"vue": "https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.min.js",
"react-app": "/react-app/react-app.js"
}
}
ã¹ããã3ïŒVue.jsãã€ã¯ãããã³ããšã³ãã®äœæ
Vue.jsãã€ã¯ãããã³ããšã³ãçšã®æ°ãããã£ã¬ã¯ããªãäœæããŸãïŒ
mkdir vue-app
cd vue-app
npx @vue/cli create .
npm install single-spa-vue --save
Vue CLIã®ã»ããã¢ããäžã«ãããã©ã«ãã®ããªã»ãããéžæããããå¿ èŠã«å¿ããŠã«ã¹ã¿ãã€ãºããŸãã
`src/main.js`ãã¡ã€ã«ã倿ŽããŠ`single-spa-vue`ã䜿çšããããã«ããŸãïŒ
import Vue from 'vue'
import App from './App.vue'
import singleSpaVue from 'single-spa-vue';
Vue.config.productionTip = false
const vueLifecycles = singleSpaVue({
Vue,
appOptions: {
el: '#vue-app',
render: h => h(App)
}
});
export const bootstrap = vueLifecycles.bootstrap;
export const mount = vueLifecycles.mount;
export const unmount = vueLifecycles.unmount;
`App.vue`ã倿ŽããŠãäœæ¥ãç°¡åã«ç¢ºèªã§ããããã«ã«ã¹ã¿ã ããã¹ãã衚瀺ããŸãïŒ
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<p>This is the <b>Vue Micro-Frontend</b>!</p>
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
</style>
Vue.jsãã€ã¯ãããã³ããšã³ãããã«ãããŸãïŒ
npm run build
`dist`ãã£ã¬ã¯ããªã`vue-app`ã«åå倿Žããsingle-SPAã¢ããªã±ãŒã·ã§ã³ã®ã«ãŒãã«é 眮ããŸããæ¬¡ã«ã`vue-app`ãã£ã¬ã¯ããªå ã«`vue-app.js`ãã¡ã€ã«ãäœæãã`dist/js/app.js`ãã¡ã€ã«ã®å 容ã貌ãä»ããŸãã`dist/js`ãã£ã¬ã¯ããªã«ä»ã®JSãã¡ã€ã«ãããå Žåã¯ãããããå«ããŠãã ããã
`index.html`ã®ã€ã³ããŒãããããæŽæ°ããŠãVue.jsãã€ã¯ãããã³ããšã³ããæãããã«ããŸãïŒ
{
"imports": {
"single-spa": "https://cdn.jsdelivr.net/npm/single-spa@5.9.0/lib/single-spa.min.js",
"react": "https://cdn.jsdelivr.net/npm/react@16.13.1/umd/react.production.min.js",
"react-dom": "https://cdn.jsdelivr.net/npm/react-dom@16.13.1/umd/react-dom.production.min.js",
"vue": "https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.min.js",
"react-app": "/react-app/react-app.js",
"vue-app": "/vue-app/vue-app.js"
}
}
ã¹ããã4ïŒã¢ããªã±ãŒã·ã§ã³ã®æäŸ
ç°¡åãªHTTPãµãŒããŒã䜿çšããŠ`index.html`ãã¡ã€ã«ãæäŸããŸãã`http-server`ã®ãããªããŒã«ã䜿çšã§ããŸãïŒ
npm install -g http-server
http-server -c-1
`http://localhost:8080/react`ã«ã¢ã¯ã»ã¹ãããšReactãã€ã¯ãããã³ããšã³ããã`http://localhost:8080/vue`ã«ã¢ã¯ã»ã¹ãããšVue.jsãã€ã¯ãããã³ããšã³ãã衚瀺ãããŸãã
éèŠãªèæ ®äºé ïŒ
- ãã®äŸã§ã¯ãURLãã¬ãã£ãã¯ã¹ã«åºã¥ãåçŽãªã«ãŒãã£ã³ã°ã䜿çšããŠããŸããããè€éãªã«ãŒãã£ã³ã°ã·ããªãªã§ã¯ã`single-spa-router`ã®ãããªå°çšã®ã«ãŒãã£ã³ã°ã©ã€ãã©ãªã®äœ¿çšãæ€èšããŠãã ããã
- æ¬çªç°å¢ã§ã¯ãéåžžãCDNãä»ã®éçã¢ã»ãããã¹ãã£ã³ã°ãµãŒãã¹ãããã€ã¯ãããã³ããšã³ããæäŸããŸãã
- ãã®äŸã§ã¯ãäŸåé¢ä¿ç®¡çã«ã€ã³ããŒããããã䜿çšããŠããŸããæ¬çªçšã«ãã€ã¯ãããã³ããšã³ãããã³ãã«ããããã«ãWebpackãParcelã®ãããªãã«ãããŒã«ã®äœ¿çšãæ€èšããŠãã ããã
é«åºŠãªSingle-SPAãã¯ããã¯
åºæ¬çãªsingle-SPAã¢ããªã±ãŒã·ã§ã³ãã»ããã¢ããããããã¢ãŒããã¯ãã£ã®ã¹ã±ãŒã©ããªãã£ãšä¿å®æ§ãåäžãããããã®ããé«åºŠãªãã¯ããã¯ãæ¢ãããšãã§ããŸãã
ããŒã»ã«ã«ããã³ãŒãå ±æ
ããŒã»ã«ã䜿çšãããšãåå©çšå¯èœãªã³ã³ããŒãã³ããšããžãã¯ããã€ã¯ãããã³ããšã³ãéã§å ±æã§ããŸããããã«ãããã³ãŒãã®éè€ãæžãããã¢ããªã±ãŒã·ã§ã³å šäœã®äžè²«æ§ãåäžãããããšãã§ããŸãã
ããŒã»ã«ãäœæããã«ã¯ã`singleSpa.mountRootParcel`颿°ã䜿çšããŸãïŒ
import * as singleSpa from 'single-spa';
import React from 'react';
import ReactDOM from 'react-dom';
function MyParcel(props) {
return (<div>Hello from Parcel! {props.name}</div>);
}
const parcel = singleSpa.mountRootParcel(() => {
return Promise.resolve({
bootstrap: () => Promise.resolve(),
mount: (props) => {
ReactDOM.render(<MyParcel name={props.name} />, document.getElementById('parcel-container'));
return Promise.resolve();
},
unmount: () => {
ReactDOM.unmountComponentAtNode(document.getElementById('parcel-container'));
return Promise.resolve();
},
});
});
// To mount the parcel:
parcel.mount({ name: 'Example' });
ãã€ã¯ãããã³ããšã³ãéã®éä¿¡
ãã€ã¯ãããã³ããšã³ãã¯ãããŒã¿ãå ±æãããã¢ã¯ã·ã§ã³ãããªã¬ãŒãããããããã«ãäºãã«éä¿¡ããå¿ èŠãããããšããããããŸãããããå®çŸããã«ã¯ããã€ãã®æ¹æ³ããããŸãïŒ
- å ±æã°ããŒãã«ç¶æ ïŒ ReduxãVuexã®ãããªã°ããŒãã«ç¶æ 管çã©ã€ãã©ãªã䜿çšããŠããã€ã¯ãããã³ããšã³ãéã§ããŒã¿ãå ±æããŸãã
- ã«ã¹ã¿ã ã€ãã³ãïŒ ã«ã¹ã¿ã DOMã€ãã³ãã䜿çšããŠããã€ã¯ãããã³ããšã³ãéã§ã¡ãã»ãŒãžããããŒããã£ã¹ãããŸãã
- çŽæ¥é¢æ°åŒã³åºãïŒ ãããã€ã¯ãããã³ããšã³ããã颿°ããšã¯ã¹ããŒãããå¥ã®ãã€ã¯ãããã³ããšã³ãã«ã€ã³ããŒãããŸãããã®ã¢ãããŒãã¯ãäŸåé¢ä¿ã埪ç°åç §ãé¿ããããã«æ éãªèª¿æŽãå¿ èŠã§ãã
- ã¡ãã»ãŒãžãããŒã«ãŒïŒ RabbitMQãKafkaã®ãããªã©ã€ãã©ãªã䜿çšããŠã¡ãã»ãŒãžãããŒã«ãŒãã¿ãŒã³ãå®è£ ãããã€ã¯ãããã³ããšã³ããççµåã«ããéåæéä¿¡ãå¯èœã«ããŸãã
èªèšŒãšèªå¯
ãã€ã¯ãããã³ããšã³ãã¢ãŒããã¯ãã£ã§èªèšŒãšèªå¯ãå®è£ ããã®ã¯é£ããå ŽåããããŸãã以äžã«äžè¬çãªã¢ãããŒããããã€ã瀺ããŸãïŒ
- äžå€®éæš©åèªèšŒïŒ äžå€®èªèšŒãµãŒãã¹ã䜿çšããŠããŠãŒã¶ãŒã®ãã°ã€ã³ãšèªèšŒãåŠçããŸããèªèšŒãµãŒãã¹ã¯ããã€ã¯ãããã³ããšã³ããžã®ãªã¯ãšã¹ããèªèšŒããããã«äœ¿çšãããããŒã¯ã³ãçºè¡ã§ããŸãã
- å ±æèªèšŒã¢ãžã¥ãŒã«ïŒ ãã¹ãŠã®ãã€ã¯ãããã³ããšã³ãã§äœ¿çšãããå ±æèªèšŒã¢ãžã¥ãŒã«ãäœæããŸãããã®ã¢ãžã¥ãŒã«ã¯ãããŒã¯ã³ç®¡çãšãŠãŒã¶ãŒã»ãã·ã§ã³ãåŠçã§ããŸãã
- APIã²ãŒããŠã§ã€ïŒ APIã²ãŒããŠã§ã€ã䜿çšããŠããã€ã¯ãããã³ããšã³ããžã®ãã¹ãŠã®ãªã¯ãšã¹ãã®èªèšŒãšèªå¯ãåŠçããŸããAPIã²ãŒããŠã§ã€ã¯ããŒã¯ã³ãæ€èšŒããã¢ã¯ã»ã¹å¶åŸ¡ããªã·ãŒãé©çšã§ããŸãã
Single-SPAã«ãããã€ã¯ãããã³ããšã³ãã¢ãŒããã¯ãã£ã®å©ç¹
- ããŒã ã®èªåŸæ§ã®åäžïŒ ç¬ç«ããããŒã ãä»ã®ããŒã ã«åœ±é¿ãäžããããšãªããã€ã¯ãããã³ããšã³ããéçºã»ãããã€ã§ããŸããããã«ãããèªåŸæ§ãšããéãéçºãµã€ã¯ã«ãä¿é²ãããŸãã
- ã¹ã±ãŒã©ããªãã£ã®åäžïŒ ãã€ã¯ãããã³ããšã³ãã¯ç¬ç«ããŠã¹ã±ãŒãªã³ã°ã§ããããããªãœãŒã¹å²ãåœãŠãæé©åããå¢å ãããã©ãã£ãã¯ã«å¯Ÿå¿ã§ããŸãã
- ä¿å®æ§ã®åŒ·åïŒ å°ããç¬ç«ãããŠãããã¯ãå€§èŠæš¡ãªã¢ããªã·ãã¯ã¢ããªã±ãŒã·ã§ã³ãšæ¯èŒããŠä¿å®ãšæŽæ°ã容æã§ãã
- æè¡ã®å€æ§æ§ïŒ ããŒã ã¯ãã€ã¯ãããã³ããšã³ãã«æé©ãªæè¡ã¹ã¿ãã¯ãéžæã§ãããã倧ããªæè»æ§ãšã€ãããŒã·ã§ã³ãå¯èœã«ããŸãã
- ãªã¹ã¯ã®è»œæžïŒ ãã€ã¯ãããã³ããšã³ãã®ç¬ç«ãããããã€ã¯ã倿Žããããã€ãããªã¹ã¯ãæžãããããŒã«ããã¯æé ãç°¡çŽ åããŸãã
- 段éçãªç§»è¡ïŒ å®å šãªæžãæããå¿ èŠãšããã«ãã¢ããªã·ãã¯ãªã¢ããªã±ãŒã·ã§ã³ããã€ã¯ãããã³ããšã³ãã¢ãŒããã¯ãã£ã«åŸã ã«ç§»è¡ã§ããŸãã
ãã€ã¯ãããã³ããšã³ãã¢ãŒããã¯ãã£ã®èª²é¡
ãã€ã¯ãããã³ããšã³ãã¯å€ãã®å©ç¹ãæäŸããŸãããããã€ãã®èª²é¡ããããããŸãïŒ
- è€éæ§ã®å¢å ïŒ è€æ°ã®ãã€ã¯ãããã³ããšã³ãã管çããããšã¯ãåäžã®ã¢ããªã·ãã¯ã¢ããªã±ãŒã·ã§ã³ã管çãããããè€éã«ãªãå¯èœæ§ããããŸãã
- éä¿¡ã®ãªãŒããŒãããïŒ ãã€ã¯ãããã³ããšã³ãéã®éä¿¡ã調æŽããããšã¯å°é£ãªå ŽåããããŸãã
- ãããã€ã®è€éæ§ïŒ è€æ°ã®ãã€ã¯ãããã³ããšã³ãããããã€ããããšã¯ãåäžã®ã¢ããªã±ãŒã·ã§ã³ããããã€ãããããè€éã«ãªãå¯èœæ§ããããŸãã
- äžè²«æ§ïŒ ãã€ã¯ãããã³ããšã³ãéã§äžè²«ãããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãç¶æããããšã¯é£ããå ŽåããããŸãã
- éè€ïŒ æ éãªèšç»ãªãã§ã¯ãã³ãŒããšäŸåé¢ä¿ããã€ã¯ãããã³ããšã³ãéã§éè€ããå¯èœæ§ããããŸãã
- éçšã®ãªãŒããŒãããïŒ è€æ°ã®ãã€ã¯ãããã³ããšã³ãã®ã€ã³ãã©ã¹ãã©ã¯ãã£ãã»ããã¢ããããã³ç®¡çãããšãéçšã®ãªãŒããŒããããå¢å ããå¯èœæ§ããããŸãã
Single-SPAã§ãã€ã¯ãããã³ããšã³ããæ§ç¯ããããã®ãã¹ããã©ã¯ãã£ã¹
single-SPAã§ãã€ã¯ãããã³ããšã³ãã¢ãŒããã¯ãã£ãæåè£ã«å®è£ ããã«ã¯ã次ã®ãã¹ããã©ã¯ãã£ã¹ã«åŸã£ãŠãã ããïŒ
- æç¢ºãªå¢çãå®çŸ©ããïŒ ãã€ã¯ãããã³ããšã³ãéã®å¢çãæç¢ºã«å®çŸ©ããŠãäŸåé¢ä¿ãšéä¿¡ã®ãªãŒããŒããããæå°éã«æããŸãã
- å ±æã¹ã¿ã€ã«ã¬ã€ãã確ç«ããïŒ å ±æã¹ã¿ã€ã«ã¬ã€ããäœæããŠããã€ã¯ãããã³ããšã³ãéã§äžè²«ãããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ã確ä¿ããŸãã
- ãããã€ãèªååããïŒ ãããã€ããã»ã¹ãèªååããŠããã€ã¯ãããã³ããšã³ãã®ãããã€ãç°¡çŽ åããŸãã
- ããã©ãŒãã³ã¹ãç£èŠããïŒ åãã€ã¯ãããã³ããšã³ãã®ããã©ãŒãã³ã¹ãç£èŠããŠãåé¡ãç¹å®ã解決ããŸãã
- äžå€®éæš©åãã®ã³ã°ã·ã¹ãã ã䜿çšããïŒ äžå€®éæš©åãã®ã³ã°ã·ã¹ãã ã䜿çšããŠããã¹ãŠã®ãã€ã¯ãããã³ããšã³ãããã®ãã°ãéçŽãããã©ãã«ã·ã¥ãŒãã£ã³ã°ãç°¡çŽ åããŸãã
- å ç¢ãªãšã©ãŒãã³ããªã³ã°ãå®è£ ããïŒ å ç¢ãªãšã©ãŒãã³ããªã³ã°ãå®è£ ããŠã1ã€ã®ãã€ã¯ãããã³ããšã³ãã®ãšã©ãŒãä»ã®ãã€ã¯ãããã³ããšã³ãã«åœ±é¿ãäžããªãããã«ããŸãã
- ã¢ãŒããã¯ãã£ãææžåããïŒ ãã€ã¯ãããã³ããšã³ãã¢ãŒããã¯ãã£ãææžåããŠãããŒã ã®å šå¡ããã®ä»çµã¿ãçè§£ã§ããããã«ããŸãã
- é©åãªéä¿¡æŠç¥ãéžæããïŒ ã¢ããªã±ãŒã·ã§ã³ã®ããŒãºã«åºã¥ããŠé©åãªéä¿¡æŠç¥ãéžæããŸãã
- ããã©ãŒãã³ã¹ãåªå ããïŒ åãã€ã¯ãããã³ããšã³ãã®ããã©ãŒãã³ã¹ãæé©åããŠãé«éã§å¿çæ§ã®é«ããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ã確ä¿ããŸãã
- ã»ãã¥ãªãã£ãèæ ®ããïŒ ã»ãã¥ãªãã£ã®ãã¹ããã©ã¯ãã£ã¹ãå®è£ ããŠããã€ã¯ãããã³ããšã³ãã¢ãŒããã¯ãã£ãè匱æ§ããä¿è·ããŸãã
- DevOpsã«ã«ãã£ãŒãæ¡çšããïŒ DevOpsã«ã«ãã£ãŒãè²ã¿ãéçºããŒã ãšéçšããŒã éã®ã³ã©ãã¬ãŒã·ã§ã³ãä¿é²ããŸãã
Single-SPAãšãã€ã¯ãããã³ããšã³ãã®ãŠãŒã¹ã±ãŒã¹
Single-SPAãšãã€ã¯ãããã³ããšã³ãã¯ã以äžã®ãããªããŸããŸãªãŠãŒã¹ã±ãŒã¹ã«é©ããŠããŸãïŒ
- å€§èŠæš¡ã§è€éãªã¢ããªã±ãŒã·ã§ã³ïŒ ãã€ã¯ãããã³ããšã³ãã¯ãå€§èŠæš¡ã§è€éãªã¢ããªã±ãŒã·ã§ã³ãããå°ããã管çãããããŠãããã«åå²ããã®ã«åœ¹ç«ã¡ãŸãã
- è€æ°ã®ããŒã ãæã€çµç¹ïŒ ãã€ã¯ãããã³ããšã³ãã¯ãç°ãªãããŒã ãã¢ããªã±ãŒã·ã§ã³ã®ç°ãªãéšåã«ç¬ç«ããŠåãçµãããšãå¯èœã«ããŸããäŸãã°ãã°ããŒãã«ãªeã³ããŒã¹äŒæ¥ã§ã¯ãããããŒã ã補åã«ã¿ãã°ïŒäŸïŒãã€ãæ ç¹ïŒã«éäžããå¥ã®ããŒã ãã·ã§ããã³ã°ã«ãŒãïŒäŸïŒã€ã³ãæ ç¹ïŒãæ åœãã3çªç®ã®ããŒã ããŠãŒã¶ãŒã¢ã«ãŠã³ãïŒäŸïŒç±³åœæ ç¹ïŒã管çããããšãã§ããŸãã
- ã¬ã¬ã·ãŒã¢ããªã±ãŒã·ã§ã³ã®ç§»è¡ïŒ ãã€ã¯ãããã³ããšã³ãã¯ãã¬ã¬ã·ãŒã¢ããªã±ãŒã·ã§ã³ãããè¿ä»£çãªã¢ãŒããã¯ãã£ã«åŸã ã«ç§»è¡ããããã«äœ¿çšã§ããŸãã
- Platform-as-a-Service (PaaS)ãœãªã¥ãŒã·ã§ã³ã®æ§ç¯ïŒ ãã€ã¯ãããã³ããšã³ãã¯ãéçºè ãç¬èªã®ã¢ããªã±ãŒã·ã§ã³ãäœæããã³ãããã€ã§ããPaaSãœãªã¥ãŒã·ã§ã³ãæ§ç¯ããããã«äœ¿çšã§ããŸãã
- ããŒãœãã©ã€ãºããããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ïŒ ç°ãªããã€ã¯ãããã³ããšã³ãã䜿çšããŠããŠãŒã¶ãŒã®åœ¹å²ã奜ã¿ããŸãã¯å Žæã«åºã¥ããŠããŒãœãã©ã€ãºããããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãæäŸã§ããŸãããŠãŒã¶ãŒã®èå³ãé²èЧ履æŽã«åºã¥ããŠç°ãªãã³ã³ãã³ãã¢ãžã¥ãŒã«ãåçã«èªã¿èŸŒããã¥ãŒã¹ãŠã§ããµã€ããæ³åããŠã¿ãŠãã ããã
ãã€ã¯ãããã³ããšã³ãã®æªæ¥
ãã€ã¯ãããã³ããšã³ãã¢ãŒããã¯ãã£ã¯é²åãç¶ããŠããã忣ããã³ããšã³ãã¢ããªã±ãŒã·ã§ã³ã®æ§ç¯ãšç®¡çã®èª²é¡ã«å¯ŸåŠããããã®æ°ããããŒã«ãæè¡ãç»å ŽããŠããŸããæ³šç®ãã¹ãããã€ãã®äž»èŠãªãã¬ã³ãã¯æ¬¡ã®ãšããã§ãïŒ
- Web ComponentsïŒ Web Componentsã¯ãã©ã®Webã¢ããªã±ãŒã·ã§ã³ã§ã䜿çšã§ããåå©çšå¯èœãªUIèŠçŽ ãäœæããããã®æšæºã§ããWeb Componentsã䜿çšããŠããã¬ãŒã ã¯ãŒã¯ã«äŸåãããç°ãªãã¢ããªã±ãŒã·ã§ã³ã«ç°¡åã«çµ±åã§ãããã€ã¯ãããã³ããšã³ããæ§ç¯ã§ããŸãã
- Module FederationïŒ Module Federationã¯ãç°ãªãWebpackãã«ãéã§ã³ãŒããšäŸåé¢ä¿ãå ±æã§ããWebpackã®æ©èœã§ããModule Federationã䜿çšããŠãççµåã§ç¬ç«ããŠãããã€å¯èœãªãã€ã¯ãããã³ããšã³ããæ§ç¯ã§ããŸãã
- ãµãŒããŒãµã€ãã¬ã³ããªã³ã° (SSR)ïŒ ãµãŒããŒãµã€ãã¬ã³ããªã³ã°ã¯ããã€ã¯ãããã³ããšã³ãã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ãšSEOãåäžãããããšãã§ããŸããSSRã䜿çšããŠãµãŒããŒäžã§ãã€ã¯ãããã³ããšã³ãã®åæHTMLãã¬ã³ããªã³ã°ããã¯ã©ã€ã¢ã³ãã§ããŠã³ããŒãããã³å®è¡ããå¿ èŠãããJavaScriptã®éãæžããããšãã§ããŸãã
- ãšããžã³ã³ãã¥ãŒãã£ã³ã°ïŒ ãšããžã³ã³ãã¥ãŒãã£ã³ã°ã䜿çšããŠããã€ã¯ãããã³ããšã³ãããŠãŒã¶ãŒã®è¿ãã«ãããã€ããé å»¶ãæžãããŠããã©ãŒãã³ã¹ãåäžãããããšãã§ããŸãããšããžã³ã³ãã¥ãŒãã£ã³ã°ã¯ããªãã©ã€ã³ã¢ã¯ã»ã¹ããªã¢ã«ã¿ã€ã ããŒã¿åŠçãªã©ããã€ã¯ãããã³ããšã³ãã®æ°ãããŠãŒã¹ã±ãŒã¹ãå¯èœã«ããŸãã
çµè«
Single-SPAã¯ãã¹ã±ãŒã©ãã«ã§ä¿å®æ§ãé«ããæè»ãªãã€ã¯ãããã³ããšã³ãã¢ãŒããã¯ãã£ãæ§ç¯ããããã®åŒ·åãªãã¬ãŒã ã¯ãŒã¯ã§ãããã€ã¯ãããã³ããšã³ãã®ååãåãå ¥ããsingle-SPAã®èœåãæŽ»çšããããšã§ãçµç¹ã¯ããŒã ã匷åããéçºãµã€ã¯ã«ãå éãããåªãããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãæäŸã§ããŸãããã€ã¯ãããã³ããšã³ãã¯è€éãã䌎ããŸããããã¹ããã©ã¯ãã£ã¹ãæ¡çšããæ éã«èšç»ããé©åãªããŒã«ãéžæããããšãæåã«ã¯äžå¯æ¬ ã§ãããã€ã¯ãããã³ããšã³ãã®äžçãé²åãç¶ããäžã§ãæ°ããæè¡ããã¯ããã¯ã«ã€ããŠåžžã«æ å ±ãåŸãããšããçŸä»£çã§å埩åã®ããWebã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã®éµãšãªããŸãã