├── .github └── FUNDING.yml ├── .gitignore ├── .travis.yml ├── LICENSE ├── Makefile ├── README.md ├── app1 ├── .browserslistrc ├── .gitignore ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── postcss.config.js ├── public │ ├── favicon.ico │ └── index.html ├── src │ ├── App.vue │ ├── assets │ │ └── logo.png │ ├── components │ │ └── HelloWorld.vue │ ├── main.js │ ├── router.js │ ├── set-public-path.js │ └── views │ │ └── Home.vue └── vue.config.js ├── app2 ├── .browserslistrc ├── .gitignore ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── postcss.config.js ├── public │ ├── favicon.ico │ └── index.html ├── src │ ├── App.vue │ ├── assets │ │ └── logo.png │ ├── components │ │ └── HelloWorld.vue │ ├── main.js │ ├── router.js │ ├── set-public-path.js │ └── views │ │ ├── About.vue │ │ └── Home.vue └── vue.config.js ├── navbar ├── .browserslistrc ├── .gitignore ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── postcss.config.js ├── public │ ├── favicon.ico │ └── index.html ├── src │ ├── App.vue │ ├── assets │ │ └── logo.png │ ├── main.js │ ├── router.js │ └── set-public-path.js └── vue.config.js └── root-html-file ├── index.html ├── package-lock.json └── package.json /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [joeldenning] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | 63 | static -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | 2 | # THIS IS NOT HOW YOU SHOULD DO DEPLOYMENTS FOR YOUR ORGANIZATION 3 | # 4 | # First off, the sed stuff for modifying import maps is quite hacky and shouldn't 5 | # be what you rely on. 6 | # 7 | # Secondly, each vue app should be in a separate repo and deployed separately, as 8 | # explained in the README.md. 9 | language: node_js 10 | node_js: 11 | - "node" 12 | script: 13 | - cd navbar && npm ci && npm run build && rm dist/index.html 14 | - cd ../app1 && npm ci && npm run build && rm dist/index.html 15 | - cd ../app2 && npm ci && npm run build && rm dist/index.html 16 | - cd .. 17 | - mkdir -p static/navbar static/app1 static/app2 && cp -a navbar/dist/* static/navbar && cp -a app1/dist/* static/app1 && cp -a app2/dist/* static/app2 18 | - cp root-html-file/index.html static 19 | - echo "Files that will be deployed" 20 | - find static 21 | - sed -i 's/http:\/\/localhost:8080/\/navbar/g' static/index.html 22 | - sed -i 's/http:\/\/localhost:8081/\/app1/g' static/index.html 23 | - sed -i 's/http:\/\/localhost:8082/\/app2/g' static/index.html 24 | - cp static/index.html static/200.html 25 | - echo "Files to deploy" 26 | - find static 27 | deploy: 28 | provider: surge 29 | project: ./static/ 30 | domain: coexisting-vue-microfrontends.surge.sh 31 | skip_cleanup: true -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Joel Denning 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | DEFAULT_GOAL := help 2 | 3 | port := 5000 4 | 5 | .PHONY: help 6 | help: 7 | @echo 8 | @echo Manage micro-frontends with single-spa 9 | @echo 10 | @fgrep "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/:.*## / - /' 11 | @echo 12 | 13 | .PHONY: install 14 | install: ## Install all dependencies 15 | @pushd ./root-html-file >/dev/null && (npm install &) && popd >/dev/null 16 | @pushd ./app1 >/dev/null && (npm install &) && popd >/dev/null 17 | @pushd ./app2 >/dev/null && (npm install &) && popd >/dev/null 18 | @pushd ./navbar >/dev/null && (npm install &) && popd >/dev/null 19 | 20 | .PHONY: clean 21 | clean: ## Clean all endpoints 22 | @rm */node_modules -rf 23 | 24 | .PHONY: start 25 | start: ## Start all endpoints 26 | @pushd ./root-html-file >/dev/null && (npx serve -s -l $(port) &) && popd >/dev/null 27 | @pushd ./app1 >/dev/null && (npx vue-cli-service serve --port 8081 &) && popd >/dev/null 28 | @pushd ./app2 >/dev/null && (npx vue-cli-service serve --port 8082 &) && popd >/dev/null 29 | @pushd ./navbar >/dev/null && (npx vue-cli-service serve --port 8080 &) && popd >/dev/null 30 | 31 | .PHONY: stop 32 | stop: ## Stop all endpoints 33 | @pkill -2 node 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Try the newer example repo 2 | 3 | The newer example demonstrating Vue Microfrontends can be found at https://github.com/vue-microfrontends and https://vue.microfrontends.app. That example better reflects the microfrontends architecture and is encouraged to use. 4 | 5 | # Coexisting Vue Microfrontends 6 | 7 | [![Build Status](https://travis-ci.org/joeldenning/coexisting-vue-microfrontends.svg?branch=master)](https://travis-ci.org/joeldenning/coexisting-vue-microfrontends) 8 | 9 | Demo: http://coexisting-vue-microfrontends.surge.sh 10 | 11 | This is a starter-kit / example repository for people who want to have multiple vue microfrontends coexist within a single page. Each 12 | of the vue applications was created by Vue CLI. 13 | 14 | It uses [single-spa](https://single-spa.js.org) to pull this off, which means that you can even add React, Angular, or other frameworks as 15 | additional microfrontends. 16 | 17 | ## An important note 18 | This github repository has four projects all in one repo. But when you do this yourself, **you'll want to have one git repo per 19 | vue application**. The root-html-file project should also be in its own repo. This is what lets different teams and developers be in 20 | charge of different microfrontends. 21 | 22 | ## Local development -- one app at a time 23 | [Tutorial video](https://www.youtube.com/watch?v=vjjcuIxqIzY&list=PLLUD8RtHvsAOhtHnyGx57EYXoaNsxGrTU&index=4) 24 | 25 | With single-spa, it is preferred to run `npm run serve` in only one single-spa application at a time, while using a deployed 26 | version of the other applications. This makes for an awesome developer experience where you can boot up just one 27 | microfrontend at a time, not even having to clone, npm install, or boot up all of the other ones. 28 | 29 | To try this out, clone the repo and run the following commands: 30 | ```sh 31 | cd app1 32 | npm i 33 | npm run serve 34 | ``` 35 | 36 | Now go to http://coexisting-vue-microfrontends.surge.sh in a browser. In a browser console, run `localStorage.setItem('overrides-ui', true)`. 37 | Refresh the page. Now click on the yellowish rectangle at the bottom right. Then click on `app1`. Change the module url to http://localhost:8081/js/app.js. Then apply the override and reload the page. This will have change app1 to load from your localhost instead of from surge.sh. 38 | As you modify the code locally, it will reload the page on coexisting-vue-microfrontends.surge.sh. See 39 | https://github.com/joeldenning/import-map-overrides for more info on this. 40 | 41 | ## Local development -- all at once 42 | It is preferred to only run one app at a time. But if you need to run them all locally, you can do so with the following instructions 43 | 44 | ```sh 45 | # First terminal tab 46 | cd root-html-file 47 | npm install 48 | npm run serve 49 | ``` 50 | ```sh 51 | # Second terminal tab 52 | cd app1 53 | npm install 54 | npm run serve 55 | ``` 56 | 57 | ```sh 58 | # Third terminal tab 59 | cd app2 60 | npm install 61 | npm run serve 62 | ``` 63 | 64 | ```sh 65 | # Fourth terminal tab 66 | cd navbar 67 | npm install 68 | npm run serve 69 | ``` 70 | 71 | Now go to http://localhost:5000 in a browser. Note that you can change any of the ports for the projects by modifying the Import Map inside of 72 | root-html-file/index.html. 73 | 74 | If you get serious about deploying your code, you'll want to make it no longer necessary to boot up all of the apps in order to do anything. 75 | When you get to that point, check out [import-map-overrides](https://github.com/joeldenning/import-map-overrides/), which lets you go to 76 | a deployed environment and override the [Import Map](https://github.com/WICG/import-maps) for just one microfrontend at a time. The 77 | import-map-overrides library is already loaded in the index.html of root-html-file, so you can start using it immediately. You can make your 78 | deployed environment overridable, just like you can do overrides on http://coexisting-vue-microfrontends.surge.sh 79 | 80 | ## More documentation 81 | Go to https://single-spa.js.org/docs/ecosystem-vue.html to learn how all of this works. 82 | -------------------------------------------------------------------------------- /app1/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | -------------------------------------------------------------------------------- /app1/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /app1/README.md: -------------------------------------------------------------------------------- 1 | # app1 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Run your tests 19 | ``` 20 | npm run test 21 | ``` 22 | 23 | ### Lints and fixes files 24 | ``` 25 | npm run lint 26 | ``` 27 | 28 | ### Customize configuration 29 | See [Configuration Reference](https://cli.vuejs.org/config/). 30 | -------------------------------------------------------------------------------- /app1/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /app1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app1", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve --port 8081", 7 | "build": "vue-cli-service build" 8 | }, 9 | "dependencies": { 10 | "core-js": "^3.4.3", 11 | "single-spa-vue": "^1.5.4", 12 | "systemjs-webpack-interop": "^1.1.2", 13 | "vue": "^2.6.10", 14 | "vue-router": "^3.1.3" 15 | }, 16 | "devDependencies": { 17 | "@vue/cli-plugin-babel": "^4.1.0", 18 | "@vue/cli-plugin-router": "^4.1.0", 19 | "@vue/cli-service": "^4.1.0", 20 | "vue-cli-plugin-single-spa": "^1.0.1", 21 | "vue-template-compiler": "^2.6.10" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app1/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /app1/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jolyndenning/coexisting-vue-microfrontends/8181085c5f4557f63b84f9dea5f8085cd5e38af4/app1/public/favicon.ico -------------------------------------------------------------------------------- /app1/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | app1 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /app1/src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 18 | -------------------------------------------------------------------------------- /app1/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jolyndenning/coexisting-vue-microfrontends/8181085c5f4557f63b84f9dea5f8085cd5e38af4/app1/src/assets/logo.png -------------------------------------------------------------------------------- /app1/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 40 | 41 | 42 | 58 | -------------------------------------------------------------------------------- /app1/src/main.js: -------------------------------------------------------------------------------- 1 | import './set-public-path' 2 | import Vue from 'vue'; 3 | import App from './App.vue'; 4 | import router from './router'; 5 | import singleSpaVue from 'single-spa-vue'; 6 | 7 | Vue.config.productionTip = false; 8 | 9 | const vueLifecycles = singleSpaVue({ 10 | Vue, 11 | appOptions: { 12 | render: (h) => h(App), 13 | router, 14 | }, 15 | }); 16 | 17 | export const bootstrap = vueLifecycles.bootstrap; 18 | export const mount = vueLifecycles.mount; 19 | export const unmount = vueLifecycles.unmount; 20 | -------------------------------------------------------------------------------- /app1/src/router.js: -------------------------------------------------------------------------------- 1 | import Router from 'vue-router' 2 | import Home from './views/Home.vue' 3 | 4 | export default new Router({ 5 | mode: 'history', 6 | base: process.env.BASE_URL, 7 | routes: [ 8 | { 9 | path: '/app1', 10 | name: 'home', 11 | component: Home 12 | }, 13 | ] 14 | }) 15 | -------------------------------------------------------------------------------- /app1/src/set-public-path.js: -------------------------------------------------------------------------------- 1 | import { setPublicPath } from 'systemjs-webpack-interop' 2 | 3 | setPublicPath('app1', 2) -------------------------------------------------------------------------------- /app1/src/views/Home.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 21 | -------------------------------------------------------------------------------- /app1/vue.config.js: -------------------------------------------------------------------------------- 1 | // Temporary until we can use https://github.com/webpack/webpack-dev-server/pull/2143 2 | module.exports = { 3 | chainWebpack: config => { 4 | config.devServer.set('inline', false) 5 | config.devServer.set('hot', true) 6 | // Vue CLI 4 output filename is js/[chunkName].js, different from Vue CLI 3 7 | // More Detail: https://github.com/vuejs/vue-cli/blob/master/packages/%40vue/cli-service/lib/config/app.js#L29 8 | if (process.env.NODE_ENV !== 'production') { 9 | config.output.filename(`js/[name].js`) 10 | } 11 | config.externals(['vue', 'vue-router']) 12 | }, 13 | filenameHashing: false 14 | } 15 | -------------------------------------------------------------------------------- /app2/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | -------------------------------------------------------------------------------- /app2/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /app2/README.md: -------------------------------------------------------------------------------- 1 | # app2 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Run your tests 19 | ``` 20 | npm run test 21 | ``` 22 | 23 | ### Lints and fixes files 24 | ``` 25 | npm run lint 26 | ``` 27 | 28 | ### Customize configuration 29 | See [Configuration Reference](https://cli.vuejs.org/config/). 30 | -------------------------------------------------------------------------------- /app2/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /app2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app2", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve --port 8082", 7 | "build": "vue-cli-service build" 8 | }, 9 | "dependencies": { 10 | "core-js": "^3.4.3", 11 | "single-spa-vue": "^1.5.4", 12 | "systemjs-webpack-interop": "^1.1.2", 13 | "vue": "^2.6.10", 14 | "vue-router": "^3.1.3" 15 | }, 16 | "devDependencies": { 17 | "@vue/cli-plugin-babel": "^4.1.0", 18 | "@vue/cli-plugin-router": "^4.1.0", 19 | "@vue/cli-service": "^4.1.0", 20 | "vue-cli-plugin-single-spa": "^1.0.1", 21 | "vue-template-compiler": "^2.6.10" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app2/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /app2/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jolyndenning/coexisting-vue-microfrontends/8181085c5f4557f63b84f9dea5f8085cd5e38af4/app2/public/favicon.ico -------------------------------------------------------------------------------- /app2/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | app2 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /app2/src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 18 | -------------------------------------------------------------------------------- /app2/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jolyndenning/coexisting-vue-microfrontends/8181085c5f4557f63b84f9dea5f8085cd5e38af4/app2/src/assets/logo.png -------------------------------------------------------------------------------- /app2/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 15 | 16 | 17 | 33 | -------------------------------------------------------------------------------- /app2/src/main.js: -------------------------------------------------------------------------------- 1 | import './set-public-path' 2 | import Vue from 'vue'; 3 | import App from './App.vue'; 4 | import router from './router'; 5 | import singleSpaVue from 'single-spa-vue'; 6 | 7 | Vue.config.productionTip = false; 8 | 9 | const vueLifecycles = singleSpaVue({ 10 | Vue, 11 | appOptions: { 12 | render: (h) => h(App), 13 | router, 14 | }, 15 | }); 16 | 17 | export const bootstrap = vueLifecycles.bootstrap; 18 | export const mount = vueLifecycles.mount; 19 | export const unmount = vueLifecycles.unmount; 20 | -------------------------------------------------------------------------------- /app2/src/router.js: -------------------------------------------------------------------------------- 1 | import Router from 'vue-router' 2 | import Home from './views/Home.vue' 3 | 4 | export default new Router({ 5 | mode: 'history', 6 | base: process.env.BASE_URL, 7 | routes: [ 8 | { 9 | path: '/app2', 10 | name: 'home', 11 | component: Home 12 | }, 13 | { 14 | path: '/app2/about', 15 | name: 'about', 16 | // route level code-splitting 17 | // this generates a separate chunk (about.[hash].js) for this route 18 | // which is lazy-loaded when the route is visited. 19 | component: () => import(/* webpackChunkName: "about" */ './views/About.vue') 20 | } 21 | ] 22 | }) 23 | -------------------------------------------------------------------------------- /app2/src/set-public-path.js: -------------------------------------------------------------------------------- 1 | import { setPublicPath } from 'systemjs-webpack-interop' 2 | 3 | setPublicPath('app2', 2) -------------------------------------------------------------------------------- /app2/src/views/About.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /app2/src/views/Home.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 19 | -------------------------------------------------------------------------------- /app2/vue.config.js: -------------------------------------------------------------------------------- 1 | // Temporary until we can use https://github.com/webpack/webpack-dev-server/pull/2143 2 | module.exports = { 3 | chainWebpack: config => { 4 | config.devServer.set('inline', false) 5 | config.devServer.set('hot', true) 6 | // Vue CLI 4 output filename is js/[chunkName].js, different from Vue CLI 3 7 | // More Detail: https://github.com/vuejs/vue-cli/blob/master/packages/%40vue/cli-service/lib/config/app.js#L29 8 | if (process.env.NODE_ENV !== 'production') { 9 | config.output.filename(`js/[name].js`) 10 | } 11 | config.externals(['vue', 'vue-router']) 12 | }, 13 | filenameHashing: false, 14 | } 15 | -------------------------------------------------------------------------------- /navbar/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | -------------------------------------------------------------------------------- /navbar/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /navbar/README.md: -------------------------------------------------------------------------------- 1 | # navbar 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Run your tests 19 | ``` 20 | npm run test 21 | ``` 22 | 23 | ### Lints and fixes files 24 | ``` 25 | npm run lint 26 | ``` 27 | 28 | ### Customize configuration 29 | See [Configuration Reference](https://cli.vuejs.org/config/). 30 | -------------------------------------------------------------------------------- /navbar/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /navbar/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "navbar", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve --port 8080", 7 | "build": "vue-cli-service build" 8 | }, 9 | "dependencies": { 10 | "core-js": "^3.4.3", 11 | "single-spa-vue": "^1.5.4", 12 | "systemjs-webpack-interop": "^1.1.2", 13 | "vue": "^2.6.10", 14 | "vue-router": "^3.1.3" 15 | }, 16 | "devDependencies": { 17 | "@vue/cli-plugin-babel": "^4.1.0", 18 | "@vue/cli-plugin-router": "^4.1.0", 19 | "@vue/cli-service": "^4.1.0", 20 | "vue-cli-plugin-single-spa": "^1.0.1", 21 | "vue-template-compiler": "^2.6.10" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /navbar/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /navbar/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jolyndenning/coexisting-vue-microfrontends/8181085c5f4557f63b84f9dea5f8085cd5e38af4/navbar/public/favicon.ico -------------------------------------------------------------------------------- /navbar/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | navbar 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /navbar/src/App.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 32 | -------------------------------------------------------------------------------- /navbar/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jolyndenning/coexisting-vue-microfrontends/8181085c5f4557f63b84f9dea5f8085cd5e38af4/navbar/src/assets/logo.png -------------------------------------------------------------------------------- /navbar/src/main.js: -------------------------------------------------------------------------------- 1 | import './set-public-path' 2 | import Vue from 'vue'; 3 | import App from './App.vue'; 4 | import router from './router'; 5 | import singleSpaVue from 'single-spa-vue'; 6 | 7 | Vue.config.productionTip = false; 8 | 9 | const vueLifecycles = singleSpaVue({ 10 | Vue, 11 | appOptions: { 12 | render: (h) => h(App), 13 | router, 14 | }, 15 | }); 16 | 17 | export const bootstrap = vueLifecycles.bootstrap; 18 | export const mount = vueLifecycles.mount; 19 | export const unmount = vueLifecycles.unmount; 20 | -------------------------------------------------------------------------------- /navbar/src/router.js: -------------------------------------------------------------------------------- 1 | import Router from 'vue-router' 2 | 3 | export default new Router({ 4 | mode: 'history', 5 | base: process.env.BASE_URL, 6 | routes: [ 7 | // { 8 | // path: '/', 9 | // name: 'home', 10 | // component: Home 11 | // }, 12 | // { 13 | // path: '/about', 14 | // name: 'about', 15 | // // route level code-splitting 16 | // // this generates a separate chunk (about.[hash].js) for this route 17 | // // which is lazy-loaded when the route is visited. 18 | // component: () => import(/* webpackChunkName: "about" */ './views/About.vue') 19 | // } 20 | ] 21 | }) 22 | -------------------------------------------------------------------------------- /navbar/src/set-public-path.js: -------------------------------------------------------------------------------- 1 | import { setPublicPath } from 'systemjs-webpack-interop' 2 | 3 | setPublicPath('navbar', 2) -------------------------------------------------------------------------------- /navbar/vue.config.js: -------------------------------------------------------------------------------- 1 | // Temporary until we can use https://github.com/webpack/webpack-dev-server/pull/2143 2 | module.exports = { 3 | chainWebpack: config => { 4 | config.devServer.set('inline', false) 5 | config.devServer.set('hot', false) 6 | // Vue CLI 4 output filename is js/[chunkName].js, different from Vue CLI 3 7 | // More Detail: https://github.com/vuejs/vue-cli/blob/master/packages/%40vue/cli-service/lib/config/app.js#L29 8 | if (process.env.NODE_ENV !== 'production') { 9 | config.output.filename(`js/[name].js`) 10 | } 11 | config.externals(['vue', 'vue-router']) 12 | }, 13 | filenameHashing: false, 14 | } -------------------------------------------------------------------------------- /root-html-file/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Coexisting Vue Microfrontends 7 | 8 | 9 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /root-html-file/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "root-html-file", 3 | "requires": true, 4 | "lockfileVersion": 1, 5 | "dependencies": { 6 | "@zeit/schemas": { 7 | "version": "2.6.0", 8 | "resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.6.0.tgz", 9 | "integrity": "sha512-uUrgZ8AxS+Lio0fZKAipJjAh415JyrOZowliZAzmnJSsf7piVL5w+G0+gFJ0KSu3QRhvui/7zuvpLz03YjXAhg==", 10 | "dev": true 11 | }, 12 | "accepts": { 13 | "version": "1.3.7", 14 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 15 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", 16 | "dev": true, 17 | "requires": { 18 | "mime-types": "~2.1.24", 19 | "negotiator": "0.6.2" 20 | } 21 | }, 22 | "ajv": { 23 | "version": "6.5.3", 24 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.3.tgz", 25 | "integrity": "sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg==", 26 | "dev": true, 27 | "requires": { 28 | "fast-deep-equal": "^2.0.1", 29 | "fast-json-stable-stringify": "^2.0.0", 30 | "json-schema-traverse": "^0.4.1", 31 | "uri-js": "^4.2.2" 32 | } 33 | }, 34 | "ansi-align": { 35 | "version": "2.0.0", 36 | "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", 37 | "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", 38 | "dev": true, 39 | "requires": { 40 | "string-width": "^2.0.0" 41 | } 42 | }, 43 | "ansi-regex": { 44 | "version": "3.0.0", 45 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 46 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", 47 | "dev": true 48 | }, 49 | "ansi-styles": { 50 | "version": "3.2.1", 51 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 52 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 53 | "dev": true, 54 | "requires": { 55 | "color-convert": "^1.9.0" 56 | } 57 | }, 58 | "arch": { 59 | "version": "2.1.1", 60 | "resolved": "https://registry.npmjs.org/arch/-/arch-2.1.1.tgz", 61 | "integrity": "sha512-BLM56aPo9vLLFVa8+/+pJLnrZ7QGGTVHWsCwieAWT9o9K8UeGaQbzZbGoabWLOo2ksBCztoXdqBZBplqLDDCSg==", 62 | "dev": true 63 | }, 64 | "arg": { 65 | "version": "2.0.0", 66 | "resolved": "https://registry.npmjs.org/arg/-/arg-2.0.0.tgz", 67 | "integrity": "sha512-XxNTUzKnz1ctK3ZIcI2XUPlD96wbHP2nGqkPKpvk/HNRlPveYrXIVSTk9m3LcqOgDPg3B1nMvdV/K8wZd7PG4w==", 68 | "dev": true 69 | }, 70 | "balanced-match": { 71 | "version": "1.0.0", 72 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 73 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 74 | "dev": true 75 | }, 76 | "boxen": { 77 | "version": "1.3.0", 78 | "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", 79 | "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", 80 | "dev": true, 81 | "requires": { 82 | "ansi-align": "^2.0.0", 83 | "camelcase": "^4.0.0", 84 | "chalk": "^2.0.1", 85 | "cli-boxes": "^1.0.0", 86 | "string-width": "^2.0.0", 87 | "term-size": "^1.2.0", 88 | "widest-line": "^2.0.0" 89 | } 90 | }, 91 | "brace-expansion": { 92 | "version": "1.1.11", 93 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 94 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 95 | "dev": true, 96 | "requires": { 97 | "balanced-match": "^1.0.0", 98 | "concat-map": "0.0.1" 99 | } 100 | }, 101 | "bytes": { 102 | "version": "3.0.0", 103 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", 104 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", 105 | "dev": true 106 | }, 107 | "camelcase": { 108 | "version": "4.1.0", 109 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", 110 | "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", 111 | "dev": true 112 | }, 113 | "chalk": { 114 | "version": "2.4.1", 115 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", 116 | "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", 117 | "dev": true, 118 | "requires": { 119 | "ansi-styles": "^3.2.1", 120 | "escape-string-regexp": "^1.0.5", 121 | "supports-color": "^5.3.0" 122 | } 123 | }, 124 | "cli-boxes": { 125 | "version": "1.0.0", 126 | "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", 127 | "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", 128 | "dev": true 129 | }, 130 | "clipboardy": { 131 | "version": "1.2.3", 132 | "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-1.2.3.tgz", 133 | "integrity": "sha512-2WNImOvCRe6r63Gk9pShfkwXsVtKCroMAevIbiae021mS850UkWPbevxsBz3tnvjZIEGvlwaqCPsw+4ulzNgJA==", 134 | "dev": true, 135 | "requires": { 136 | "arch": "^2.1.0", 137 | "execa": "^0.8.0" 138 | }, 139 | "dependencies": { 140 | "execa": { 141 | "version": "0.8.0", 142 | "resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz", 143 | "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=", 144 | "dev": true, 145 | "requires": { 146 | "cross-spawn": "^5.0.1", 147 | "get-stream": "^3.0.0", 148 | "is-stream": "^1.1.0", 149 | "npm-run-path": "^2.0.0", 150 | "p-finally": "^1.0.0", 151 | "signal-exit": "^3.0.0", 152 | "strip-eof": "^1.0.0" 153 | } 154 | } 155 | } 156 | }, 157 | "color-convert": { 158 | "version": "1.9.3", 159 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 160 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 161 | "dev": true, 162 | "requires": { 163 | "color-name": "1.1.3" 164 | } 165 | }, 166 | "color-name": { 167 | "version": "1.1.3", 168 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 169 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 170 | "dev": true 171 | }, 172 | "compressible": { 173 | "version": "2.0.17", 174 | "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.17.tgz", 175 | "integrity": "sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==", 176 | "dev": true, 177 | "requires": { 178 | "mime-db": ">= 1.40.0 < 2" 179 | } 180 | }, 181 | "compression": { 182 | "version": "1.7.3", 183 | "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.3.tgz", 184 | "integrity": "sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==", 185 | "dev": true, 186 | "requires": { 187 | "accepts": "~1.3.5", 188 | "bytes": "3.0.0", 189 | "compressible": "~2.0.14", 190 | "debug": "2.6.9", 191 | "on-headers": "~1.0.1", 192 | "safe-buffer": "5.1.2", 193 | "vary": "~1.1.2" 194 | } 195 | }, 196 | "concat-map": { 197 | "version": "0.0.1", 198 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 199 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 200 | "dev": true 201 | }, 202 | "content-disposition": { 203 | "version": "0.5.2", 204 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", 205 | "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", 206 | "dev": true 207 | }, 208 | "cross-spawn": { 209 | "version": "5.1.0", 210 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", 211 | "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", 212 | "dev": true, 213 | "requires": { 214 | "lru-cache": "^4.0.1", 215 | "shebang-command": "^1.2.0", 216 | "which": "^1.2.9" 217 | } 218 | }, 219 | "debug": { 220 | "version": "2.6.9", 221 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 222 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 223 | "dev": true, 224 | "requires": { 225 | "ms": "2.0.0" 226 | } 227 | }, 228 | "deep-extend": { 229 | "version": "0.6.0", 230 | "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", 231 | "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", 232 | "dev": true 233 | }, 234 | "escape-string-regexp": { 235 | "version": "1.0.5", 236 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 237 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 238 | "dev": true 239 | }, 240 | "execa": { 241 | "version": "0.7.0", 242 | "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", 243 | "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", 244 | "dev": true, 245 | "requires": { 246 | "cross-spawn": "^5.0.1", 247 | "get-stream": "^3.0.0", 248 | "is-stream": "^1.1.0", 249 | "npm-run-path": "^2.0.0", 250 | "p-finally": "^1.0.0", 251 | "signal-exit": "^3.0.0", 252 | "strip-eof": "^1.0.0" 253 | } 254 | }, 255 | "fast-deep-equal": { 256 | "version": "2.0.1", 257 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", 258 | "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", 259 | "dev": true 260 | }, 261 | "fast-json-stable-stringify": { 262 | "version": "2.0.0", 263 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 264 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", 265 | "dev": true 266 | }, 267 | "fast-url-parser": { 268 | "version": "1.1.3", 269 | "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", 270 | "integrity": "sha1-9K8+qfNNiicc9YrSs3WfQx8LMY0=", 271 | "dev": true, 272 | "requires": { 273 | "punycode": "^1.3.2" 274 | }, 275 | "dependencies": { 276 | "punycode": { 277 | "version": "1.4.1", 278 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 279 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", 280 | "dev": true 281 | } 282 | } 283 | }, 284 | "get-stream": { 285 | "version": "3.0.0", 286 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", 287 | "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", 288 | "dev": true 289 | }, 290 | "has-flag": { 291 | "version": "3.0.0", 292 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 293 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 294 | "dev": true 295 | }, 296 | "ini": { 297 | "version": "1.3.7", 298 | "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", 299 | "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", 300 | "dev": true 301 | }, 302 | "is-fullwidth-code-point": { 303 | "version": "2.0.0", 304 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 305 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 306 | "dev": true 307 | }, 308 | "is-stream": { 309 | "version": "1.1.0", 310 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", 311 | "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", 312 | "dev": true 313 | }, 314 | "isexe": { 315 | "version": "2.0.0", 316 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 317 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 318 | "dev": true 319 | }, 320 | "json-schema-traverse": { 321 | "version": "0.4.1", 322 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 323 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 324 | "dev": true 325 | }, 326 | "lru-cache": { 327 | "version": "4.1.5", 328 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", 329 | "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", 330 | "dev": true, 331 | "requires": { 332 | "pseudomap": "^1.0.2", 333 | "yallist": "^2.1.2" 334 | } 335 | }, 336 | "mime-db": { 337 | "version": "1.40.0", 338 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", 339 | "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", 340 | "dev": true 341 | }, 342 | "mime-types": { 343 | "version": "2.1.24", 344 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", 345 | "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", 346 | "dev": true, 347 | "requires": { 348 | "mime-db": "1.40.0" 349 | } 350 | }, 351 | "minimatch": { 352 | "version": "3.0.4", 353 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 354 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 355 | "dev": true, 356 | "requires": { 357 | "brace-expansion": "^1.1.7" 358 | } 359 | }, 360 | "minimist": { 361 | "version": "1.2.5", 362 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", 363 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", 364 | "dev": true 365 | }, 366 | "ms": { 367 | "version": "2.0.0", 368 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 369 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 370 | "dev": true 371 | }, 372 | "negotiator": { 373 | "version": "0.6.2", 374 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", 375 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", 376 | "dev": true 377 | }, 378 | "npm-run-path": { 379 | "version": "2.0.2", 380 | "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", 381 | "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", 382 | "dev": true, 383 | "requires": { 384 | "path-key": "^2.0.0" 385 | } 386 | }, 387 | "on-headers": { 388 | "version": "1.0.2", 389 | "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", 390 | "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", 391 | "dev": true 392 | }, 393 | "p-finally": { 394 | "version": "1.0.0", 395 | "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", 396 | "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", 397 | "dev": true 398 | }, 399 | "path-is-inside": { 400 | "version": "1.0.2", 401 | "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", 402 | "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", 403 | "dev": true 404 | }, 405 | "path-key": { 406 | "version": "2.0.1", 407 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", 408 | "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", 409 | "dev": true 410 | }, 411 | "path-to-regexp": { 412 | "version": "2.2.1", 413 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz", 414 | "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==", 415 | "dev": true 416 | }, 417 | "pseudomap": { 418 | "version": "1.0.2", 419 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", 420 | "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", 421 | "dev": true 422 | }, 423 | "punycode": { 424 | "version": "2.1.1", 425 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 426 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", 427 | "dev": true 428 | }, 429 | "range-parser": { 430 | "version": "1.2.0", 431 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", 432 | "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", 433 | "dev": true 434 | }, 435 | "rc": { 436 | "version": "1.2.8", 437 | "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", 438 | "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", 439 | "dev": true, 440 | "requires": { 441 | "deep-extend": "^0.6.0", 442 | "ini": "~1.3.0", 443 | "minimist": "^1.2.0", 444 | "strip-json-comments": "~2.0.1" 445 | } 446 | }, 447 | "registry-auth-token": { 448 | "version": "3.3.2", 449 | "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", 450 | "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", 451 | "dev": true, 452 | "requires": { 453 | "rc": "^1.1.6", 454 | "safe-buffer": "^5.0.1" 455 | } 456 | }, 457 | "registry-url": { 458 | "version": "3.1.0", 459 | "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", 460 | "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", 461 | "dev": true, 462 | "requires": { 463 | "rc": "^1.0.1" 464 | } 465 | }, 466 | "safe-buffer": { 467 | "version": "5.1.2", 468 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 469 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 470 | "dev": true 471 | }, 472 | "serve": { 473 | "version": "11.1.0", 474 | "resolved": "https://registry.npmjs.org/serve/-/serve-11.1.0.tgz", 475 | "integrity": "sha512-+4wpDtOSS+4ZLyDWMxThutA3iOTawX2+yDovOI8cjOUOmemyvNlHyFAsezBlSgbZKTYChI3tzA1Mh0z6XZ62qA==", 476 | "dev": true, 477 | "requires": { 478 | "@zeit/schemas": "2.6.0", 479 | "ajv": "6.5.3", 480 | "arg": "2.0.0", 481 | "boxen": "1.3.0", 482 | "chalk": "2.4.1", 483 | "clipboardy": "1.2.3", 484 | "compression": "1.7.3", 485 | "serve-handler": "6.1.0", 486 | "update-check": "1.5.2" 487 | } 488 | }, 489 | "serve-handler": { 490 | "version": "6.1.0", 491 | "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.0.tgz", 492 | "integrity": "sha512-63N075Tn3PsFYcu0NVV7tb367UbiW3gnC+/50ohL4oqOhAG6bmbaWqiRcXQgbzqc0ALBjSAzg7VTfa0Qw4E3hA==", 493 | "dev": true, 494 | "requires": { 495 | "bytes": "3.0.0", 496 | "content-disposition": "0.5.2", 497 | "fast-url-parser": "1.1.3", 498 | "mime-types": "2.1.18", 499 | "minimatch": "3.0.4", 500 | "path-is-inside": "1.0.2", 501 | "path-to-regexp": "2.2.1", 502 | "range-parser": "1.2.0" 503 | }, 504 | "dependencies": { 505 | "mime-db": { 506 | "version": "1.33.0", 507 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", 508 | "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", 509 | "dev": true 510 | }, 511 | "mime-types": { 512 | "version": "2.1.18", 513 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", 514 | "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", 515 | "dev": true, 516 | "requires": { 517 | "mime-db": "~1.33.0" 518 | } 519 | } 520 | } 521 | }, 522 | "shebang-command": { 523 | "version": "1.2.0", 524 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 525 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", 526 | "dev": true, 527 | "requires": { 528 | "shebang-regex": "^1.0.0" 529 | } 530 | }, 531 | "shebang-regex": { 532 | "version": "1.0.0", 533 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 534 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", 535 | "dev": true 536 | }, 537 | "signal-exit": { 538 | "version": "3.0.2", 539 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 540 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", 541 | "dev": true 542 | }, 543 | "string-width": { 544 | "version": "2.1.1", 545 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 546 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 547 | "dev": true, 548 | "requires": { 549 | "is-fullwidth-code-point": "^2.0.0", 550 | "strip-ansi": "^4.0.0" 551 | } 552 | }, 553 | "strip-ansi": { 554 | "version": "4.0.0", 555 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 556 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 557 | "dev": true, 558 | "requires": { 559 | "ansi-regex": "^3.0.0" 560 | } 561 | }, 562 | "strip-eof": { 563 | "version": "1.0.0", 564 | "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", 565 | "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", 566 | "dev": true 567 | }, 568 | "strip-json-comments": { 569 | "version": "2.0.1", 570 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 571 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", 572 | "dev": true 573 | }, 574 | "supports-color": { 575 | "version": "5.5.0", 576 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 577 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 578 | "dev": true, 579 | "requires": { 580 | "has-flag": "^3.0.0" 581 | } 582 | }, 583 | "term-size": { 584 | "version": "1.2.0", 585 | "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", 586 | "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", 587 | "dev": true, 588 | "requires": { 589 | "execa": "^0.7.0" 590 | } 591 | }, 592 | "update-check": { 593 | "version": "1.5.2", 594 | "resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.2.tgz", 595 | "integrity": "sha512-1TrmYLuLj/5ZovwUS7fFd1jMH3NnFDN1y1A8dboedIDt7zs/zJMo6TwwlhYKkSeEwzleeiSBV5/3c9ufAQWDaQ==", 596 | "dev": true, 597 | "requires": { 598 | "registry-auth-token": "3.3.2", 599 | "registry-url": "3.1.0" 600 | } 601 | }, 602 | "uri-js": { 603 | "version": "4.2.2", 604 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", 605 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", 606 | "dev": true, 607 | "requires": { 608 | "punycode": "^2.1.0" 609 | } 610 | }, 611 | "vary": { 612 | "version": "1.1.2", 613 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 614 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", 615 | "dev": true 616 | }, 617 | "which": { 618 | "version": "1.3.1", 619 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 620 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 621 | "dev": true, 622 | "requires": { 623 | "isexe": "^2.0.0" 624 | } 625 | }, 626 | "widest-line": { 627 | "version": "2.0.1", 628 | "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", 629 | "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", 630 | "dev": true, 631 | "requires": { 632 | "string-width": "^2.1.1" 633 | } 634 | }, 635 | "yallist": { 636 | "version": "2.1.2", 637 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", 638 | "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", 639 | "dev": true 640 | } 641 | } 642 | } 643 | -------------------------------------------------------------------------------- /root-html-file/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "root-html-file", 3 | "scripts": { 4 | "serve": "serve -s -l 5000" 5 | }, 6 | "devDependencies": { 7 | "serve": "^11.1.0" 8 | } 9 | } 10 | --------------------------------------------------------------------------------