├── .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 | [](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 |