Migrate remote module functionality to the deferred format
This functionality is available for Creatio 8.3.4 and later.
Creatio provides a dedicated public API that significantly extends the capabilities of Freedom UI Designer setup areas. To support this, the remote module structure separates runtime and design-time code into independent loading features. Learn more: Working with collection attributes when implementing Freedom UI Designer setup area.
If custom functionality was implemented using a remote module for Creatio version 8.3.3 and earlier, it follows the legacy structure. Migrate it to the deferred format to take advantage of the new API, improve startup performance, and make large remotes easier to maintain. In the deferred structure, the host discovers what the remote provides without loading all runtime code up front — runtime components, setup areas, and designer metadata activate only when actually needed. Migration involves refactoring the existing Angular project to match the deferred remote structure, not recreating it from a template. For manual migration, keep the deferred remote template open for reference.
Legacy and deferred remote structures
A typical legacy remote has the following structure:
src/
main.ts
bootstrap.ts
app/
app.module.ts
components/...
handlers/...
validators/...
converters/...
A typical deferred remote has the following structure after migration:
src/
main.ts
app/
remote-app.module.ts
remote-app-context.ts
remote-entry.ids.ts
features/
runtime/
runtime-feature.ids.ts
runtime-feature.module.ts
runtime.feature-definition.ts
runtime.feature-activation.ts
runtime.designer-definitions.ts
view-elements/...
handlers/...
validators/...
converters/...
design/
design-feature.ids.ts
design-feature.module.ts
design.feature-definition.ts
design.feature-activation.ts
property-panels/...
The exact folder names can vary, but the important change is the same in every case:
- In the legacy remote, one eager entry path bootstraps everything
- In the deferred remote, the entry publishes definitions, and runtime and design code activate lazily through separate features
- Runtime components, validators, converters, and handlers usually are placed under the "features/runtime" directory
- Setup areas and other design-only elements usually are placed under the "features/design" directory
If you migrate manually, keep the deferred remote template open while working and compare the current project against this structure.
Before starting the migration, make sure the current remote module still follows the legacy remote module structure:
- "src/main.ts" file imports "./bootstrap" file.
- "bootstrap.ts" file bootstraps an Angular module.
- The "app.module.ts" file eagerly registers runtime artifacts through the
bootstrapCrtModule()method. - Runtime components use the
@CrtInterfaceDesignerItem()or@CrtMobileInterfaceDesignerItem()decorator.
To migrate remote module functionality to the deferred format, complete the following steps.
General procedure
1. Inventory the remote module
-
Inspect the entry, "bootstrap.ts," and "app.module.ts" files. Make sure to inspect files beyond "app.module.ts." Remote modules often spread behavior across nested
CrtModuleinstances and imported Angular modules. -
Record the following:
- the remote module name and webpack expose settings
- all public runtime view elements, including mobile view elements if any
- validators, converters, and request handlers
- all custom setup areas
- all usages of the
@CrtInterfaceDesignerItem()and@CrtMobileInterfaceDesignerItem()decorators - any
CrtModule.includesproperty - Angular modules imported by "app.module.ts"
- app-wide initialization and
APP_INITIALIZERlogic - translation files and translation bootstrap
2. Replace the entry and webpack contract
-
Open the "src/main.ts" file.
-
Export
RemoteEntryDefinition."main.ts" fileexport { RemoteEntryDefinition } from './app/remote-entry.ids'; -
Open the "webpack.config.js" file.
-
Complete the following to match the deferred entry contract.
- Use the
withModuleFederationPlugin()method. - Expose "./Main" from "./src/main.ts."
- Emit "remoteModuleEntry.js."
- Set the correct remote module name and
output.uniqueNameproperty.
- Use the
-
Open the "angular.json" file.
-
Set the
commonChunkproperty totruefor the deferred baseline. -
Save the files.
3. Move runtime artifacts into the runtime feature
-
Open the "src/app/features/runtime/runtime-feature.module.ts" file.
-
Import declarations, imports, and
@CrtModule(). -
Open the "src/app/features/runtime/runtime.feature-definition.ts" file.
-
Import discovery metadata only. Keep the file lightweight — do not import runtime modules, icons, SVG strings, or other heavy assets there.
-
Open the "src/app/features/runtime/runtime.feature-activation.ts" file.
-
Import custom-element registration and
bootstrapCrtModule(). -
Make sure the following is moved into the "src/app/features/runtime/" directory:
- public runtime components
- mobile components
- validators, converters, and request handlers
- Angular imports they depend on
-
Save the files.
4. Move designer metadata out of runtime components
- Open the runtime component files.
- Remove
@CrtInterfaceDesignerItem()and@CrtMobileInterfaceDesignerItem()from all runtime components. - Keep
@CrtViewElement(),@CrtMobileViewElement(), and normal inputs and outputs on the components. - Open the "src/app/features/runtime/runtime.designer-definitions.ts" file.
- Move
caption, icon, default values, andpropertiesPanelproperty references into the file. Runtime components describe runtime behavior, while toolbox metadata belongs in the designer-definition loading path. - Save the files.
5. Move setup areas into the design feature
If the Freedom UI component has a custom setup area implemented using a remote module, complete the following steps:
- Move setup areas out of the "src/app/features/runtime/" directory and into the "src/app/features/design/" directory that includes the "design-feature.module.ts," "design.feature-activation.ts," and "design.feature-definition.ts" files.
- Reference each setup area by type using the
propertiesPanelproperty in the "runtime.designer-definitions.ts" file. The design feature is responsible for discovering and activating the setup area component itself.
6. Split lightweight IDs from heavy data
If the remote module has a shared "constants.ts" file, complete the following steps:
-
Open the "constants.ts" file.
-
Split the file into:
- lightweight IDs and type names in the "src/app/features/runtime/runtime-feature.ids.ts" and "src/app/features/design/design-feature.ids.ts" files
- activation-only constants in the "src/app/features/runtime/runtime.feature-activation.ts" and "src/app/features/design/design.feature-activation.ts" files
- designer-only icons and defaults in the "src/app/features/runtime/runtime.feature-definition.ts" and "src/app/features/design/design.feature-definition.ts" files
-
Keep the deferred entry, "src/app/features/runtime/runtime.feature-definition.ts," and "src/app/features/design/design.feature-definition.ts" files lightweight. Importing heavy icon or activation data into these files undermines the purpose of deferred loading.
7. Add localization
Skip this step if the remote module does not use the @ngx-translate external library. Otherwise, complete the following steps:
- Add a localization module.
- Open the "remote-app.module.ts" file.
- Import the localization module.
- Keep translation files under the "src/assets/i18n/" directory.
- Open the "remote-app-context.ts" file.
- Extend the file so it can switch language culture before returning designer metadata.
- Save the files.
8. Relocate app-wide initialization
-
Open the files that contain startup logic.
-
Distribute startup logic as follows:
- keep true app-wide initialization in
RemoteAppModule - keep localization initialization in the localization module
- move feature-specific setup into the feature that needs it
Do not recreate the legacy remote module structure just to preserve initialization order.
- keep true app-wide initialization in
-
Save the files.
9. Make sure the migration is successful
After migration, confirm the following:
- "src/main.ts" file exports
RemoteEntryDefinition - the remote module no longer imports "./bootstrap" file
- runtime discovery metadata is lightweight
- runtime code loads through the
activate()method - designer metadata loads through the
loadDesignerDefinitions()method - runtime components no longer use designer decorators
- setup areas are discovered through the design feature
- entry and feature-definition files do not import heavy icon or activation data
- the built remote module loads follow-up chunks correctly
Use the table below to verify the location of each legacy remote module artifact in the deferred format.
Legacy remote module artifact | Location in deferred format |
|---|---|
Legacy entry and bootstrap | "src/main.ts," "src/app/remote-app.module.ts," and "src/app/remote-app-context.ts" files |
Runtime | "src/app/features/runtime/runtime-feature.module.ts" file |
Runtime activation logic | "src/app/features/runtime/runtime.feature-activation.ts" file |
Runtime discovery metadata | "src/app/features/runtime/runtime.feature-definition.ts" file |
Designer decorators on runtime components | "src/app/features/runtime/runtime.designer-definitions.ts" file |
Setup areas | "src/app/features/design/" directory |
Setup area discovery and activation | "src/app/features/design/design.feature-definition.ts" and "src/app/features/design/design.feature-activation.ts" files |
Small IDs and type names | "src/app/features/runtime/runtime-feature.ids.ts" and "src/app/features/design/design-feature.ids.ts" files |
Heavy constants, icons, and activation-only data | Lazy files used only by activation or designer-definition code |
As a result, custom functionality implemented using a remote module will be migrated to the deferred format. The host can now discover what the remote module provides without activating all runtime code at startup. Runtime components, setup areas, and designer metadata load only when needed, reducing unnecessary startup overhead and making the remote module easier to structure and maintain.