@backstage/cli 0.35.4-next.1 → 0.35.4

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.
Files changed (36) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/dist/lib/entryPoints.cjs.js +4 -2
  3. package/dist/modules/build/commands/package/build/command.cjs.js +15 -1
  4. package/dist/modules/build/commands/package/start/startFrontend.cjs.js +3 -4
  5. package/dist/modules/build/index.cjs.js +6 -0
  6. package/dist/modules/build/lib/buildFrontend.cjs.js +3 -4
  7. package/dist/modules/build/lib/builder/config.cjs.js +2 -1
  8. package/dist/modules/build/lib/builder/packager.cjs.js +2 -1
  9. package/dist/modules/build/lib/builder/plugins.cjs.js +35 -0
  10. package/dist/modules/build/lib/bundler/bundle.cjs.js +9 -2
  11. package/dist/modules/build/lib/bundler/config.cjs.js +19 -76
  12. package/dist/modules/build/lib/bundler/moduleFederation.cjs.js +98 -15
  13. package/dist/modules/build/lib/bundler/server.cjs.js +15 -5
  14. package/dist/modules/build/lib/packager/productionPack.cjs.js +4 -1
  15. package/dist/modules/maintenance/commands/repo/fix.cjs.js +27 -15
  16. package/dist/packages/backend-defaults/package.json.cjs.js +1 -1
  17. package/dist/packages/backend-plugin-api/package.json.cjs.js +1 -1
  18. package/dist/packages/backend-test-utils/package.json.cjs.js +1 -1
  19. package/dist/packages/catalog-client/package.json.cjs.js +1 -1
  20. package/dist/packages/cli/package.json.cjs.js +5 -3
  21. package/dist/packages/core-app-api/package.json.cjs.js +1 -1
  22. package/dist/packages/core-components/package.json.cjs.js +1 -1
  23. package/dist/packages/core-plugin-api/package.json.cjs.js +1 -1
  24. package/dist/packages/dev-utils/package.json.cjs.js +1 -1
  25. package/dist/packages/frontend-defaults/package.json.cjs.js +1 -1
  26. package/dist/packages/frontend-plugin-api/package.json.cjs.js +1 -1
  27. package/dist/packages/frontend-test-utils/package.json.cjs.js +1 -1
  28. package/dist/packages/test-utils/package.json.cjs.js +1 -1
  29. package/dist/packages/theme/package.json.cjs.js +1 -1
  30. package/dist/plugins/auth-backend/package.json.cjs.js +1 -1
  31. package/dist/plugins/auth-backend-module-guest-provider/package.json.cjs.js +1 -1
  32. package/dist/plugins/catalog-node/package.json.cjs.js +1 -1
  33. package/dist/plugins/scaffolder-node/package.json.cjs.js +1 -1
  34. package/dist/plugins/scaffolder-node-test-utils/package.json.cjs.js +1 -1
  35. package/package.json +33 -31
  36. package/templates/scaffolder-backend-module/src/module.ts +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,46 @@
1
1
  # @backstage/cli
2
2
 
3
+ ## 0.35.4
4
+
5
+ ### Patch Changes
6
+
7
+ - cfd8103: Updated catalog provider module template to use stable catalog extension points from `@backstage/plugin-catalog-node` instead of alpha exports.
8
+ - 20131c5: Added support for CSS exports in package builds. When a package declares a CSS file in its `exports` field (e.g., `"./styles.css": "./src/styles.css"`), the CLI will automatically bundle it during `backstage-cli package build`, resolving any `@import` statements. The export path is rewritten from `src/` to `dist/` at publish time.
9
+
10
+ Fixed `backstage-cli repo fix` to not add `typesVersions` entries for non-script exports like CSS files.
11
+
12
+ - 7455dae: Use node prefix on native imports
13
+ - 6ce4a13: Removed `/alpha` from `scaffolderActionsExtensionPoint` import
14
+ - fdbd404: Removed the `EXPERIMENTAL_MODULE_FEDERATION` environment variable flag, making module federation host support always available during `package start`. The host shared dependencies are now managed through `@backstage/module-federation-common` and injected as a versioned runtime script at build time.
15
+ - fdbd404: Updated `@module-federation/enhanced`, `@module-federation/runtime`, and `@module-federation/sdk` dependencies from `^0.9.0` to `^0.21.6`.
16
+ - 4fc7bf0: Bump to tar v7
17
+ - 5e3ef57: Added support for the new `peerModules` metadata field in `package.json`. This field allows plugin packages to declare modules that should be installed alongside them for cross-plugin integrations. The field is validated by `backstage-cli repo fix --publish`.
18
+ - 122d39c: Completely removed support for the deprecated `app.experimental.packages` configuration. Replace existing usage directly with `app.packages`.
19
+ - 73351c2: Updated dependency `webpack` to `~5.104.0`.
20
+ - 69d880e: Bump to latest zod to ensure it has the latest features
21
+ - Updated dependencies
22
+ - @backstage/integration@1.20.0
23
+ - @backstage/config-loader@1.10.8
24
+ - @backstage/eslint-plugin@0.2.1
25
+ - @backstage/cli-common@0.1.18
26
+ - @backstage/cli-node@0.2.18
27
+ - @backstage/module-federation-common@0.1.0
28
+
29
+ ## 0.35.4-next.2
30
+
31
+ ### Patch Changes
32
+
33
+ - 20131c5: Added support for CSS exports in package builds. When a package declares a CSS file in its `exports` field (e.g., `"./styles.css": "./src/styles.css"`), the CLI will automatically bundle it during `backstage-cli package build`, resolving any `@import` statements. The export path is rewritten from `src/` to `dist/` at publish time.
34
+
35
+ Fixed `backstage-cli repo fix` to not add `typesVersions` entries for non-script exports like CSS files.
36
+
37
+ - 6ce4a13: Removed `/alpha` from `scaffolderActionsExtensionPoint` import
38
+ - 73351c2: Updated dependency `webpack` to `~5.104.0`.
39
+ - Updated dependencies
40
+ - @backstage/integration@1.20.0-next.2
41
+ - @backstage/cli-node@0.2.18-next.1
42
+ - @backstage/config-loader@1.10.8-next.0
43
+
3
44
  ## 0.35.4-next.1
