/mfe-angular-elements

Example of Angular Elements as a Micro Front End solution.

Primary LanguageTypeScript

MfeAngularElementsEducative

  • Generate workspace
    • npx --ignore-existing create-nx-workspace mfe-angular-elements-educative --preset=empty
  • Canceled - Install web plugin
    • npm install --save-dev @nrwl/web
  • Canceled - Generate container app
    • npx nx generate @nrwl/web:app container --e2eTestRunner=none --no-interactive
  • Remove web app container to change for VueJS
    • npx nx generate remove container
  • Canceled - Install VueJS plugin
    • npm install @nx-plus/vue --save-dev --force
    • Had to force because VueJS plugin doesn't support Nx 13 yet, only version 12
  • Canceled - Generate VueJS container app
    • npx nx generate @nx-plus/vue:app container
    • Didn't work because VueJS plugin doesn't support Nx 13 yet
    • Will change to React
  • Install React plugin
    • npm install --save-dev @nrwl/react
  • Generate React container app
    • npx nx generate @nrwl/react:app container --e2eTestRunner=none --unitTestRunner=none --no-interactive
  • Run the container app to see if it's working
    • npx nx serve container
  • Changing the container app layout
  • Removing the initial component
    • rm -rf apps/container/src/app/nx-welcome.tsx
    • Also need to remove its references on AppComponent
  • Canceled - Installing Tailwind on container app
    • Installing Tailwind dependencies
    • npm install tailwindcss@latest postcss@latest autoprefixer@latest
    • Initializing on container app
    • cd apps/container
    • npx tailwindcss init -p
    • The config files for tailwind and postcss had to be changed
    • Tailwind base styles needs to be imported on styles.css
  • Configuring Pico CSS
    • npm install @picocss/pico
    • Changing root element to body
      • Don't do this in production
  • Creating header component
    • nx generate @nrwl/react:component --name=header --project=container --style=none --skipTests --flat --no-interactive
  • Creating home component
    • nx generate @nrwl/react:component --name=home --project=container --style=none --skipTests --flat --no-interactive
  • Creating profile component
    • nx generate @nrwl/react:component --name=profile --project=container --style=none --skipTests --flat --no-interactive
  • Adding routing
    • npm install react-router-dom@6
    • Reflected the current item on navbar using React Router hooks
  • Creating a Custom Element without Angular
    • Adding a web project to workspace
    • npm install -D @nrwl/web
    • nx generate @nrwl/web:app mfe-web --e2eTestRunner=none --unitTestRunner=none --port=4201 --no-interactive
    • Also changed the AppElement file
    • Had to change the port that this project is going to be served during development
    • Changed it on project.json file, port property
  • Embedding the Custom Element on container app
    • Creating a mfe-container component
      • nx generate @nrwl/react:component --name=mfe-container --project=container --style=none --skipTests --flat --no-interactive
    • Loading Custom Element
      • Had to customize the webpack config
        • file: apps/mfe-web/webpack/web.config.js
        • It had to be done because webpackChunk conflicts on different bundles
        • Property output.uniqueName on webpack config determines webpackChunk name
      • Getting an error when going out of Contacts page and returning to it
        • CustomElementRegistry.define: 'mfe-web' has already been defined as a custom element
        • MfeContainer loader needs to verify if an element is already loaded
  • Adding an Angular app to the workspace
    • Install Angular plugin npm install --save-dev @nrwl/angular
    • Create Angular App nx generate @nrwl/angular:app contacts --prefix=contacts --routing --e2eTestRunner=none --unitTestRunner=none --port=4201 --no-interactive
    • Run the app to see if its okay
  • Move contacts Page to Angular App
    • Run the app to see it on port 4201
  • Remove mfe-web
    • nx generate remove mfe-web
  • Converting the Angular app to Angular Element
  • Loading Angular Element on Container app
    • In Angular doesn't need to customize Webpack config, the chunk are already named correctly
  • Structuring the Angular Element project
    • Contact list
      • Trying to style the list of contacts to seems better and still don't break HTML semantics
      • Pico was turned on, but have to be turned off later
      • Routing had to be added, but I changed the schematics on app creation so this won't be needed in the future
    • Creating Contacts Service
      • nx generate @schematics/angular:service --name=contacts --project=contacts --path=apps/contacts/src/app/contacts --skipTests --no-interactive
    • Moving Contact list to a List component and route
      • nx generate @schematics/angular:component --name=list --project=contacts --style=none --flat --inlineTemplate --path=apps/contacts/src/app/contacts --skipTests --no-interactive
      • It was needed to perform an initial navigation on AppModule, since we are controlling the Angular state by hand
      • It was also necessary to navigate using skipLocationChange: true to not conflict with the container app routes
        • If not set, when the user navigates to /contacts route the URL is replaced by /
        • /contacts route is located in the container app
        • / is the route controlled by the Angular Element
    • Create the edit component
      • nx generate @schematics/angular:component --name=edit --project=contacts --style=none --flat --inlineTemplate --path=apps/contacts/src/app/contacts --skipTests --no-interactive
      • Had to add 'contacts' at the start of the routes, to match the container route
        • TODO: it needs to be removed
      • When navigating away from the Contacts section (click on navbar) and returning to it, the internal Angular Elements routing are not being updated
        • To reproduce
        • Navigate to Contacts
          • List of contacts are shown
        • Click to Edit a contact
          • A page to edit the selected contact are shown
        • Click on another item on Navbar (eg: Profile)
          • The contacts element is removed from the page
        • Navigate again to Contacts
          • The page that should be visible is the contact list
          • But the last edited contacted is displayed instead
          • Maybe a way to reflect the current route would be ok
        • TODO: don't know what to do yet
      • The initial navigation was changed to use the Router default
        • The logic using .navigate[''] had some problems
        • But it's not the final version yet
    • Next steps
      • Create the edit route pointing to this new component
      • Configure the baseHref or deployUrl to match the container routing
      • The images used on the first lessons also needs to be changed
        • Those are referencing an old version of the app