|
| 1 | +[id="assembly-third-party-plugins-installation"] |
| 2 | += Third-party plugins in {product} |
| 3 | +:context: assembly-third-party-plugins-installation |
| 4 | + |
| 5 | +In {product}, third-party dynamic plugins can be integrated seamlessly, enabling the use of external plugins alongside native ones. This flexibility allows you to enhance the platform’s functionality without modifying its core structure. To add third-party dynamic plugins, you can either export them as standalone packages or wrap them in custom wrappers, especially if you want to adjust the plugin’s dependencies or configurations for compatibility. |
| 6 | + |
| 7 | +The third-party plugins are typically packaged as dynamic plugins, which means they can be loaded at runtime, enabling you to easily manage external modules without rebuilding the entire application. The process involves creating a wrapper that exports the plugin code, ensuring that dependencies are correctly bundled or marked as shared, depending on their relationship to the {product-short} environment. |
| 8 | + |
| 9 | +To integrate a third-party plugin into {product-short}: |
| 10 | + |
| 11 | +. First, obtain the plugin's source code. |
| 12 | +. Export the plugin as a dynamic plugin package. See xref:proc-export-third-party-plugins-rhdh_{context}[]. |
| 13 | +. Package and publish the dynamic plugin. See xref:proc-package-third-party-dynamic-plugin_{context}[]. |
| 14 | +. Install the plugin in the {product-short} environment. See xref:proc-install-third-party-plugins-rhdh_{context}[]. |
| 15 | + |
| 16 | +The third-party plugins include: |
| 17 | + |
| 18 | +Backend plugins:: |
| 19 | ++ |
| 20 | +-- |
| 21 | +To ensure compatibility with the dynamic plugin support and enable their use as dynamic plugins, existing backend plugins must be compatible with, the new backend system. Additionally, these plugins must be rebuilt using a dedicated CLI command. |
| 22 | + |
| 23 | +The new backend system is created using `createBackendPlugin()` or `createBackendModule()`. You must export the new backend system as the default export from either the main package or an alpha package (if support exists in alpha). The dynamic export mechanism automatically identifies private dependencies, and adds them to the `bundleDependencies` field in the `package.json` file. This mechanism ensures that the dynamic plugin package is self-contained, with private dependencies bundled within a private `node_modules` folder. |
| 24 | + |
| 25 | +The backend plugins contains two types of dependencies, including: |
| 26 | + |
| 27 | +* *Shared dependencies* are provided by the Backstage application and listed as `peerDependencies` in `package.json` file, not bundled in the dynamic plugin package. By default, all `@backstage` packages are shared. |
| 28 | ++ |
| 29 | +You can use the `--shared-package` flag to specify shared dependencies. To treat a `@backstage` package as private, use the negation prefix (`!`). |
| 30 | + |
| 31 | +* *Embedded dependencies* are bundled into the dynamic plugin package with their dependencies hoisted to the top level. By default, packages with `-node` or `-common` suffixes are embedded. |
| 32 | ++ |
| 33 | +You can use the `--embed-package` flag to specify additional embedded packages, including those in the same monorepo that do not follow the default naming convention. |
| 34 | + |
| 35 | +The following is an example of exporting a dynamic plugin with shared and embedded packages: |
| 36 | + |
| 37 | +.Example dynamic plugin export with shared and embedded packages |
| 38 | +[source,bash] |
| 39 | +---- |
| 40 | +npx @janus-idp/cli@latest export-dynamic-plugin --shared-package '!/@backstage/plugin-notifications/'<1> --embed-package @backstage/plugin-notifications-backend <2> |
| 41 | +---- |
| 42 | + |
| 43 | +<1> `@backstage/plugin-notifications` package is treated as a private dependency and is bundled in the dynamic plugin package, despite being in the `@backstage` scope. |
| 44 | +<2> `@backstage/plugin-notifications-backend` package is marked as an embedded dependency and is bundled in the dynamic plugin package. |
| 45 | +-- |
| 46 | + |
| 47 | +Frontend plugins:: |
| 48 | ++ |
| 49 | +-- |
| 50 | +Frontend plugins can leverage Scalprum for configuration, which the CLI can generate automatically during the export process. The generated default configuration is logged when running the following command: |
| 51 | + |
| 52 | +.Example command to log the default configuration |
| 53 | +[source,bash] |
| 54 | +---- |
| 55 | +npx @janus-idp/cli@latest export-dynamic |
| 56 | +---- |
| 57 | + |
| 58 | +The following is an example of default Scalprum configuration: |
| 59 | + |
| 60 | +.Default Scalprum configuration |
| 61 | +[source,json] |
| 62 | +---- |
| 63 | +"scalprum": { |
| 64 | + "name": "<package_name>", // The Webpack container name matches the NPM package name, with "@" replaced by "." and "/" removed. |
| 65 | + "exposedModules": { |
| 66 | + "PluginRoot": "./src/index.ts" // The default module name is "PluginRoot" and doesn't need explicit specification in the app-config.yaml file. |
| 67 | + } |
| 68 | +} |
| 69 | +---- |
| 70 | + |
| 71 | +To customize Scalprum, add a `scalprum` section to the `package.json` file. For example: |
| 72 | + |
| 73 | +.Example Scalprum customization |
| 74 | +[source,json] |
| 75 | +---- |
| 76 | +"scalprum": { |
| 77 | + "name": "custom-package-name", |
| 78 | + "exposedModules": { |
| 79 | + "FooModuleName": "./src/foo.ts", |
| 80 | + "BarModuleName": "./src/bar.ts" |
| 81 | + // Define multiple modules here, with each exposed as a separate entry point in the Webpack container. |
| 82 | + } |
| 83 | +} |
| 84 | +---- |
| 85 | + |
| 86 | +Dynamic plugins might need adjustments for {product-short} needs, such as static JSX for mountpoints or dynamic routes. These changes are optional but might be incompatible with static plugins. |
| 87 | + |
| 88 | +To include static JSX, define an additional export and use it as the dynamic plugin's `importName`. For example: |
| 89 | + |
| 90 | +.Example static and dynamic plugin export |
| 91 | +[source,tsx] |
| 92 | +---- |
| 93 | +// For a static plugin |
| 94 | +export const EntityTechdocsContent = () => {...} |
| 95 | +
|
| 96 | +// For a dynamic plugin |
| 97 | +export const DynamicEntityTechdocsContent = { |
| 98 | + element: EntityTechdocsContent, |
| 99 | + staticJSXContent: ( |
| 100 | + <TechDocsAddons> |
| 101 | + <ReportIssue /> |
| 102 | + </TechDocsAddons> |
| 103 | + ), |
| 104 | +}; |
| 105 | +---- |
| 106 | +-- |
| 107 | +//Export third-party plugins |
| 108 | +include::../modules/dynamic-plugins/proc-export-third-party-plugins-rhdh.adoc[leveloffset=+2] |
| 109 | + |
| 110 | +//package and publish third-party plugins |
| 111 | +include::../modules/dynamic-plugins/proc-package-third-party-dynamic-plugin.adoc[leveloffset=+2] |
| 112 | + |
| 113 | +//install third-party plugins |
| 114 | +include::../modules/dynamic-plugins/proc-install-third-party-plugins-rhdh.adoc[leveloffset=+2] |
0 commit comments