4
45
 
5
46
  ### Patch Changes
@@ -8,17 +8,19 @@ const defaultIndex = {
8
8
  name: "index",
9
9
  ext: ".ts"
10
10
  };
11
+ const SCRIPT_EXTS = [".js", ".jsx", ".ts", ".tsx"];
11
12
  function parseEntryPoint(mount, path$1) {
13
+ const ext = path.extname(path$1);
12
14
  let name = mount;
13
15
  if (name === ".") {
14
16
  name = "index";
15
17
  } else if (name.startsWith("./")) {
16
18
  name = name.slice(2);
17
19
  }
18
- if (name.includes("/")) {
20
+ if (name.includes("/") && SCRIPT_EXTS.includes(ext)) {
19
21
  throw new Error(`Mount point '${mount}' may not contain multiple slashes`);
20
22
  }
21
- return { mount, path: path$1, name, ext: path.extname(path$1) };
23
+ return { mount, path: path$1, name, ext };
22
24
  }
23
25
  function readEntryPoints(pkg) {
24
26
  const exp = pkg.exports;
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var fs = require('fs-extra');
3
4
  var packager = require('../../../lib/builder/packager.cjs.js');
4
5
  var types = require('../../../lib/builder/types.cjs.js');
5
6
  var role = require('../../../../../lib/role.cjs.js');
@@ -12,6 +13,7 @@ var chalk = require('chalk');
12
13
 
13
14
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
14
15
 
16
+ var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
15
17
  var chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
16
18
 
17
19
  async function command(opts) {
@@ -39,17 +41,25 @@ async function command(opts) {
39
41
  minify: Boolean(opts.minify)
40
42
  });
41
43
  }
44
+ let isModuleFederationRemote = void 0;
42
45
  if (role$1 === "frontend-dynamic-container") {
43
46
  console.log(
44
47
  chalk__default.default.yellow(
45
48
  `\u26A0\uFE0F WARNING: The 'frontend-dynamic-container' package role is experimental and will receive immediate breaking changes in the future.`
46
49
  )
47
50
  );
51
+ isModuleFederationRemote = true;
52
+ }
53
+ if (opts.moduleFederation) {
54
+ isModuleFederationRemote = true;
55
+ }
56
+ if (isModuleFederationRemote) {
57
+ console.log("Building package as a module federation remote");
48
58
  return buildFrontend.buildFrontend({
49
59
  targetDir: paths.paths.targetDir,
50
60
  configPaths: [],
51
61
  writeStats: Boolean(opts.stats),
52
- isModuleFederationRemote: true,
62
+ isModuleFederationRemote,
53
63
  webpack
54
64
  });
55
65
  }
@@ -64,8 +74,12 @@ async function command(opts) {
64
74
  if (roleInfo.output.includes("types")) {
65
75
  outputs.add(types.Output.types);
66
76
  }
77
+ const packageJson = await fs__default.default.readJson(
78
+ paths.paths.resolveTarget("package.json")
79
+ );
67
80
  return packager.buildPackage({
68
81
  outputs,
82
+ packageJson,
69
83
  minify: Boolean(opts.minify),
70
84
  workspacePackages: await cliNode.PackageGraph.listTargetPackages()
71
85
  });
@@ -39,11 +39,10 @@ async function startFrontend(options) {
39
39
  verifyVersions: options.verifyVersions,
40
40
  skipOpenBrowser: options.skipOpenBrowser,
41
41
  linkedWorkspace: options.linkedWorkspace,
42
- moduleFederation: await moduleFederation.getModuleFederationOptions(
42
+ moduleFederationRemote: options.isModuleFederationRemote ? await moduleFederation.getModuleFederationRemoteOptions(
43
43
  packageJson,
44
- path.resolve(paths.paths.targetDir),
45
- options.isModuleFederationRemote
46
- )
44
+ path.resolve(paths.paths.targetDir)
45
+ ) : void 0
47
46
  });
48
47
  await waitForExit();
49
48
  }
@@ -22,6 +22,9 @@ function registerPackageCommands(command) {
22
22
  "Config files to load instead of app-config.yaml. Applies to app packages only.",
23
23
  (opt, opts) => opts ? [...opts, opt] : [opt],
24
24
  Array()
25
+ ).option(
26
+ "--module-federation",
27
+ "Build a package as a module federation remote. Applies to frontend plugin packages only."
25
28
  ).action(lazy.lazy(() => import('./commands/package/build/index.cjs.js'), "command"));
26
29
  }
27
30
  const buildPlugin = factory.createCliPlugin({
@@ -49,6 +52,9 @@ const buildPlugin = factory.createCliPlugin({
49
52
  "Config files to load instead of app-config.yaml. Applies to app packages only.",
50
53
  (opt, opts) => opts ? [...opts, opt] : [opt],
51
54
  Array()
55
+ ).option(
56
+ "--module-federation",
57
+ "Build a package as a module federation remote. Applies to frontend plugin packages only."
52
58
  ).action(lazy.lazy(() => import('./commands/package/build/index.cjs.js'), "command"));
53
59
  await defaultCommand.parseAsync(args, { from: "user" });
54
60
  }
@@ -37,11 +37,10 @@ async function buildFrontend(options) {
37
37
  entry: "src/index",
38
38
  parallelism: parallel.getEnvironmentParallelism(),
39
39
  statsJsonEnabled: writeStats,
40
- moduleFederation: await moduleFederation.getModuleFederationOptions(
40
+ moduleFederationRemote: options.isModuleFederationRemote ? await moduleFederation.getModuleFederationRemoteOptions(
41
41
  packageJson,
42
- path.resolve(targetDir),
43
- options.isModuleFederationRemote
44
- ),
42
+ path.resolve(targetDir)
43
+ ) : void 0,
45
44
  ...await config.loadCliConfig({
46
45
  args: configPaths,
47
46
  fromPackage: packageJson.name
@@ -210,7 +210,8 @@ async function makeRollupConfigs(options) {
210
210
  esbuild__default.default({
211
211
  target: "ES2023",
212
212
  minify: options.minify
213
- })
213
+ }),
214
+ plugins.cssEntryPoints({ entryPoints: entryPoints$1, targetDir })
214
215
  ]
215
216
  });
216
217
  }
