@backstage/frontend-dynamic-feature-loader 0.1.9-next.1 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @backstage/frontend-dynamic-feature-loader
2
2
 
3
+ ## 0.1.9
4
+
5
+ ### Patch Changes
6
+
7
+ - fdbd404: Updated module federation integration to use `@module-federation/enhanced/runtime` `createInstance` API and the new `loadModuleFederationHostShared` from `@backstage/module-federation-common` for loading shared dependencies. Also added support for passing a pre-created `ModuleFederation` instance via the `moduleFederation.instance` option.
8
+ - fdbd404: Updated `@module-federation/enhanced`, `@module-federation/runtime`, and `@module-federation/sdk` dependencies from `^0.9.0` to `^0.21.6`.
9
+ - a7e0d50: Updated `react-router-dom` peer dependency to `^6.30.2` and explicitly disabled v7 future flags to suppress deprecation warnings.
10
+ - Updated dependencies
11
+ - @backstage/frontend-plugin-api@0.14.0
12
+ - @backstage/module-federation-common@0.1.0
13
+
3
14
  ## 0.1.9-next.1
4
15
 
5
16
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { FederationRuntimePlugin } from '@module-federation/enhanced/runtime';
1
+ import { ModuleFederationRuntimePlugin, ModuleFederation } from '@module-federation/enhanced/runtime';
2
2
  import { FrontendFeatureLoader } from '@backstage/frontend-plugin-api';
3
3
  import { UserOptions, ShareStrategy } from '@module-federation/runtime/types';
4
4
 
@@ -13,7 +13,8 @@ type DynamicFrontendFeaturesLoaderOptions = {
13
13
  moduleFederation: {
14
14
  shared?: UserOptions['shared'];
15
15
  shareStrategy?: ShareStrategy;
16
- plugins?: Array<FederationRuntimePlugin>;
16
+ plugins?: Array<ModuleFederationRuntimePlugin>;
17
+ instance?: ModuleFederation;
17
18
  };
18
19
  };
