diff --git a/.vscode/settings.json b/.vscode/settings.json index d5c4eb36..52cbf377 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,19 +1,27 @@ { "workbench.colorCustomizations": { - "activityBar.activeBackground": "#bfc3d8", - "activityBar.activeBorder": "#ab747d", - "activityBar.background": "#bfc3d8", + "activityBar.activeBackground": "#cbf1ee", + "activityBar.activeBorder": "#d681dd", + "activityBar.background": "#cbf1ee", "activityBar.foreground": "#15202b", "activityBar.inactiveForeground": "#15202b99", - "activityBarBadge.background": "#ab747d", + "activityBarBadge.background": "#d681dd", "activityBarBadge.foreground": "#15202b", - "statusBar.background": "#9fa6c5", + "statusBar.background": "#a2e7e1", "statusBar.foreground": "#15202b", - "statusBarItem.hoverBackground": "#7f89b2", - "titleBar.activeBackground": "#9fa6c5", + "statusBarItem.hoverBackground": "#79ddd4", + "titleBar.activeBackground": "#a2e7e1", "titleBar.activeForeground": "#15202b", - "titleBar.inactiveBackground": "#9fa6c599", + "titleBar.inactiveBackground": "#a2e7e199", "titleBar.inactiveForeground": "#15202b99" }, - "peacock.color": "#9fa6c5" + "peacock.color": "#a2e7e1", + "spellright.language": [ + "en" + ], + "spellright.documentTypes": [ + "markdown", + "latex", + "plaintext" + ] } \ No newline at end of file diff --git a/packages/mf/README.md b/packages/mf/README.md index f45f6e97..f1567fbd 100644 --- a/packages/mf/README.md +++ b/packages/mf/README.md @@ -13,13 +13,27 @@ Big thanks to the following people who helped to make this possible: - Angular CLI 11 (currently BETA) -## Usage +## Motivation ๐Ÿ’ฅ + +Module Federation allows to load separately compiled and deployed code (like micro frontends or plugins) into an application. This plugin makes Module Federation work together with Angular and the CLI. + +## Features ๐Ÿ”ฅ + +โœ… Generates the skeleton for a Module Federation config. + +โœ… Installs a custom builder to enable Module Federation. + +โœ… Assigning a new port to serve (``ng serve``) several projects at once. + +The module federation config is a **partial** webpack configuration. It only contains stuff to control module federation. The rest is generated by the CLI as usual. + +## Usage ๐Ÿ› ๏ธ 1. ``ng add @angular-architects/module-federation`` 2. Adjust the generated ``webpack.config.js`` file 3. Repeat this for further projects in your workspace (if needed) -## Notes for CLI 11 BETA (next.XY) +## Notes for CLI 11 BETA (next.XY) ๐Ÿง - You need to use **yarn** b/c it allows to override dependencies - Existing Projects: ``ng config -g cli.packageManager yarn`` @@ -35,10 +49,32 @@ Big thanks to the following people who helped to make this possible: - Run **yarn** to install all packages -## Example +Please note that the current CLI **beta** lacks some features when using it with webpack 5, e. g. **reloading an application in debug mode** (when using ng serve). Hence, you have to restart ng serve after a change. This is just a temporal limitation and will be solved with one of the upcoming versions. + +## Example ๐Ÿ“ฝ๏ธ + +This [example](https://github.com/manfredsteyer/module-federation-plugin-example) + loads a microfrontend into a shell: + +![Microfrontend Loaded into Shell](./tutorial/result.png) + +Please have a look into the example's **readme**. It points you to the important aspects of using Module Federation. + + +## Tutorial ๐Ÿงช + +Please find here a [tutorial](./tutorial/tutorial.md) that shows step by step how to introduce Module Federation into the above mentioned example. + +![Microfrontend Loaded into Shell](./tutorial/result.png) + +[>> Start Tutorial](./tutorial/tutorial.md) + + +## More Details on Module Federation ๐Ÿ“ฐ -See https://github.com/manfredsteyer/module-federation-plugin-example +Have a look at this [article series about Module Federation](https://www.angulararchitects.io/aktuelles/the-microfrontend-revolution-part-2-module-federation-with-angular/). -## More Details +## Angular Trainings, Workshops, and Consulting ๐Ÿ‘จโ€๐Ÿซ -Have a look at this [article series about Module Federation](https://www.angulararchitects.io/aktuelles/the-microfrontend-revolution-part-2-module-federation-with-angular/) +- [Angular Trainings and Workshops](https://www.angulararchitects.io/en/angular-workshops/) +- [Angular Consulting](https://www.angulararchitects.io/en/consulting/) diff --git a/packages/mf/package.json b/packages/mf/package.json index cf81cdc7..03d879a0 100644 --- a/packages/mf/package.json +++ b/packages/mf/package.json @@ -1,6 +1,6 @@ { "name": "@angular-architects/module-federation", - "version": "1.0.0", + "version": "1.0.1", "license": "MIT", "repository": { "type": "GitHub", diff --git a/packages/mf/tutorial/.vscode/settings.json b/packages/mf/tutorial/.vscode/settings.json new file mode 100644 index 00000000..eb56df2f --- /dev/null +++ b/packages/mf/tutorial/.vscode/settings.json @@ -0,0 +1,10 @@ +{ + "spellright.language": [ + "en" + ], + "spellright.documentTypes": [ + "markdown", + "latex", + "plaintext" + ] +} \ No newline at end of file diff --git a/packages/mf/tutorial/mfe1.png b/packages/mf/tutorial/mfe1.png new file mode 100644 index 00000000..c6a1cac5 Binary files /dev/null and b/packages/mf/tutorial/mfe1.png differ diff --git a/packages/mf/tutorial/result.png b/packages/mf/tutorial/result.png new file mode 100644 index 00000000..fa66ed59 Binary files /dev/null and b/packages/mf/tutorial/result.png differ diff --git a/packages/mf/tutorial/shell.png b/packages/mf/tutorial/shell.png new file mode 100644 index 00000000..f0993eba Binary files /dev/null and b/packages/mf/tutorial/shell.png differ diff --git a/packages/mf/tutorial/tutorial.md b/packages/mf/tutorial/tutorial.md new file mode 100644 index 00000000..2aee35c2 --- /dev/null +++ b/packages/mf/tutorial/tutorial.md @@ -0,0 +1,173 @@ +# Tutorial: Getting Started with Webpack Module Federation and Angular + +This tutorial shows how to use Webpack Module Federation together with the Angular CLI and the ``@angular-architects/module-federation`` plugin. The goal is to make a shell capable of **loading a separately compiled and deployed microfrontend**: + +![Microfrontend Loaded into Shell](./result.png) + + +## Part 1: Clone and Inspect the Starterkit + +In this part you will clone the starterkit and inspect its projects. + +1. Clone the starterkit for this tutorial: + + ``` + git clone https://github.com/manfredsteyer/module-federation-plugin-example.git --branch starter + ``` + +2. Have a look to the ``package.json``. You should find this section: + + ```json + "resolutions": { + "webpack": "5.0.0" + }, + ``` + + This section makes yarn to install webpack 5 for the CLI (and for all the other libraries depending on webpack). + +3. Move into the project directory and install the dependencies with **yarn**: + + ``` + cd module-federation-plugin-example + yarn + ``` + + You really **need to install the dependencies with yarn** because providing resolutions as shown above is a **yarn** feature. + +4. Start the shell (``ng serve shell -o``) and inspect it a bit: + 1. Click on the ``flights`` link. It leads to a dummy route. This route will later be used for loading the separately compiled microfrontend. + + Please **ignore depreaction warnings**. They are a temporal issue in the current CLI beta when using webpack 5. + + 2. Have a look to the shell's source code. + + > Please note that the current CLI **beta** lacks some features when using it with webpack 5, e. g. **reloading an application in debug mode** (when using ng serve). Hence, you have to restart ng serve after changing a source file. This is just a temporal limitation and will be solved with one of the upcoming versions. + + 3. Stop the CLI (``CTRL+C``). + +5. Do the same for the microfrontend. In this project, it's called ``mfe1`` (Microfrontend 1) You can start it with ``ng serve mfe1 -o``. + +## Part 2: Activate and Configure Module Federation + +Now, let's activate and configure module federation: + +1. Install ``@angular-architects/module-federation`` into the shell and into the micro frontend: + + ``` + ng add @angular-architects/module-federation --project shell --port 5000 + + ng add @angular-architects/module-federation --project mfe1 --port 3000 + ``` + + This activates module federation, assigns a port for ng serve, and generates the skeleton of a module federation configuration. + +2. Switch into the project ``mfe1`` and open the generated configuration file ``projects\mfe1\webpack.config.js``. It contains the module federation configuration for ``mfe1``. Adjust it as follows: + + ```javascript + const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin"); + + module.exports = { + output: { + publicPath: "http://localhost:3000/", + uniqueName: "mfe1" + }, + optimization: { + // Only needed to bypass a temporary bug + runtimeChunk: false + }, + plugins: [ + new ModuleFederationPlugin({ + + // For remotes (please adjust) + name: "mfe1", + library: { type: "var", name: "mfe1" }, + filename: "remoteEntry.js", + + exposes: { + './Module': './projects/mfe1/src/app/flights/flights.module.ts', + }, + + shared: ["@angular/core", "@angular/common", "@angular/router"] + }) + ], + }; + ``` + + This exposes the ``FlightsModule`` under the Name ``./Module.``. Hence, the shell can use this path to load it. + +3. Switch into the ``shell`` project and open the file ``projects\shell\webpack.config.js``. Adjust it as follows: + + ```javascript + const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin"); + + module.exports = { + output: { + publicPath: "http://localhost:5000/", + uniqueName: "shell" + }, + optimization: { + // Only needed to bypass a temporary bug + runtimeChunk: false + }, + plugins: [ + new ModuleFederationPlugin({ + remotes: { + 'mfe1': "mfe1@http://localhost:3000/remoteEntry.js" + }, + shared: ["@angular/core", "@angular/common", "@angular/router"] + }) + ], + }; + ``` + + This references the separately compiled and deployed ``mfe1`` project. There are some alternatives to configure its URL (see links at the end). + +4. Open the ``shell``'s router config (``projects\shell\src\app\app.routes.ts``) and add a route loading the microfrontend: + + ```javascript + { + path: 'flights', + loadChildren: () => import('mfe1/Module').then(m => m.FlightsModule) + }, + ``` + + Please note that the imported URL consists of the names defined in the configuration files above. + +5. As the Url ``mfe1/Module`` does not exist at compile time, ease the TypeScript compiler by adding the following line to the file ``projects\shell\src\decl.d.ts``: + + ```javascript + declare module 'mfe1/Module'; + ``` + +## Part 3: Try it out + +Now, let's try it out! + +1. Start the ``shell`` and ``mfe1`` side by side: + + ``` + ng serve shell -o + ng serve mfe1 -o + ``` + + **Hint:** You might use two terminals for this. + +2. After a browser window with the shell opened (``http://localhost:5000``), click on ``Flights``. This should load the microfrontend into the shell: + + ![Shell](shell.png) + +3. Also, ensure yourself that the microfrontend also runs in standalone mode at http://localhost:3000: + + ![Microfrontend](mfe1.png) + + +Congratulations! You've implemented your first Module Federation project with Angular! + +## More Details on Module Federation + +Have a look at this [article series about Module Federation](https://www.angulararchitects.io/aktuelles/the-microfrontend-revolution-part-2-module-federation-with-angular/) + +## Angular Trainings, Workshops, and Consulting + +- [Angular Trainings and Workshops](https://www.angulararchitects.io/en/angular-workshops/) +- [Angular Consulting](https://www.angulararchitects.io/en/consulting/) \ No newline at end of file