1.0.0 ā€¢ Published 1 year ago

iot-manager v1.0.0

Weekly downloads
-
License
ISC
Repository
-
Last release
1 year ago

IoT Manager

IoT Shared Capability (Wombat) Device Manager web application.

TypeScript

Setup

  1. Create new .npmrc file in project root.

    touch .npmrc
  2. Add the following to the .npmrc file.

    registry=https://pkgs.dev.azure.com/BuiltEnvironmentEngineering/09552df7-02fe-4661-831c-bc01d67336e9/_packaging/iot-manager/npm/registry/
    always-auth=true
    auto-install-peers=true
    strict-peer-dependencies=false

    If you are using preproxy configuration here then you will also need to add the following to your .npmrc file

    proxy=http://127.0.0.1:3128
    https-proxy=http://127.0.0.1:3128
  3. Setup credentials according to these instructions. The technique is slightly different on Windows compared to Mac/Linux.

    Once the process is done, your user .npmrc file will end up looking like the following example.

    ; begin auth token
    //pkgs.dev.azure.com/BuiltEnvironmentEngineering/09552df7-02fe-4661-831c-bc01d67336e9/_packaging/iot-manager/npm/registry/:username=BuiltEnvironmentEngineering
    //pkgs.dev.azure.com/BuiltEnvironmentEngineering/09552df7-02fe-4661-831c-bc01d67336e9/_packaging/iot-manager/npm/registry/:_password=[BASE64_ENCODED_PERSONAL_ACCESS_TOKEN]
    //pkgs.dev.azure.com/BuiltEnvironmentEngineering/09552df7-02fe-4661-831c-bc01d67336e9/_packaging/iot-manager/npm/registry/:email=npm requires email to be set but doesn't use the value
    //pkgs.dev.azure.com/BuiltEnvironmentEngineering/09552df7-02fe-4661-831c-bc01d67336e9/_packaging/iot-manager/npm/:username=BuiltEnvironmentEngineering
    //pkgs.dev.azure.com/BuiltEnvironmentEngineering/09552df7-02fe-4661-831c-bc01d67336e9/_packaging/iot-manager/npm/:_password=[BASE64_ENCODED_PERSONAL_ACCESS_TOKEN]
    //pkgs.dev.azure.com/BuiltEnvironmentEngineering/09552df7-02fe-4661-831c-bc01d67336e9/_packaging/iot-manager/npm/:email=npm requires email to be set but doesn't use the value
    ; end auth token
  4. Install pnpm. Follow the installation instructions here.

  5. Install packages. Optionally connect to VPN if you can't connect to Azure without VPN.

    pnpm install

    pnpm install will install workspace dependencies such as husky and nx specified in workspace package.json as well as all project dependencies in /packages/ specified in their package.json file.

  6. Setup git hooks by running pnpm -w prepare.

    This will tell pnpm to run prepare script specified in workspace level package.json which sets up your git hooks which is used for running linters on changed files pre-commit.

  7. Setup local environment to sign-in with CAIMAN.

    Local CAIMAN sign-in only works on http://idm-local.test.com:3000. This is because a URL must be whitelisted to work with CAIMAN for CORS purposes. idm-local.test.com is the whitelisted URL for local development. See Authentication with CAIMAN for more details.

    Add 127.0.0.1 idm-local.test.com to your computer's hosts file and open the web app on http://idm-local.test.com:3000.

    # hosts file entry
    127.0.0.1 idm-local.test.com

How to run

To run container app, we need to first build and generate compiled js code of core which will be located in iot-manager/packages/core/dist after running build in core. This will be used by the other projects. Second, we also need Auth MFE and device manager MFE running so webpack-dev-server can start serving entry point file to auth MFE (localhost:8082/remoteEntry.js) and device manager MFE (localhost:8083/remoteEntry.js) which will be consumed by container during runtime.

Using pnpm and nx


Simply run pnpm -w local:all

Alternatively without pnpm and nx you can do the following


  1. Go to packages/core and npm run build
  2. Go to packages/auth and npm run local
  3. Go to packages/device-manager and npm run local
  4. Go to packages/container and npm run local
  5. Visit localhost:8083 to view and test device manager MFE in isolation
  6. Visit localhost:8082 to view and test auth MFE in isolation
  7. Visit localhost:8081 to view and test container app which also renders auth and device manager MFEs