19
20
  /**
@@ -1,6 +1,7 @@
1
- import { init, loadRemote } from '@module-federation/enhanced/runtime';
1
+ import { createInstance } from '@module-federation/enhanced/runtime';
2
2
  import { DefaultApiClient } from './schema/openapi/generated/apis/Api.client.esm.js';
3
3
  import { createFrontendFeatureLoader } from '@backstage/frontend-plugin-api';
4
+ import { loadModuleFederationHostShared } from '@backstage/module-federation-common';
4
5
 
5
6
  function dynamicFrontendFeaturesLoader(options) {
6
7
  return createFrontendFeatureLoader({
@@ -40,15 +41,42 @@ function dynamicFrontendFeaturesLoader(options) {
40
41
  );
41
42
  return [];
42
43
  }
44
+ let instance;
43
45
  try {
44
- init({
45
- ...options?.moduleFederation,
46
- name: appPackageName.replaceAll("@", "").replaceAll("/", "__").replaceAll("-", "_"),
47
- remotes: frontendPluginRemotes.map((remote) => ({
48
- alias: remote.packageName,
49
- ...remote.remoteInfo
50
- }))
51
- });
46
+ if (options?.moduleFederation?.instance) {
47
+ instance = options.moduleFederation.instance;
48
+ } else {
49
+ const shared = await loadModuleFederationHostShared({
50
+ onError: (err) => error(err.message, err.cause)
51
+ });
52
+ const createOptions = {
53
+ name: appPackageName.replaceAll("@", "").replaceAll("/", "__").replaceAll("-", "_"),
54
+ shared,
55
+ remotes: []
56
+ };
57
+ if (options?.moduleFederation?.shareStrategy) {
58
+ createOptions.shareStrategy = options.moduleFederation.shareStrategy;
59
+ }
60
+ instance = createInstance(createOptions);
61
+ }
62
+ const userOptions = {
63
+ name: instance.name,
64
+ remotes: []
65
+ };
66
+ if (options?.moduleFederation?.plugins) {
67
+ userOptions.plugins = options.moduleFederation.plugins;
68
+ }
69
+ if (options?.moduleFederation?.shareStrategy) {
70
+ userOptions.shareStrategy = options.moduleFederation.shareStrategy;
71
+ }
72
+ if (options?.moduleFederation?.shared) {
73
+ userOptions.shared = options.moduleFederation.shared;
74
+ }
75
+ userOptions.remotes = frontendPluginRemotes.map((remote) => ({
76
+ alias: remote.packageName,
77
+ ...remote.remoteInfo
78
+ }));
79
+ instance.initOptions(userOptions);
52
80
  } catch (err) {
53
81
  error(`Failed initializing module federation`, err);
54
82
  return [];
@@ -63,7 +91,7 @@ function dynamicFrontendFeaturesLoader(options) {
63
91
  const remoteModuleName = exposedModuleName === "." ? remote.remoteInfo.name : `${remote.remoteInfo.name}/${exposedModuleName}`;
64
92
  let module;
65
93
  try {
66
- module = await loadRemote(remoteModuleName);
94
+ module = await instance.loadRemote(remoteModuleName);
67
95
  } catch (err) {
68
96
  error(
69
97
  `Failed loading remote module '${remoteModuleName}' of dynamic plugin '${remote.packageName}'`,
@@ -1 +1 @@
1
- {"version":3,"file":"loader.esm.js","sources":["../src/loader.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n FederationRuntimePlugin,\n init,\n loadRemote,\n} from '@module-federation/enhanced/runtime';\nimport { Module } from '@module-federation/sdk';\nimport { DefaultApiClient, Remote } from './schema/openapi';\nimport {\n FrontendFeature,\n FrontendFeatureLoader,\n createFrontendFeatureLoader,\n} from '@backstage/frontend-plugin-api';\nimport { ShareStrategy, UserOptions } from '@module-federation/runtime/types';\n\n/**\n *\n * @public\n */\nexport type DynamicFrontendFeaturesLoaderOptions = {\n /**\n * Additional module federation arguments for the Module Federation runtime initialization.\n */\n moduleFederation: {\n shared?: UserOptions['shared'];\n shareStrategy?: ShareStrategy;\n plugins?: Array<FederationRuntimePlugin>;\n };\n};\n\n/**\n * A function providing a loader of frontend features exposed as module federation remotes\n * from the backend dynamic features service.\n *\n * @public\n */\nexport function dynamicFrontendFeaturesLoader(\n options?: DynamicFrontendFeaturesLoaderOptions,\n): FrontendFeatureLoader {\n return createFrontendFeatureLoader({\n async loader({ config }) {\n const dynamicPLuginsConfig = config.getOptionalConfig('dynamicPlugins');\n if (!dynamicPLuginsConfig) {\n return [];\n }\n\n function error(message: string, err: unknown) {\n // eslint-disable-next-line no-console\n console.error(\n `${message}: ${\n err instanceof Error ? err.toString() : JSON.stringify(err)\n }`,\n );\n }\n\n const backendBaseUrl = config.getString('backend.baseUrl');\n\n const appPackageName =\n config.getOptionalString('app.packageName') ?? 'app';\n let frontendPluginRemotes: Array<Remote>;\n try {\n const apiClient = new DefaultApiClient({\n discoveryApi: {\n getBaseUrl: async rootPath => `${backendBaseUrl}/${rootPath}`,\n },\n fetchApi: {\n fetch(input) {\n return global.fetch(input);\n },\n },\n });\n\n const response = await apiClient.getRemotes({});\n if (!response.ok) {\n throw new Error(`${response.status} - ${response.statusText}`);\n }\n frontendPluginRemotes = await response.json();\n } catch (err) {\n error(\n `Failed fetching module federation configuration of dynamic frontend plugins`,\n err,\n );\n return [];\n }\n\n try {\n init({\n ...options?.moduleFederation,\n name: appPackageName\n .replaceAll('@', '')\n .replaceAll('/', '__')\n .replaceAll('-', '_'),\n remotes: frontendPluginRemotes.map(remote => ({\n alias: remote.packageName,\n ...remote.remoteInfo,\n })),\n });\n } catch (err) {\n error(`Failed initializing module federation`, err);\n return [];\n }\n\n const features = (\n await Promise.all(\n frontendPluginRemotes.map(async remote => {\n // eslint-disable-next-line no-console\n console.debug(\n `Loading dynamic plugin '${remote.packageName}' from '${remote.remoteInfo.entry}'`,\n );\n\n const moduleFeatures = await Promise.all(\n remote.exposedModules.map(async exposedModuleName => {\n const remoteModuleName =\n exposedModuleName === '.'\n ? remote.remoteInfo.name\n : `${remote.remoteInfo.name}/${exposedModuleName}`;\n let module: Module;\n try {\n module = await loadRemote<Module>(remoteModuleName);\n } catch (err) {\n error(\n `Failed loading remote module '${remoteModuleName}' of dynamic plugin '${remote.packageName}'`,\n err,\n );\n return undefined;\n }\n if (!module) {\n // eslint-disable-next-line no-console\n console.warn(\n `Skipping empty dynamic plugin remote module '${remoteModuleName}'.`,\n );\n return undefined;\n }\n // eslint-disable-next-line no-console\n console.info(\n `Remote module '${remoteModuleName}' of dynamic plugin '${remote.packageName}' loaded from ${remote.remoteInfo.entry}`,\n );\n const defaultEntry = module.default;\n if (!isLoadable(defaultEntry)) {\n // eslint-disable-next-line no-console\n console.debug(\n `Skipping dynamic plugin remote module '${remote}' since it doesn't export a new 'FrontendFeature' as default export.`,\n );\n return undefined;\n }\n return defaultEntry;\n }),\n );\n return moduleFeatures;\n }),\n )\n )\n .flat()\n .filter((feature): feature is FrontendFeature => feature !== undefined);\n\n return [...features];\n },\n });\n}\n\nfunction isLoadable(obj: unknown): obj is FrontendFeature {\n if (obj !== null && typeof obj === 'object' && '$$type' in obj) {\n return (\n obj.$$type === '@backstage/FrontendPlugin' ||\n obj.$$type === '@backstage/FrontendModule'\n );\n }\n return false;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loader.esm.js","sources":["../src/loader.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ModuleFederationRuntimePlugin,\n createInstance,\n ModuleFederation,\n} from '@module-federation/enhanced/runtime';\nimport { Module } from '@module-federation/sdk';\nimport { DefaultApiClient, Remote } from './schema/openapi';\nimport {\n FrontendFeature,\n FrontendFeatureLoader,\n createFrontendFeatureLoader,\n} from '@backstage/frontend-plugin-api';\nimport { ShareStrategy, UserOptions } from '@module-federation/runtime/types';\nimport { loadModuleFederationHostShared } from '@backstage/module-federation-common';\n\n/**\n *\n * @public\n */\nexport type DynamicFrontendFeaturesLoaderOptions = {\n /**\n * Additional module federation arguments for the Module Federation runtime initialization.\n */\n moduleFederation: {\n shared?: UserOptions['shared'];\n shareStrategy?: ShareStrategy;\n plugins?: Array<ModuleFederationRuntimePlugin>;\n instance?: ModuleFederation;\n };\n};\n\n/**\n * A function providing a loader of frontend features exposed as module federation remotes\n * from the backend dynamic features service.\n *\n * @public\n */\nexport function dynamicFrontendFeaturesLoader(\n options?: DynamicFrontendFeaturesLoaderOptions,\n): FrontendFeatureLoader {\n return createFrontendFeatureLoader({\n async loader({ config }) {\n const dynamicPLuginsConfig = config.getOptionalConfig('dynamicPlugins');\n if (!dynamicPLuginsConfig) {\n return [];\n }\n\n function error(message: string, err: unknown) {\n // eslint-disable-next-line no-console\n console.error(\n `${message}: ${\n err instanceof Error ? err.toString() : JSON.stringify(err)\n }`,\n );\n }\n\n const backendBaseUrl = config.getString('backend.baseUrl');\n\n const appPackageName =\n config.getOptionalString('app.packageName') ?? 'app';\n let frontendPluginRemotes: Array<Remote>;\n try {\n const apiClient = new DefaultApiClient({\n discoveryApi: {\n getBaseUrl: async rootPath => `${backendBaseUrl}/${rootPath}`,\n },\n fetchApi: {\n fetch(input) {\n return global.fetch(input);\n },\n },\n });\n\n const response = await apiClient.getRemotes({});\n if (!response.ok) {\n throw new Error(`${response.status} - ${response.statusText}`);\n }\n frontendPluginRemotes = await response.json();\n } catch (err) {\n error(\n `Failed fetching module federation configuration of dynamic frontend plugins`,\n err,\n );\n return [];\n }\n\n let instance: ModuleFederation;\n try {\n if (options?.moduleFederation?.instance) {\n instance = options.moduleFederation.instance;\n } else {\n const shared = await loadModuleFederationHostShared({\n onError: err => error(err.message, err.cause),\n });\n\n const createOptions: UserOptions = {\n name: appPackageName\n .replaceAll('@', '')\n .replaceAll('/', '__')\n .replaceAll('-', '_'),\n shared,\n remotes: [],\n };\n if (options?.moduleFederation?.shareStrategy) {\n createOptions.shareStrategy =\n options.moduleFederation.shareStrategy;\n }\n instance = createInstance(createOptions);\n }\n\n const userOptions: UserOptions = {\n name: instance.name,\n remotes: [],\n };\n\n if (options?.moduleFederation?.plugins) {\n userOptions.plugins = options.moduleFederation.plugins;\n }\n if (options?.moduleFederation?.shareStrategy) {\n userOptions.shareStrategy = options.moduleFederation.shareStrategy;\n }\n if (options?.moduleFederation?.shared) {\n userOptions.shared = options.moduleFederation.shared;\n }\n userOptions.remotes = frontendPluginRemotes.map(remote => ({\n alias: remote.packageName,\n ...remote.remoteInfo,\n }));\n instance.initOptions(userOptions);\n } catch (err) {\n error(`Failed initializing module federation`, err);\n return [];\n }\n\n const features = (\n await Promise.all(\n frontendPluginRemotes.map(async remote => {\n // eslint-disable-next-line no-console\n console.debug(\n `Loading dynamic plugin '${remote.packageName}' from '${remote.remoteInfo.entry}'`,\n );\n\n const moduleFeatures = await Promise.all(\n remote.exposedModules.map(async exposedModuleName => {\n const remoteModuleName =\n exposedModuleName === '.'\n ? remote.remoteInfo.name\n : `${remote.remoteInfo.name}/${exposedModuleName}`;\n let module: Module;\n try {\n module = await instance.loadRemote<Module>(remoteModuleName);\n } catch (err) {\n error(\n `Failed loading remote module '${remoteModuleName}' of dynamic plugin '${remote.packageName}'`,\n err,\n );\n return undefined;\n }\n if (!module) {\n // eslint-disable-next-line no-console\n console.warn(\n `Skipping empty dynamic plugin remote module '${remoteModuleName}'.`,\n );\n return undefined;\n }\n // eslint-disable-next-line no-console\n console.info(\n `Remote module '${remoteModuleName}' of dynamic plugin '${remote.packageName}' loaded from ${remote.remoteInfo.entry}`,\n );\n const defaultEntry = module.default;\n if (!isLoadable(defaultEntry)) {\n // eslint-disable-next-line no-console\n console.debug(\n `Skipping dynamic plugin remote module '${remote}' since it doesn't export a new 'FrontendFeature' as default export.`,\n );\n return undefined;\n }\n return defaultEntry;\n }),\n );\n return moduleFeatures;\n }),\n )\n )\n .flat()\n .filter((feature): feature is FrontendFeature => feature !== undefined);\n\n return [...features];\n },\n });\n}\n\nfunction isLoadable(obj: unknown): obj is FrontendFeature {\n if (obj !== null && typeof obj === 'object' && '$$type' in obj) {\n return (\n obj.$$type === '@backstage/FrontendPlugin' ||\n obj.$$type === '@backstage/FrontendModule'\n );\n }\n return false;\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/frontend-dynamic-feature-loader",
3
- "version": "0.1.9-next.1",
3
+ "version": "0.1.9",
4
4
  "backstage": {
5
5
  "role": "web-library"
6
6
  },
@@ -32,17 +32,18 @@
32
32
  "test": "backstage-cli package test"
33
33
  },
34
34
  "dependencies": {
35
- "@backstage/config": "1.3.6",
36
- "@backstage/frontend-plugin-api": "0.14.0-next.2",
37
- "@module-federation/enhanced": "^0.9.0",
38
- "@module-federation/runtime": "^0.9.0",
39
- "@module-federation/sdk": "^0.9.0",
35
+ "@backstage/config": "^1.3.6",
36
+ "@backstage/frontend-plugin-api": "^0.14.0",
37
+ "@backstage/module-federation-common": "^0.1.0",
38
+ "@module-federation/enhanced": "^0.21.6",
39
+ "@module-federation/runtime": "^0.21.6",
40
+ "@module-federation/sdk": "^0.21.6",
40
41
  "cross-fetch": "^4.0.0",
41
42
  "uri-template": "^2.0.0"
42
43
  },
43
44
  "devDependencies": {
44
- "@backstage/cli": "0.35.4-next.2",
45
- "@backstage/test-utils": "1.7.15-next.2",
45
+ "@backstage/cli": "^0.35.4",
46
+ "@backstage/test-utils": "^1.7.15",
46
47
  "@testing-library/jest-dom": "^6.0.0",
47
48
  "@testing-library/react": "^16.0.0",
48
49
  "@types/react": "^18.0.0",