Module Development with the Angular template¶
The whole template is basically just a regular Angular base application with Webpack Module Federation and an injectable service that is wrapper for HortiView's Module API. ng serve
behaves as it normally does - runs the application that can be openend in a browser, but ng build
doesn't behave like in a basic Angular application. The default Angular configuration in angular.json
for building was renamed to build_standalone
, and build
now serves the purpose of building a federated module that cannot run on its own, but is meant to be run in a Webpack Module Federation host app (HortiView in this case).
Local development¶
All you have to do to develop locally is to install npm packages and run ng serve
. To make the local development easier, it's recommended to run the project in a browser with CORS policies turned off. Nothing else is required to run the project locally.
ng serve vs ng build
Running ng serve
runs the Angular application in a regular way, just as any Angular application would be run. However, ng build
has been modified (in angular.json
) so that it wraps the whole application into Webpack Module Federation. This is required to run the module in HortiView.
Setup for deployment¶
A good approach would be to first register a module in HortiView before setting up the following.
The template is almost good to go, but you have to change a couple of things first in webpack.config.js
module.exports = {
output: {
uniqueName: "yourScopeName", // 1
///...
},
///...
plugins: [
new ModuleFederationPlugin({
name: "yourScopeName", // 1
filename: "remoteEntry.js", // 3
library: {type: 'window', name: 'yourScopeName'}, // 1
exposes: {
'./YourComponentName': './src/loadApp.ts', // 2
},
///...
}),
///...
],
};
1) Change module.exports.output.uniqueName
, module.exports.plugins.ModuleFederationPlugin.name
and module.exports.plugins.ModuleFederationPlugin.library.name
to what you have provided during the module registration in HortiView in the Remote Module Name (Scope) field, 2) Change module.exports.plugins.ModuleFederationPlugin.exposes
property name to what you have provided during the module registration in HortiView in the Expose Component Name field, 3) You can change the name of the entry file which you will later on have to choose in the vendor page, but it can stay as it is.
Environments & building for deployment¶
There are currently 3 supported environments:
- tes (test)
- dem (demo)
- prod (prod)
You can find environment files for each of them in src/environments
. For local development you have to create the environment.local.ts
. I recommend copy-pasting the environment file for tes and adding there the moduleId (from tes environment) and HortiView credentials.
export const environment = {
COMMONDATA_API: 'https://app-hv-c-commondata-tes-weu-001.azurewebsites.net',
MODULE_API: 'https://app-hv-c-moduleapi-tes-weu-001.azurewebsites.net',
moduleId: '00000000-your-modu-leee-guid00000000', // your moduleId from the tes environment
hvCreds: {
username: 'john.doe@company.com', // your farmer account email
password: 'abc!@#', // your farmer account password
organizationId: 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee', // the id of the organization you want to have active during the runtime
}
}
In package.json
you can find a build script for each environment:
build:tes
build:dem
build:prod
Routing¶
Routing is set up in src/app/app.routes.ts
using the standard Angular router library.
export const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'first', component: FirstComponent },
{ path: 'second', component: SecondComponent },
];
Because of the HortiView overhead the way that routing works is that during the mounting of the module, there is a base
HTML Element created with the href
attribute set to the current website URL. The base URL when you open a module will be something like this:
https://app.hortiview.com/farm/modules/00000000-your-modu-leee-guid00000000/
that part won't interest you. The routing set up above takes into consideration only stuff put after that URL, so e.g.
https://app.hortiview.com/farm/modules/00000000-your-modu-leee-guid00000000/second
will move to the SecondComponent
.
Other than that, the routing is done in the regular Angular name.
Module API - HortiViewDataService¶
At src/app/hortiview-data.service.ts
there is the HortiViewDataService
service which wraps the logic required to get data from the Module API. You can use the getEntity
method to get data from the API by just putting the data area key as a parameter. Currently supported are:
fields
zones
farm_members
farm_organizations
farms
but it will work for all the keys that you can get from https://app-hv-c-commondata-{{env}}-weu-001.azurewebsites.net/api/v1/dataAreaEntity/dropdown
, there are just no models for that in the template.
There are also methods that will return Module API data after modifying it a bit e.g. getFarms
or getFieldsAndBlocks
. You don't have to use them or you can write your own methods, up to you.
The service has a simple caching mechanism, so if you e.g. run getFarms
method multiple times, you will get the same results from the cache.
Read More
For more on that topic please refer to this part of the React module template documentation ( the useEntity
hook is just a wrapper for Module API calls) and more importantly the API section of the docs