Linters

How to setup git hooks

Run pnpm -w prepare in any directory as long as it is located in the iot-manager project/workspace. This will setup your git hooks and make sure eslint and stylelint are executed to check your js, jsx, ts, tsx, scss, and css files pre-commit.

How to run

Using pnpm and nx


Simply run

pnpm -w lint:all
pnpm -w stylelint:all

To run npm script for executing eslint in a single project anywhere in the workspace

pnpm nx lint {project-name i.e auth}
pnpm nx stylelint {project-name i.e auth}

Alternatively without pnpm and nx you can do the following


npm run lint - Run this inside each individual project folders

packages/core
packages/auth
packages/device-manager
packages/container

npm run lint:fix - Run this inside each individual project folders as above. This goes through all .js, .ts and .tsx and automatically fix issues that it finds and report those it cannot fix.

TODO:

āŽ HMR for ts/js/stylesheets (not supported by webpack yet)

Styling

Class naming standard

For tailwind custom component class names and custom classes defined in stylesheets, we use https://css-tricks.com/abem-useful-adaptation-bem/ to avoid clashing class names between MFEs.

Use the atomic prefix when creating class names for components i.e. for class names used for components in components/atoms folder, prefix it with {projectName}-a-{blockName}__elementName -modifierName

Working with clean architecture

Clean architecture overview and example

Creating Repo and Service/Usecase/Interactor classes

Tests

Setup

WIP

How to run

Using pnpm and nx


Simply run

pnpm -w test:unit:all

To run npm script for executing unit tests in a single project anywhere in the workspace

pnpm nx test:unit {project-name i.e auth}

Alternatively without pnpm and nx you can do the following


Run npm run test:unit in each individual project folder

CI/CD

Webpack prod config


webpack.prod.js contains your webpack prod deployment config. There will only be few differences in prod config vs development config.

  • No devServer as we are no longer hosting the app locally via webpack-dev-server
  • output.publicPath will be different due to the same reason above and also because we might also want to tell webpack to retrieve the MFE assets under a different base path in the same domain. For example, so you might want to set it to /auth/latest/ which will tell webpack to retrieve the MFE remoteEntry.js from ${domain}/auth/latest/remoteEntry.js instead of ${domain}/remoteEntry.js which you will be able to see in the generated index.html script tag.

Publishing to Azure Artifacts

Libraries published on the Nexus repository needs to be re-published on Azure Artifacts so that the pipeline can run. This is important as Azure can't reach Nexus at this time.

Refer to Azure Artifacts for details on re-republishing libraries.

Deployment Pipeline Flow


  1. After code has been merged to master branch, it triggers the pipeline
  2. Pipeline checks where the changes are located (which MFE folder)
  3. Depending on where the changes are located, pipeline will go into the specific MFE folder
  4. Install dependencies
  5. Build and generate compiled code using webpack, default webpack output should be in /dist folder
  6. Upload the content of /dist folder to hosting service, and make sure when uploading /dist, it is uploaded to the correct folder based on what you have set as base asset path in your webpack.prod.js output.publicPath i.e. if output.publicPath is set to /container/latest/, then upload the /dist content to that same path
  7. Invalidate CDN cache so it stops serving stale index.html / remoteEntry.js

FAQs

1. Is it safe to use unstable_HistoryRouter from react-router v6?


Yes, as mentioned in the react-router document, it is only prefixed with unstable_ because react-router does not have a mechanism to detect mis-matched history version which will be removed once they have fixed this. This can only happen when we add and install history dependency ourselves. By default when installing react-router, it also installs history in our node_modules, as long as we are aware of this and don't add history library in our package.json we should be fine.

2. How auth state is stored and shared across all MFEs


Auth state and logic

  • Container app manages auth state
  • Store auth state in either local (persisted after closing browser or tab) or session storage (disappears after closing tab or browser) after successful login
  • When first time application is loaded, check local / session storage to see if user is authenticated i.e. valid jwt token exists
  • If jwt token exists, container app needs to update its local react state for tracking auth state let's call it isLoggedIn and set this to true.
  • Container then simple passes isLoggedIn to other MFEs
  • Whenever user logs in via the auth MFE, it will need to notify container app. This can be done by passing callback fn from container app to auth MFE for auth MFE to call after successfully logging user in, this callback fn will simply change auth state in container app when called.