@@ -90,7 +90,8 @@ const buildPackage = async (options) => {
90
90
  } catch {
91
91
  }
92
92
  const rollupConfigs = await config.makeRollupConfigs(options);
93
- await fs__default.default.remove(path.resolve(options.targetDir ?? paths.paths.targetDir, "dist"));
93
+ const targetDir = options.targetDir ?? paths.paths.targetDir;
94
+ await fs__default.default.remove(path.resolve(targetDir, "dist"));
94
95
  const buildTasks = rollupConfigs.map(rollupBuild);
95
96
  await Promise.all(buildTasks);
96
97
  };
@@ -1,12 +1,16 @@
1
1
  'use strict';
2
2
 
3
3
  var fs = require('fs-extra');
4
+ var postcss = require('postcss');
5
+ var postcssImport = require('postcss-import');
4
6
  var path = require('node:path');
5
7
  var rollupPluginutils = require('rollup-pluginutils');
6
8
 
7
9
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
8
10
 
9
11
  var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
12
+ var postcss__default = /*#__PURE__*/_interopDefaultCompat(postcss);
13
+ var postcssImport__default = /*#__PURE__*/_interopDefaultCompat(postcssImport);
10
14
 
11
15
  function forwardFileImports(options) {
12
16
  const filter = rollupPluginutils.createFilter(options.include, options.exclude);
@@ -85,6 +89,37 @@ function forwardFileImports(options) {
85
89
  }
86
90
  };
87
91
  }
