├── .editorconfig
├── .eslintrc.json
├── .gitignore
├── .prettierignore
├── .prettierrc
├── .vscode
├── extensions.json
└── settings.json
├── LICENSE
├── README.md
├── angular.json
├── apps
├── .gitkeep
├── react-mfe-e2e
│ ├── .eslintrc.json
│ ├── cypress.json
│ ├── project.json
│ ├── src
│ │ ├── fixtures
│ │ │ └── example.json
│ │ ├── integration
│ │ │ └── app.spec.ts
│ │ └── support
│ │ │ ├── app.po.ts
│ │ │ ├── commands.ts
│ │ │ └── index.ts
│ └── tsconfig.json
├── react-mfe
│ ├── .babelrc
│ ├── .browserslistrc
│ ├── .eslintrc.json
│ ├── jest.config.ts
│ ├── project.json
│ ├── src
│ │ ├── app
│ │ │ ├── app.module.scss
│ │ │ ├── app.spec.tsx
│ │ │ ├── app.tsx
│ │ │ └── nx-welcome.tsx
│ │ ├── assets
│ │ │ ├── .gitkeep
│ │ │ └── icons
│ │ │ │ └── react-icon.svg
│ │ ├── custom-router.tsx
│ │ ├── environments
│ │ │ ├── environment.prod.ts
│ │ │ └── environment.ts
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── main.tsx
│ │ ├── polyfills.ts
│ │ └── styles.scss
│ ├── tsconfig.app.json
│ ├── tsconfig.json
│ └── tsconfig.spec.json
├── shell-e2e
│ ├── .eslintrc.json
│ ├── cypress.json
│ ├── project.json
│ ├── src
│ │ ├── fixtures
│ │ │ └── example.json
│ │ ├── integration
│ │ │ └── app.spec.ts
│ │ └── support
│ │ │ ├── app.po.ts
│ │ │ ├── commands.ts
│ │ │ └── index.ts
│ └── tsconfig.json
└── shell
│ ├── .browserslistrc
│ ├── .eslintrc.json
│ ├── jest.config.js
│ ├── project.json
│ ├── src
│ ├── assets
│ │ ├── .gitkeep
│ │ └── icons
│ │ │ ├── icon-72x72.png
│ │ │ ├── twitter-logo.png
│ │ │ └── twitter.jpg
│ ├── environments
│ │ ├── environment.prod.ts
│ │ └── environment.ts
│ ├── favicon.ico
│ ├── first-app
│ │ ├── app-routing.module.ts
│ │ ├── app.component.html
│ │ ├── app.component.scss
│ │ ├── app.component.spec.ts
│ │ ├── app.component.ts
│ │ ├── app.module.ts
│ │ ├── home
│ │ │ ├── home.component.html
│ │ │ ├── home.component.scss
│ │ │ ├── home.component.spec.ts
│ │ │ └── home.component.ts
│ │ └── use-case
│ │ │ ├── use-case.component.html
│ │ │ ├── use-case.component.scss
│ │ │ ├── use-case.component.spec.ts
│ │ │ └── use-case.component.ts
│ ├── index.html
│ ├── main.ts
│ ├── polyfills.ts
│ ├── second-app
│ │ ├── app-routing.module.ts
│ │ ├── app.component.html
│ │ ├── app.component.scss
│ │ ├── app.component.spec.ts
│ │ ├── app.component.ts
│ │ ├── app.module.ts
│ │ ├── home
│ │ │ ├── home.component.html
│ │ │ ├── home.component.scss
│ │ │ ├── home.component.spec.ts
│ │ │ └── home.component.ts
│ │ └── use-case
│ │ │ ├── use-case.component.html
│ │ │ ├── use-case.component.scss
│ │ │ ├── use-case.component.spec.ts
│ │ │ └── use-case.component.ts
│ ├── styles.scss
│ └── test-setup.ts
│ ├── tsconfig.app.json
│ ├── tsconfig.editor.json
│ ├── tsconfig.json
│ └── tsconfig.spec.json
├── babel.config.json
├── decorate-angular-cli.js
├── jest.config.js
├── jest.preset.js
├── libs
├── .gitkeep
└── microapp
│ ├── .browserslistrc
│ ├── .eslintrc.json
│ ├── jest.config.js
│ ├── ng-package.json
│ ├── package.json
│ ├── project.json
│ ├── src
│ ├── index.ts
│ ├── lib
│ │ ├── headless
│ │ │ └── index.ts
│ │ ├── loader
│ │ │ └── index.ts
│ │ ├── messaging
│ │ │ ├── event-messaging.ts
│ │ │ └── index.ts
│ │ ├── routing
│ │ │ ├── angular
│ │ │ │ ├── index.ts
│ │ │ │ ├── micro-app-location-strategy.ts
│ │ │ │ ├── micro-app-name.token.ts
│ │ │ │ ├── micro-app-routing-state.ts
│ │ │ │ ├── micro-app-routing.module.ts
│ │ │ │ └── micro-app-url-handling-strategy.ts
│ │ │ ├── index.ts
│ │ │ └── javascript.ts
│ │ └── state
│ │ │ └── index.ts
│ └── test-setup.ts
│ ├── tsconfig.json
│ ├── tsconfig.lib.json
│ ├── tsconfig.lib.prod.json
│ └── tsconfig.spec.json
├── nx.json
├── package-lock.json
├── package.json
├── tools
├── generators
│ └── .gitkeep
└── tsconfig.tools.json
└── tsconfig.base.json
/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.md]
12 | max_line_length = off
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "ignorePatterns": ["**/*"],
4 | "plugins": ["@nrwl/nx"],
5 | "overrides": [
6 | {
7 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
8 | "rules": {
9 | "@nrwl/nx/enforce-module-boundaries": [
10 | "error",
11 | {
12 | "enforceBuildableLibDependency": true,
13 | "allow": [],
14 | "depConstraints": [
15 | {
16 | "sourceTag": "*",
17 | "onlyDependOnLibsWithTags": ["*"]
18 | }
19 | ]
20 | }
21 | ]
22 | }
23 | },
24 | {
25 | "files": ["*.ts", "*.tsx"],
26 | "extends": ["plugin:@nrwl/nx/typescript"],
27 | "rules": {}
28 | },
29 | {
30 | "files": ["*.js", "*.jsx"],
31 | "extends": ["plugin:@nrwl/nx/javascript"],
32 | "rules": {}
33 | }
34 | ]
35 | }
36 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist
5 | /tmp
6 | /out-tsc
7 |
8 | # dependencies
9 | /node_modules
10 |
11 | # IDEs and editors
12 | /.idea
13 | .project
14 | .classpath
15 | .c9/
16 | *.launch
17 | .settings/
18 | *.sublime-workspace
19 |
20 | # IDE - VSCode
21 | .vscode/*
22 | !.vscode/settings.json
23 | !.vscode/tasks.json
24 | !.vscode/launch.json
25 | !.vscode/extensions.json
26 |
27 | # misc
28 | /.sass-cache
29 | /connect.lock
30 | /coverage
31 | /libpeerconnection.log
32 | npm-debug.log
33 | yarn-error.log
34 | testem.log
35 | /typings
36 |
37 | # System Files
38 | .DS_Store
39 | Thumbs.db
40 |
41 | .angular
42 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | # Add files here to ignore them from prettier formatting
2 |
3 | /dist
4 | /coverage
5 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true
3 | }
4 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "angular.ng-template",
4 | "nrwl.angular-console",
5 | "esbenp.prettier-vscode",
6 | "firsttris.vscode-jest-runner",
7 | "dbaeumer.vscode-eslint"
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "workbench.colorCustomizations": {
3 | "activityBar.activeBackground": "#2f7c47",
4 | "activityBar.activeBorder": "#422c74",
5 | "activityBar.background": "#2f7c47",
6 | "activityBar.foreground": "#e7e7e7",
7 | "activityBar.inactiveForeground": "#e7e7e799",
8 | "activityBarBadge.background": "#422c74",
9 | "activityBarBadge.foreground": "#e7e7e7",
10 | "sash.hoverBorder": "#2f7c47",
11 | "statusBar.background": "#215732",
12 | "statusBar.foreground": "#e7e7e7",
13 | "statusBarItem.hoverBackground": "#2f7c47",
14 | "statusBarItem.remoteBackground": "#215732",
15 | "statusBarItem.remoteForeground": "#e7e7e7",
16 | "titleBar.activeBackground": "#215732",
17 | "titleBar.activeForeground": "#e7e7e7",
18 | "titleBar.inactiveBackground": "#21573299",
19 | "titleBar.inactiveForeground": "#e7e7e799",
20 | "commandCenter.border": "#e7e7e799"
21 | },
22 | "peacock.color": "#215732"
23 | }
24 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2021-2022 intauria GmbH
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
13 | all 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
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # @angular-architects/microapp
2 |
3 | This library support Micro App frontend development.
4 |
5 | - [@angular-architects/microapp](#angular-architectsmicroapp)
6 | - [Supported features](#supported-features)
7 | - [Roadmap](#roadmap)
8 | - [Setup](#setup)
9 | - [Install `node_module`](#install-node_module)
10 | - [Shell](#shell)
11 | - [Micro App](#micro-app)
12 | - [Routing](#routing)
13 | - [Deeplinking from Shell to Micro App](#deeplinking-from-shell-to-micro-app)
14 | - [Experimental string-based Deeplinking from Shell to Micro App](#experimental-string-based-deeplinking-from-shell-to-micro-app)
15 |
16 | ## Supported features
17 |
18 | - Multi Router support in the same window object
19 | - Support for Angular 13+
20 | - Messaging API based on CustomEvents
21 | - influenced by RxJS and NgRx Action Creators
22 | - Deep Linking across different Micro Apps
23 |
24 | ## Roadmap
25 |
26 | - Named router outlets w/i an Angular app
27 | - Support for different versions and environment configs
28 | - Headless shell infrastructure
29 | - Cross tech support
30 | - React, Vue, AngularJS
31 | - Distributed State Management
32 |
33 | ## Setup
34 |
35 | ### Install `node_module`
36 |
37 | ```
38 | npm install @angular-architects/microapp
39 | ```
40 |
41 | ### Shell
42 | ```typescript
43 | @NgModule({
44 | declarations: [AppComponent],
45 | imports: [
46 | BrowserModule,
47 | MicroAppRoutingModule.forShell({ name: 'shell' }),
48 | AppRoutingModule
49 | ],
50 | bootstrap: [AppComponent],
51 | })
52 | export class AppModule {}
53 | ```
54 |
55 | ### Micro App
56 | ```typescript
57 | @NgModule({
58 | declarations: [AppComponent],
59 | imports: [
60 | BrowserModule,
61 | MicroAppRoutingModule.forMicroApp({ name: 'microapp' }),
62 | AppRoutingModule
63 | ],
64 | bootstrap: [AppComponent],
65 | })
66 | export class AppModule {}
67 | ```
68 |
69 | ### Routing
70 |
71 | Use normal Angular `route` definitions and the `routerLink` Directive.
72 |
73 | #### Deeplinking from Shell to Micro App
74 | ```html
75 | Deeplink from Shell to Micro App -> mypath
76 | ```
77 |
78 | #### Experimental string-based Deeplinking from Shell to Micro App
79 | ```html
80 | Deeplink string from Shell to Micro App -> mypath
81 | ```
82 |
--------------------------------------------------------------------------------
/angular.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 2,
3 | "projects": {
4 | "microapp": "libs/microapp",
5 | "react-mfe": "apps/react-mfe",
6 | "react-mfe-e2e": "apps/react-mfe-e2e",
7 | "shell": "apps/shell",
8 | "shell-e2e": "apps/shell-e2e"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/apps/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/intauria/microapp/78d2edb5a39dbef96345d232c16a1ef0a3e1e9fd/apps/.gitkeep
--------------------------------------------------------------------------------
/apps/react-mfe-e2e/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["plugin:cypress/recommended", "../../.eslintrc.json"],
3 | "ignorePatterns": ["!**/*"],
4 | "overrides": [
5 | {
6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
7 | "rules": {}
8 | }
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/apps/react-mfe-e2e/cypress.json:
--------------------------------------------------------------------------------
1 | {
2 | "fileServerFolder": ".",
3 | "fixturesFolder": "./src/fixtures",
4 | "integrationFolder": "./src/integration",
5 | "modifyObstructiveCode": false,
6 | "supportFile": "./src/support/index.ts",
7 | "pluginsFile": false,
8 | "video": true,
9 | "videosFolder": "../../dist/cypress/apps/react-mfe-e2e/videos",
10 | "screenshotsFolder": "../../dist/cypress/apps/react-mfe-e2e/screenshots",
11 | "chromeWebSecurity": false
12 | }
13 |
--------------------------------------------------------------------------------
/apps/react-mfe-e2e/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "root": "apps/react-mfe-e2e",
3 | "sourceRoot": "apps/react-mfe-e2e/src",
4 | "projectType": "application",
5 | "targets": {
6 | "e2e": {
7 | "executor": "@nrwl/cypress:cypress",
8 | "options": {
9 | "cypressConfig": "apps/react-mfe-e2e/cypress.json",
10 | "devServerTarget": "react-mfe:serve:development"
11 | },
12 | "configurations": {
13 | "production": {
14 | "devServerTarget": "react-mfe:serve:production"
15 | }
16 | }
17 | },
18 | "lint": {
19 | "executor": "@nrwl/linter:eslint",
20 | "outputs": ["{options.outputFile}"],
21 | "options": {
22 | "lintFilePatterns": ["apps/react-mfe-e2e/**/*.{js,ts}"]
23 | }
24 | }
25 | },
26 | "tags": [],
27 | "implicitDependencies": ["react-mfe"]
28 | }
29 |
--------------------------------------------------------------------------------
/apps/react-mfe-e2e/src/fixtures/example.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Using fixtures to represent data",
3 | "email": "hello@cypress.io"
4 | }
5 |
--------------------------------------------------------------------------------
/apps/react-mfe-e2e/src/integration/app.spec.ts:
--------------------------------------------------------------------------------
1 | import { getGreeting } from '../support/app.po';
2 |
3 | describe('react-mfe', () => {
4 | beforeEach(() => cy.visit('/'));
5 |
6 | it('should display welcome message', () => {
7 | // Custom command example, see `../support/commands.ts` file
8 | cy.login('my-email@something.com', 'myPassword');
9 |
10 | // Function helper example, see `../support/app.po.ts` file
11 | getGreeting().contains('Welcome react-mfe');
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/apps/react-mfe-e2e/src/support/app.po.ts:
--------------------------------------------------------------------------------
1 | export const getGreeting = () => cy.get('h1');
2 |
--------------------------------------------------------------------------------
/apps/react-mfe-e2e/src/support/commands.ts:
--------------------------------------------------------------------------------
1 | // ***********************************************
2 | // This example commands.js shows you how to
3 | // create various custom commands and overwrite
4 | // existing commands.
5 | //
6 | // For more comprehensive examples of custom
7 | // commands please read more here:
8 | // https://on.cypress.io/custom-commands
9 | // ***********************************************
10 |
11 | // eslint-disable-next-line @typescript-eslint/no-namespace
12 | declare namespace Cypress {
13 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
14 | interface Chainable {
15 | login(email: string, password: string): void;
16 | }
17 | }
18 | //
19 | // -- This is a parent command --
20 | Cypress.Commands.add('login', (email, password) => {
21 | console.log('Custom command example: Login', email, password);
22 | });
23 | //
24 | // -- This is a child command --
25 | // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
26 | //
27 | //
28 | // -- This is a dual command --
29 | // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
30 | //
31 | //
32 | // -- This will overwrite an existing command --
33 | // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
34 |
--------------------------------------------------------------------------------
/apps/react-mfe-e2e/src/support/index.ts:
--------------------------------------------------------------------------------
1 | // ***********************************************************
2 | // This example support/index.js is processed and
3 | // loaded automatically before your test files.
4 | //
5 | // This is a great place to put global configuration and
6 | // behavior that modifies Cypress.
7 | //
8 | // You can change the location of this file or turn off
9 | // automatically serving support files with the
10 | // 'supportFile' configuration option.
11 | //
12 | // You can read more here:
13 | // https://on.cypress.io/configuration
14 | // ***********************************************************
15 |
16 | // Import commands.js using ES2015 syntax:
17 | import './commands';
18 |
--------------------------------------------------------------------------------
/apps/react-mfe-e2e/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "compilerOptions": {
4 | "sourceMap": false,
5 | "outDir": "../../dist/out-tsc",
6 | "allowJs": true,
7 | "types": ["cypress", "node"]
8 | },
9 | "include": ["src/**/*.ts", "src/**/*.js"]
10 | }
11 |
--------------------------------------------------------------------------------
/apps/react-mfe/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "@nrwl/react/babel",
5 | {
6 | "runtime": "automatic"
7 | }
8 | ]
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/apps/react-mfe/.browserslistrc:
--------------------------------------------------------------------------------
1 | # This file is used by:
2 | # 1. autoprefixer to adjust CSS to support the below specified browsers
3 | # 2. babel preset-env to adjust included polyfills
4 | #
5 | # For additional information regarding the format and rule options, please see:
6 | # https://github.com/browserslist/browserslist#queries
7 | #
8 | # If you need to support different browsers in production, you may tweak the list below.
9 |
10 | last 1 Chrome version
11 | last 1 Firefox version
12 | last 2 Edge major versions
13 | last 2 Safari major version
14 | last 2 iOS major versions
15 | Firefox ESR
16 | not IE 9-11 # For IE 9-11 support, remove 'not'.
--------------------------------------------------------------------------------
/apps/react-mfe/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["plugin:@nrwl/nx/react", "../../.eslintrc.json"],
3 | "ignorePatterns": ["!**/*"],
4 | "overrides": [
5 | {
6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
7 | "rules": {}
8 | },
9 | {
10 | "files": ["*.ts", "*.tsx"],
11 | "rules": {}
12 | },
13 | {
14 | "files": ["*.js", "*.jsx"],
15 | "rules": {}
16 | }
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/apps/react-mfe/jest.config.ts:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | displayName: 'react-mfe',
3 | preset: '../../jest.preset.js',
4 | transform: {
5 | '^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nrwl/react/plugins/jest',
6 | '^.+\\.[tj]sx?$': 'babel-jest',
7 | },
8 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
9 | coverageDirectory: '../../coverage/apps/react-mfe',
10 | };
11 |
--------------------------------------------------------------------------------
/apps/react-mfe/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "root": "apps/react-mfe",
3 | "sourceRoot": "apps/react-mfe/src",
4 | "projectType": "application",
5 | "targets": {
6 | "build": {
7 | "executor": "@nrwl/web:webpack",
8 | "outputs": ["{options.outputPath}"],
9 | "defaultConfiguration": "production",
10 | "options": {
11 | "compiler": "babel",
12 | "outputPath": "dist/apps/react-mfe",
13 | "index": "apps/react-mfe/src/index.html",
14 | "baseHref": "/",
15 | "main": "apps/react-mfe/src/main.tsx",
16 | "polyfills": "apps/react-mfe/src/polyfills.ts",
17 | "tsConfig": "apps/react-mfe/tsconfig.app.json",
18 | "assets": [
19 | "apps/react-mfe/src/favicon.ico",
20 | "apps/react-mfe/src/assets"
21 | ],
22 | "styles": ["apps/react-mfe/src/styles.scss"],
23 | "scripts": [],
24 | "webpackConfig": "@nrwl/react/plugins/webpack"
25 | },
26 | "configurations": {
27 | "development": {
28 | "extractLicenses": false,
29 | "optimization": false,
30 | "sourceMap": true,
31 | "vendorChunk": true
32 | },
33 | "production": {
34 | "fileReplacements": [
35 | {
36 | "replace": "apps/react-mfe/src/environments/environment.ts",
37 | "with": "apps/react-mfe/src/environments/environment.prod.ts"
38 | }
39 | ],
40 | "optimization": true,
41 | "outputHashing": "all",
42 | "sourceMap": false,
43 | "namedChunks": false,
44 | "extractLicenses": true,
45 | "vendorChunk": false
46 | }
47 | }
48 | },
49 | "serve": {
50 | "executor": "@nrwl/web:dev-server",
51 | "defaultConfiguration": "development",
52 | "options": {
53 | "buildTarget": "react-mfe:build",
54 | "hmr": true,
55 | "port": 4000
56 | },
57 | "configurations": {
58 | "development": {
59 | "buildTarget": "react-mfe:build:development"
60 | },
61 | "production": {
62 | "buildTarget": "react-mfe:build:production",
63 | "hmr": false
64 | }
65 | }
66 | },
67 | "lint": {
68 | "executor": "@nrwl/linter:eslint",
69 | "outputs": ["{options.outputFile}"],
70 | "options": {
71 | "lintFilePatterns": ["apps/react-mfe/**/*.{ts,tsx,js,jsx}"]
72 | }
73 | },
74 | "test": {
75 | "executor": "@nrwl/jest:jest",
76 | "outputs": ["coverage/apps/react-mfe"],
77 | "options": {
78 | "jestConfig": "apps/react-mfe/jest.config.ts",
79 | "passWithNoTests": true
80 | }
81 | }
82 | },
83 | "tags": []
84 | }
85 |
--------------------------------------------------------------------------------
/apps/react-mfe/src/app/app.module.scss:
--------------------------------------------------------------------------------
1 | /* Your styles goes here. */
2 |
--------------------------------------------------------------------------------
/apps/react-mfe/src/app/app.spec.tsx:
--------------------------------------------------------------------------------
1 | import { render } from '@testing-library/react';
2 |
3 | import { BrowserRouter } from 'react-router-dom';
4 |
5 | import App from './app';
6 |
7 | describe('App', () => {
8 | it('should render successfully', () => {
9 | const { baseElement } = render(
10 |
11 |
12 |
13 | );
14 |
15 | expect(baseElement).toBeTruthy();
16 | });
17 |
18 | it('should have a greeting as the title', () => {
19 | const { getByText } = render(
20 |
21 |
22 |
23 | );
24 |
25 | expect(getByText(/Welcome react-mfe/gi)).toBeTruthy();
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/apps/react-mfe/src/app/app.tsx:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
2 | import { Link, Route, Routes } from 'react-router-dom';
3 |
4 |
5 | export function App() {
6 | /* const navigate = useNavigate();
7 | const location = useLocation();
8 |
9 | //useEffect(() => {
10 | function nav(data: any, unused: string, url?: string | URL | null | undefined) {
11 | console.log(url, location);
12 | if (url !== location.pathname) {
13 | originalPushStateFn(data, unused, url);
14 | }
15 | }
16 | patchPushState(nav as any, { overwrite: true });
17 | patchReplaceState(replaceEventReplaceStateFn, { overwrite: true });
18 | //}); */
19 |
20 | return (
21 | <>
22 |
23 | React App (Micro App)
24 |
25 | {/* START: routes */}
26 | {/* These routes and navigation have been generated for you */}
27 | {/* Feel free to move and update them to fit your needs */}
28 | {/*
29 |
30 | */}
31 |
32 |
33 |
34 | Home
35 |
36 |
37 | Use Case 3
38 |
39 |
40 | Use Case 3, App-1 Use-Case-1
41 |
42 |
43 |
44 |
45 | home 3 works!
49 | }
50 | />
51 | use-case 3 works!
55 | }
56 | />
57 |
58 | {/* END: routes */}
59 | >
60 | );
61 | }
62 |
63 | export default App;
64 |
--------------------------------------------------------------------------------
/apps/react-mfe/src/app/nx-welcome.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * * * * * * * * * * * * * * * * * * * * * * * * * * * *
3 | This is a starter component and can be deleted.
4 | * * * * * * * * * * * * * * * * * * * * * * * * * * * *
5 | Delete this file and get started with your project!
6 | * * * * * * * * * * * * * * * * * * * * * * * * * * * *
7 | */
8 | export function NxWelcome({ title }: { title: string }) {
9 | return (
10 | <>
11 |