92
+ function cssEntryPoints(options) {
93
+ const cssEntries = options.entryPoints.filter((ep) => ep.ext === ".css");
94
+ const generatedFor = /* @__PURE__ */ new Set();
95
+ return {
96
+ name: "backstage-css-entry-points",
97
+ async generateBundle(outputOptions, _bundle, isWrite) {
98
+ if (!isWrite) {
99
+ return;
100
+ }
101
+ const dir = outputOptions.dir || path.dirname(outputOptions.file);
102
+ if (generatedFor.has(dir)) {
103
+ return;
104
+ }
105
+ generatedFor.add(dir);
106
+ for (const entryPoint of cssEntries) {
107
+ const sourcePath = path.resolve(options.targetDir, entryPoint.path);
108
+ const outputPath = entryPoint.path.replace(/^(\.\/)?src\//, "");
109
+ const source = await fs__default.default.readFile(sourcePath, "utf8");
110
+ const result = await postcss__default.default([postcssImport__default.default()]).process(source, {
111
+ from: sourcePath
112
+ });
113
+ this.emitFile({
114
+ type: "asset",
115
+ fileName: outputPath,
116
+ source: result.css
117
+ });
118
+ }
119
+ }
120
+ };
121
+ }
88
122
 
123
+ exports.cssEntryPoints = cssEntryPoints;
89
124
  exports.forwardFileImports = forwardFileImports;
90
125
  //# sourceMappingURL=plugins.cjs.js.map
@@ -10,6 +10,7 @@ var config = require('./config.cjs.js');
10
10
  var paths = require('./paths.cjs.js');
11
11
  var chalk = require('chalk');
12
12
  var packageDetection = require('./packageDetection.cjs.js');
13
+ var moduleFederation = require('./moduleFederation.cjs.js');
13
14
 
14
15
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
15
16
 
@@ -39,17 +40,23 @@ async function buildBundle(options) {
39
40
  getFrontendAppConfigs: () => options.frontendAppConfigs
40
41
  };
41
42
  const configs = [];
42
- if (options.moduleFederation?.mode === "remote") {
43
+ if (options.moduleFederationRemote) {
43
44
  configs.push(await config.createConfig(paths$1, commonConfigOptions));
44
45
  } else {
45
46
  const detectedModulesEntryPoint = await packageDetection.createDetectedModulesEntryPoint({
46
47
  config: options.fullConfig,
47
48
  targetPath: paths$1.targetPath
48
49
  });
50
+ const moduleFederationSharedDependenciesEntryPoint = await moduleFederation.createRuntimeSharedDependenciesEntryPoint({
51
+ targetPath: paths$1.targetPath
52
+ });
49
53
  configs.push(
50
54
  await config.createConfig(paths$1, {
51
55
  ...commonConfigOptions,
52
- additionalEntryPoints: detectedModulesEntryPoint,
56
+ additionalEntryPoints: [
57
+ ...detectedModulesEntryPoint,
58
+ ...moduleFederationSharedDependenciesEntryPoint
59
+ ],
53
60
  appMode: publicPaths ? "protected" : "public"
54
61
  })
55
62
  );
@@ -28,17 +28,17 @@ var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
28
28
  var pickBy__default = /*#__PURE__*/_interopDefaultCompat(pickBy);
29
29
  var yn__default = /*#__PURE__*/_interopDefaultCompat(yn);
30
30
 
31
- function resolveBaseUrl(config, moduleFederation) {
31
+ function resolveBaseUrl(config, moduleFederationRemote) {
32
32
  const baseUrl = config.getOptionalString("app.baseUrl");
33
- const defaultBaseUrl = moduleFederation?.mode === "remote" ? `http://localhost:${process.env.PORT ?? "3000"}` : "http://localhost:3000";
33
+ const defaultBaseUrl = moduleFederationRemote ? `http://localhost:${process.env.PORT ?? "3000"}` : "http://localhost:3000";
34
34
  try {
35
35
  return new URL(baseUrl ?? "/", defaultBaseUrl);
36
36
  } catch (error) {
37
37
  throw new Error(`Invalid app.baseUrl, ${error}`);
38
38
  }
39
39
  }
40
- function resolveEndpoint(config, moduleFederation) {
41
- const url = resolveBaseUrl(config, moduleFederation);
40
+ function resolveEndpoint(config, moduleFederationRemote) {
41
+ const url = resolveBaseUrl(config, moduleFederationRemote);
42
42
  return {
43
43
  host: config.getOptionalString("app.listen.host") ?? url.hostname,
44
44
  port: config.getOptionalNumber("app.listen.port") ?? Number(url.port) ?? (url.protocol === "https:" ? 443 : 80)
@@ -77,12 +77,12 @@ async function createConfig(paths, options) {
77
77
  checksEnabled,
78
78
  isDev,
79
79
  frontendConfig,
80
- moduleFederation,
80
+ moduleFederationRemote,
81
81
  publicSubPath = "",
82
82
  webpack
83
83
  } = options;
84
84
  const { plugins, loaders } = transforms.transforms(options);
85
- const validBaseUrl = resolveBaseUrl(frontendConfig, moduleFederation);
85
+ const validBaseUrl = resolveBaseUrl(frontendConfig, moduleFederationRemote);
86
86
  let publicPath = validBaseUrl.pathname.replace(/\/$/, "");
87
87
  if (publicSubPath) {
88
88
  publicPath = `${publicPath}${publicSubPath}`.replace("//", "/");
@@ -90,7 +90,7 @@ async function createConfig(paths, options) {
90
90
  if (isDev) {
91
91
  const { host, port } = resolveEndpoint(
92
92
  options.frontendConfig,
93
- options.moduleFederation
93
+ options.moduleFederationRemote
94
94
  );
95
95
  const refreshOptions = {
96
96
  overlay: {
@@ -129,7 +129,7 @@ async function createConfig(paths, options) {
129
129
  Buffer: ["buffer", "Buffer"]
130
130
  })
131
131
  );
132
- if (options.moduleFederation?.mode !== "remote") {
132
+ if (!options.moduleFederationRemote) {
133
133
  const templateOptions = {
134
134
  meta: {
135
135
  "backstage-app-mode": options?.appMode ?? "public"
@@ -164,79 +164,22 @@ async function createConfig(paths, options) {
164
164
  })
165
165
  );
166
166
  }
167
- if (options.moduleFederation) {
168
- const isRemote = options.moduleFederation?.mode === "remote";
167
+ if (options.moduleFederationRemote) {
169
168
  const AdaptedModuleFederationPlugin = webpack ? require("@module-federation/enhanced/webpack").ModuleFederationPlugin : rspack.ModuleFederationPlugin;
170
- const exposes = options.moduleFederation?.exposes ? Object.fromEntries(
171
- Object.entries(options.moduleFederation?.exposes).map(([k, v]) => [
172
- k,
173
- path.resolve(paths.targetPath, v)
174
- ])
169
+ const exposes = options.moduleFederationRemote.exposes ? Object.fromEntries(
170
+ Object.entries(options.moduleFederationRemote?.exposes).map(
171
+ ([k, v]) => [k, path.resolve(paths.targetPath, v)]
172
+ )
175
173
  ) : {
176
174
  ".": paths.targetEntry
177
175
  };
178
176
  plugins.push(
179
177
  new AdaptedModuleFederationPlugin({
180
- ...isRemote && {
181
- filename: "remoteEntry.js",
182
- exposes
183
- },
184
- name: options.moduleFederation.name,
178
+ filename: "remoteEntry.js",
179
+ exposes,
180
+ name: options.moduleFederationRemote.name,
185
181
  runtime: false,
186
- shared: {
187
- // React
188
- react: {
189
- singleton: true,
190
- requiredVersion: "*",
191
- eager: !isRemote,
192
- ...isRemote && { import: false }
193
- },
194
- "react-dom": {
195
- singleton: true,
196
- requiredVersion: "*",
197
- eager: !isRemote,
198
- ...isRemote && { import: false }
199
- },
200
- // React Router
201
- "react-router": {
202
- singleton: true,
203
- requiredVersion: "*",
204
- eager: !isRemote,
205
- ...isRemote && { import: false }
206
- },
207
- "react-router-dom": {
208
- singleton: true,
209
- requiredVersion: "*",
210
- eager: !isRemote,
211
- ...isRemote && { import: false }
212
- },
213
- // MUI v4
214
- // not setting import: false for MUI packages as this
215
- // will break once Backstage moves to BUI
216
- "@material-ui/core/styles": {
217
- singleton: true,
218
- requiredVersion: "*",
219
- eager: !isRemote
220
- },
221
- "@material-ui/styles": {
222
- singleton: true,
223
- requiredVersion: "*",
224
- eager: !isRemote
225
- },
226
- // MUI v5
227
- // not setting import: false for MUI packages as this
228
- // will break once Backstage moves to BUI
229
- "@mui/material/styles/": {
230
- singleton: true,
231
- requiredVersion: "*",
232
- eager: !isRemote
233
- },
234
- "@emotion/react": {
235
- singleton: true,
236
- requiredVersion: "*",
237
- eager: !isRemote
238
- }
239
- }
182
+ shared: options.moduleFederationRemote.sharedDependencies
240
183
  })
241
184
  );
242
185
  }
@@ -337,9 +280,9 @@ async function createConfig(paths, options) {
337
280
  rules: loaders
338
281
  },
339
282
  output: {
340
- uniqueName: options.moduleFederation?.name,
283
+ uniqueName: options.moduleFederationRemote?.name,
341
284
  path: paths.targetDist,
342
- publicPath: options.moduleFederation?.mode === "remote" ? "auto" : `${publicPath}/`,
285
+ publicPath: options.moduleFederationRemote ? "auto" : `${publicPath}/`,
343
286
  filename: isDev ? "[name].js" : "static/[name].[contenthash:8].js",
344
287
  chunkFilename: isDev ? "[name].chunk.js" : "static/[name].[contenthash:8].chunk.js",
345
288
  ...isDev ? {
@@ -1,25 +1,23 @@
1
1
  'use strict';
2
2
 
3
- var chalk = require('chalk');
4
3
  var entryPoints = require('../../../../lib/entryPoints.cjs.js');
5
4
  var typeDistProject = require('../../../../lib/typeDistProject.cjs.js');
5
+ var moduleFederationCommon = require('@backstage/module-federation-common');
6
+ var path = require('path');
7
+ var fs = require('fs-extra');
8
+ var chokidar = require('chokidar');
9
+ var PQueue = require('p-queue');
6
10
 
7
11
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
8
12
 
9
- var chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
13
+ var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
14
+ var chokidar__default = /*#__PURE__*/_interopDefaultCompat(chokidar);
15
+ var PQueue__default = /*#__PURE__*/_interopDefaultCompat(PQueue);
10
16
 
11
- async function getModuleFederationOptions(packageJson, packageDir, isModuleFederationRemote) {
12
- if (!isModuleFederationRemote && !process.env.EXPERIMENTAL_MODULE_FEDERATION) {
13
- return void 0;
14
- }
15
- console.log(
16
- chalk__default.default.yellow(
17
- `\u26A0\uFE0F WARNING: Module federation is experimental and will receive immediate breaking changes in the future.`
18
- )
19
- );
17
+ async function getModuleFederationRemoteOptions(packageJson, packageDir) {
20
18
  let exposes;
21
19
  const packageRole = packageJson.backstage?.role;
22
- if (isModuleFederationRemote && packageJson.exports && packageRole) {
20
+ if (packageJson.exports && packageRole) {
23
21
  const project = await typeDistProject.createTypeDistProject();
24
22
  exposes = Object.fromEntries(
25
23
  entryPoints.readEntryPoints(packageJson).filter((ep) => {
@@ -39,14 +37,99 @@ async function getModuleFederationOptions(packageJson, packageDir, isModuleFeder
39
37
  );
40
38
  }
41
39
  return {
42
- mode: isModuleFederationRemote ? "remote" : "host",
43
40
  // The default output mode requires the name to be a usable as a code
44
41
  // symbol, there might be better options here but for now we need to
45
42
  // sanitize the name.
46
43
  name: packageJson.name.replaceAll("@", "").replaceAll("/", "__").replaceAll("-", "_"),
47
- exposes
44
+ exposes,
45
+ sharedDependencies: moduleFederationCommon.defaultRemoteSharedDependencies()
46
+ };
47
+ }
48
+ function prepareRuntimeSharedDependenciesScript(hostSharedDependencies) {
49
+ const items = Object.entries(hostSharedDependencies).map(
50
+ ([name, sharedDep]) => {
51
+ if (!sharedDep.version) {
52
+ throw new Error(`Version is required for shared dependency '${name}'`);
53
+ }
54
+ return {
55
+ name,
56
+ version: sharedDep.version,
57
+ lib: name,
58
+ // Coverted into import below
59
+ shareConfig: {
60
+ singleton: sharedDep.singleton,
61
+ requiredVersion: sharedDep.requiredVersion,
62
+ eager: sharedDep.eager
63
+ }
64
+ };
65
+ }
66
+ );
67
+ return `window['${moduleFederationCommon.BACKSTAGE_RUNTIME_SHARED_DEPENDENCIES_GLOBAL}'] = ${JSON.stringify(
68
+ { items, version: "v1" },
69
+ null,
70
+ 2
71
+ ).replace(
72
+ /"lib": ("[^"]+")/gm,
73
+ (_, name) => `"lib": () => import(${name})`
74
+ )};`;
75
+ }
76
+ const RUNTIME_SHARED_DEPENDENCIES_MODULE_NAME = "__backstage-module-federation-runtime-shared-dependencies__";
77
+ const writeQueue = new PQueue__default.default({ concurrency: 1 });
78
+ async function writeRuntimeSharedDependenciesModule(targetPath, runtimeSharedDependencies) {
79
+ const script = prepareRuntimeSharedDependenciesScript(
80
+ runtimeSharedDependencies
81
+ );
82
+ await writeQueue.add(async () => {
83
+ const path$1 = path.join(
84
+ targetPath,
85
+ "node_modules",
86
+ `${RUNTIME_SHARED_DEPENDENCIES_MODULE_NAME}.js`
87
+ );
88
+ await fs__default.default.ensureDir(path.dirname(path$1));
89
+ await fs__default.default.writeFile(path$1, script);
90
+ });
91
+ }
92
+ function resolveSharedDependencyVersions(targetPath, hostSharedDependencies) {
93
+ return Object.fromEntries(
94
+ Object.entries(hostSharedDependencies).filter(([_, sharedDep]) => sharedDep !== void 0).flatMap(([importPath, sharedDep]) => {
95
+ const moduleName = importPath.startsWith("@") ? importPath.split("/").slice(0, 2).join("/") : importPath.split("/")[0];
96
+ let version;
97
+ try {
98
+ const packagePath = require.resolve(`${moduleName}/package.json`, {
99
+ paths: [targetPath]
100
+ });
101
+ version = require(packagePath).version;
102
+ } catch (e) {
103
+ console.log(
104
+ `Skipping module federation shared dependency '${importPath}' because it could not be resolved.`
105
+ );
106
+ return [];
107
+ }
108
+ return [[importPath, { ...sharedDep, version }]];
109
+ })
110
+ );
111
+ }
112
+ async function createRuntimeSharedDependenciesEntryPoint(options) {
113
+ const { targetPath, watch } = options;
114
+ const doWriteSharedDependenciesModule = async () => {
115
+ const sharedDependencies = moduleFederationCommon.defaultHostSharedDependencies();
116
+ await writeRuntimeSharedDependenciesModule(
117
+ targetPath,
118
+ resolveSharedDependencyVersions(targetPath, sharedDependencies)
119
+ );
48
120
  };
121
+ if (watch) {
122
+ const watcher = chokidar__default.default.watch(path.resolve(targetPath, "package.json"));
123
+ watcher.on("change", async () => {
124
+ await doWriteSharedDependenciesModule();
125
+ watch();
126
+ });
127
+ }
128
+ await doWriteSharedDependenciesModule();
129
+ return [RUNTIME_SHARED_DEPENDENCIES_MODULE_NAME];
49
130
  }
50
131
 
51
- exports.getModuleFederationOptions = getModuleFederationOptions;
132
+ exports.createRuntimeSharedDependenciesEntryPoint = createRuntimeSharedDependenciesEntryPoint;
133
+ exports.getModuleFederationRemoteOptions = getModuleFederationRemoteOptions;
134
+ exports.prepareRuntimeSharedDependenciesScript = prepareRuntimeSharedDependenciesScript;
52
135
  //# sourceMappingURL=moduleFederation.cjs.js.map
@@ -11,6 +11,7 @@ var config = require('../../../config/lib/config.cjs.js');
11
11
  var config$1 = require('./config.cjs.js');
12
12
  var packageDetection = require('./packageDetection.cjs.js');
13
13
  var paths = require('./paths.cjs.js');
14
+ var moduleFederation = require('./moduleFederation.cjs.js');
14
15
 
15
16
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
16
17
 
@@ -78,10 +79,10 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be
78
79
  );
79
80
  }
80
81
  const { frontendConfig, fullConfig } = cliConfig;
81
- const url = config$1.resolveBaseUrl(frontendConfig, options.moduleFederation);
82
+ const url = config$1.resolveBaseUrl(frontendConfig, options.moduleFederationRemote);
82
83
  const { host, port } = config$1.resolveEndpoint(
83
84
  frontendConfig,
84
- options.moduleFederation
85
+ options.moduleFederationRemote
85
86
  );
86
87
  const detectedModulesEntryPoint = await packageDetection.createDetectedModulesEntryPoint({
87
88
  config: fullConfig,
@@ -90,6 +91,12 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be
90
91
  triggerReload();
91
92
  }
92
93
  });
94
+ const moduleFederationSharedDependenciesEntryPoint = await moduleFederation.createRuntimeSharedDependenciesEntryPoint({
95
+ targetPath: paths$2.targetPath,
96
+ watch() {
97
+ triggerReload();
98
+ }
99
+ });
93
100
  const webpack = process.env.LEGACY_WEBPACK_BUILD ? require("webpack") : void 0;
94
101
  const commonConfigOptions = {
95
102
  ...options,
@@ -104,8 +111,11 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be
104
111
  };
105
112
  const config$2 = await config$1.createConfig(paths$2, {
106
113
  ...commonConfigOptions,
107
- additionalEntryPoints: detectedModulesEntryPoint,
108
- moduleFederation: options.moduleFederation
114
+ additionalEntryPoints: [
115
+ ...detectedModulesEntryPoint,
116
+ ...moduleFederationSharedDependenciesEntryPoint
117
+ ],
118
+ moduleFederationRemote: options.moduleFederationRemote
109
119
  });
110
120
  const bundler = webpack ?? core.rspack;
111
121
  const DevServer = webpack ? require("webpack-dev-server") : devServer.RspackDevServer;
@@ -135,7 +145,7 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be
135
145
  publicPath: config$2.output?.publicPath,
136
146
  directory: paths$2.targetPublic
137
147
  } : void 0,
138
- historyApiFallback: options.moduleFederation?.mode === "remote" ? false : {
148
+ historyApiFallback: options.moduleFederationRemote ? false : {
139
149
  // Paths with dots should still use the history fallback.
140
150
  // See https://github.com/facebookincubator/create-react-app/issues/387.
141
151
  disableDotRule: true,
@@ -92,7 +92,10 @@ async function rewriteEntryPoints(pkg, packageDir, featureDetectionProject) {
92
92
  }
93
93
  for (const entryPoint of entryPoints$1) {
94
94
  if (!SCRIPT_EXTS.includes(entryPoint.ext)) {
95
- outputExports[entryPoint.mount] = entryPoint.path;
95
+ outputExports[entryPoint.mount] = entryPoint.path.replace(
96
+ /^(\.\/)?src\//,
97
+ "./dist/"
98
+ );
96
99
  continue;
97
100
  }
98
101
  let exp = {};
@@ -10,6 +10,7 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
10
10
 
11
11
  var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
12
12
 
13
+ const SCRIPT_EXTS = [".js", ".jsx", ".ts", ".tsx", ".json"];
13
14
  async function readFixablePackages() {
14
15
  const packages = await cliNode.PackageGraph.listTargetPackages();
15
16
  return packages.map((pkg) => ({ ...pkg, changed: false }));
@@ -72,32 +73,43 @@ function fixPackageExports(pkg) {
72
73
  }
73
74
  const existingTypesVersions = JSON.stringify(pkg.packageJson.typesVersions);
74
75
  const typeEntries = {};
75
- for (const [path, value] of Object.entries(exp)) {
76
- if (path === ".") {
76
+ for (const [path$1, value] of Object.entries(exp)) {
77
+ if (path$1 === ".") {
77
78
  continue;
78
79
  }
79
- const newPath = trimRelative(path);
80
+ const newPath = trimRelative(path$1);
80
81
  if (typeof value === "string") {
81
- typeEntries[newPath] = [trimRelative(value)];
82
+ if (SCRIPT_EXTS.includes(path.extname(value))) {
83
+ typeEntries[newPath] = [trimRelative(value)];
84
+ }
82
85
  } else if (value && typeof value === "object" && !Array.isArray(value)) {
83
86
  if (typeof value.types === "string") {
84
87
  typeEntries[newPath] = [trimRelative(value.types)];
85
- } else if (typeof value.default === "string") {
88
+ } else if (typeof value.default === "string" && SCRIPT_EXTS.includes(path.extname(value.default))) {
86
89
  typeEntries[newPath] = [trimRelative(value.default)];
87
90
  }
88
91
  }
89
92
  }
90
- const typesVersions = { "*": typeEntries };
93
+ const hasTypeEntries = Object.keys(typeEntries).length > 0;
94
+ const typesVersions = hasTypeEntries ? { "*": typeEntries } : void 0;
91
95
  if (existingTypesVersions !== JSON.stringify(typesVersions)) {
92
- const newPkgEntries = Object.entries(pkg.packageJson).filter(
93
- ([name]) => name !== "typesVersions"
94
- );
95
- newPkgEntries.splice(
96
- newPkgEntries.findIndex(([name]) => name === "exports") + 1,
97
- 0,
98
- ["typesVersions", typesVersions]
99
- );
100
- pkg.packageJson = Object.fromEntries(newPkgEntries);
96
+ if (pkg.packageJson.typesVersions) {
97
+ if (typesVersions) {
98
+ pkg.packageJson.typesVersions = typesVersions;
99
+ } else {
100
+ delete pkg.packageJson.typesVersions;
101
+ }
102
+ } else if (typesVersions) {
103
+ const newPkgEntries = Object.entries(pkg.packageJson);
104
+ newPkgEntries.splice(
105
+ newPkgEntries.findIndex(([name]) => name === "exports") + 1,
106
+ 0,
107
+ ["typesVersions", typesVersions]
108
+ );
109
+ pkg.packageJson = Object.fromEntries(
110
+ newPkgEntries
111
+ );
112
+ }
101
113
  pkg.changed = true;
102
114
  }
103
115
  const publishConfig = pkg.packageJson.publishConfig;
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "0.15.2-next.1";
3
+ var version = "0.15.2";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "1.7.0-next.1";
3
+ var version = "1.7.0";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "1.10.5-next.0";
3
+ var version = "1.11.0";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "1.12.1";
3
+ var version = "1.13.0";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "0.35.4-next.1";
3
+ var version = "0.35.4";
4
4
  var dependencies = {
5
5
  "@backstage/catalog-model": "workspace:^",
6
6
  "@backstage/cli-common": "workspace:^",
@@ -10,10 +10,11 @@ var dependencies = {
10
10
  "@backstage/errors": "workspace:^",
11
11
  "@backstage/eslint-plugin": "workspace:^",
12
12
  "@backstage/integration": "workspace:^",
13
+ "@backstage/module-federation-common": "workspace:^",
13
14
  "@backstage/release-manifests": "workspace:^",
14
15
  "@backstage/types": "workspace:^",
15
16
  "@manypkg/get-packages": "^1.1.3",
16
- "@module-federation/enhanced": "^0.9.0",
17
+ "@module-federation/enhanced": "^0.21.6",
17
18
  "@octokit/request": "^8.0.0",
18
19
  "@rollup/plugin-commonjs": "^26.0.0",
19
20
  "@rollup/plugin-json": "^6.0.0",
@@ -73,6 +74,7 @@ var dependencies = {
73
74
  "p-queue": "^6.6.2",
74
75
  pirates: "^4.0.6",
75
76
  postcss: "^8.1.0",
77
+ "postcss-import": "^16.1.0",
76
78
  process: "^0.11.10",
77
79
  "raw-loader": "^4.0.2",
78
80
  "react-dev-utils": "^12.0.0-next.60",
@@ -146,7 +148,7 @@ var devDependencies = {
146
148
  msw: "^1.0.0",
147
149
  nodemon: "^3.0.1",
148
150
  "terser-webpack-plugin": "^5.1.3",
149
- webpack: "~5.103.0",
151
+ webpack: "~5.104.0",
150
152
  "webpack-dev-server": "^5.0.0"
151
153
  };
152
154
 
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "1.19.5-next.0";
3
+ var version = "1.19.5";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "0.18.7-next.1";
3
+ var version = "0.18.7";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "1.12.3-next.0";
3
+ var version = "1.12.3";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "1.1.20-next.1";
3
+ var version = "1.1.20";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "0.4.0-next.1";
3
+ var version = "0.4.0";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "0.14.0-next.1";
3
+ var version = "0.14.0";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "0.4.6-next.1";
3
+ var version = "0.5.0";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "1.7.15-next.1";
3
+ var version = "1.7.15";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "0.7.2-next.0";
3
+ var version = "0.7.2";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "0.26.1-next.0";
3
+ var version = "0.27.0";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "0.2.16-next.0";
3
+ var version = "0.2.16";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "1.21.0-next.0";
3
+ var version = "2.0.0";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "0.12.5-next.1";
3
+ var version = "0.12.5";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "0.3.8-next.0";
3
+ var version = "0.3.8";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/cli",
3
- "version": "0.35.4-next.1",
3
+ "version": "0.35.4",
4
4
  "description": "CLI for developing Backstage plugins and apps",
5
5
  "backstage": {
6
6
  "role": "cli"
@@ -47,18 +47,19 @@
47
47
  ]
48
48
  },
49
49
  "dependencies": {
50
- "@backstage/catalog-model": "1.7.6",
51
- "@backstage/cli-common": "0.1.18-next.0",
52
- "@backstage/cli-node": "0.2.18-next.1",
53
- "@backstage/config": "1.3.6",
54
- "@backstage/config-loader": "1.10.8-next.0",
55
- "@backstage/errors": "1.2.7",
56
- "@backstage/eslint-plugin": "0.2.1-next.0",
57
- "@backstage/integration": "1.20.0-next.1",
58
- "@backstage/release-manifests": "0.0.13",
59
- "@backstage/types": "1.2.2",
50
+ "@backstage/catalog-model": "^1.7.6",
51
+ "@backstage/cli-common": "^0.1.18",
52
+ "@backstage/cli-node": "^0.2.18",
53
+ "@backstage/config": "^1.3.6",
54
+ "@backstage/config-loader": "^1.10.8",
55
+ "@backstage/errors": "^1.2.7",
56
+ "@backstage/eslint-plugin": "^0.2.1",
57
+ "@backstage/integration": "^1.20.0",
58
+ "@backstage/module-federation-common": "^0.1.0",
59
+ "@backstage/release-manifests": "^0.0.13",
60
+ "@backstage/types": "^1.2.2",
60
61
  "@manypkg/get-packages": "^1.1.3",
61
- "@module-federation/enhanced": "^0.9.0",
62
+ "@module-federation/enhanced": "^0.21.6",
62
63
  "@octokit/request": "^8.0.0",
63
64
  "@rollup/plugin-commonjs": "^26.0.0",
64
65
  "@rollup/plugin-json": "^6.0.0",
@@ -118,6 +119,7 @@
118
119
  "p-queue": "^6.6.2",
119
120
  "pirates": "^4.0.6",
120
121
  "postcss": "^8.1.0",
122
+ "postcss-import": "^16.1.0",
121
123
  "process": "^0.11.10",
122
124
  "raw-loader": "^4.0.2",
123
125
  "react-dev-utils": "^12.0.0-next.60",
@@ -146,22 +148,22 @@
146
148
  "zod-validation-error": "^4.0.2"
147
149
  },
148
150
  "devDependencies": {
149
- "@backstage/backend-plugin-api": "1.7.0-next.1",
150
- "@backstage/backend-test-utils": "1.10.5-next.0",
151
- "@backstage/catalog-client": "1.12.1",
152
- "@backstage/config": "1.3.6",
153
- "@backstage/core-app-api": "1.19.5-next.0",
154
- "@backstage/core-components": "0.18.7-next.1",
155
- "@backstage/core-plugin-api": "1.12.3-next.0",
156
- "@backstage/dev-utils": "1.1.20-next.1",
157
- "@backstage/errors": "1.2.7",
158
- "@backstage/plugin-auth-backend": "0.26.1-next.0",
159
- "@backstage/plugin-auth-backend-module-guest-provider": "0.2.16-next.0",
160
- "@backstage/plugin-catalog-node": "1.21.0-next.0",
161
- "@backstage/plugin-scaffolder-node": "0.12.5-next.1",
162
- "@backstage/plugin-scaffolder-node-test-utils": "0.3.8-next.0",
163
- "@backstage/test-utils": "1.7.15-next.1",
164
- "@backstage/theme": "0.7.2-next.0",
151
+ "@backstage/backend-plugin-api": "^1.7.0",
152
+ "@backstage/backend-test-utils": "^1.11.0",
153
+ "@backstage/catalog-client": "^1.13.0",
154
+ "@backstage/config": "^1.3.6",
155
+ "@backstage/core-app-api": "^1.19.5",
156
+ "@backstage/core-components": "^0.18.7",
157
+ "@backstage/core-plugin-api": "^1.12.3",
158
+ "@backstage/dev-utils": "^1.1.20",
159
+ "@backstage/errors": "^1.2.7",
160
+ "@backstage/plugin-auth-backend": "^0.27.0",
161
+ "@backstage/plugin-auth-backend-module-guest-provider": "^0.2.16",
162
+ "@backstage/plugin-catalog-node": "^2.0.0",
163
+ "@backstage/plugin-scaffolder-node": "^0.12.5",
164
+ "@backstage/plugin-scaffolder-node-test-utils": "^0.3.8",
165
+ "@backstage/test-utils": "^1.7.15",
166
+ "@backstage/theme": "^0.7.2",
165
167
  "@jest/environment-jsdom-abstract": "^30.0.0",
166
168
  "@pmmmwh/react-refresh-webpack-plugin": "^0.6.0",
167
169
  "@types/cross-spawn": "^6.0.2",
@@ -191,12 +193,12 @@
191
193
  "msw": "^1.0.0",
192
194
  "nodemon": "^3.0.1",
193
195
  "terser-webpack-plugin": "^5.1.3",
194
- "webpack": "~5.103.0",
196
+ "webpack": "~5.104.0",
195
197
  "webpack-dev-server": "^5.0.0"
196
198
  },
197
199
  "peerDependencies": {
198
200
  "@jest/environment-jsdom-abstract": "^30.0.0",
199
- "@module-federation/enhanced": "^0.9.0",
201
+ "@module-federation/enhanced": "^0.21.6",
200
202
  "@pmmmwh/react-refresh-webpack-plugin": "^0.6.0",
201
203
  "esbuild-loader": "^4.0.0",
202
204
  "eslint-webpack-plugin": "^4.2.0",
@@ -206,7 +208,7 @@
206
208
  "jsdom": "^27.1.0",
207
209
  "mini-css-extract-plugin": "^2.4.2",
208
210
  "terser-webpack-plugin": "^5.1.3",
209
- "webpack": "~5.103.0",
211
+ "webpack": "~5.104.0",
210
212
  "webpack-dev-server": "^5.0.0"
211
213
  },
212
214
  "peerDependenciesMeta": {
@@ -1,5 +1,5 @@
1
1
  import { createBackendModule } from "@backstage/backend-plugin-api";
2
- import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha';
2
+ import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node';
3
3
  import { createExampleAction } from "./actions/example";
4
4
 
5
5
  /**