@backstage/cli 0.35.4-next.2 → 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.
- package/CHANGELOG.md +26 -0
- package/dist/modules/build/commands/package/build/command.cjs.js +9 -1
- package/dist/modules/build/commands/package/start/startFrontend.cjs.js +3 -4
- package/dist/modules/build/index.cjs.js +6 -0
- package/dist/modules/build/lib/buildFrontend.cjs.js +3 -4
- package/dist/modules/build/lib/bundler/bundle.cjs.js +9 -2
- package/dist/modules/build/lib/bundler/config.cjs.js +19 -76
- package/dist/modules/build/lib/bundler/moduleFederation.cjs.js +98 -15
- package/dist/modules/build/lib/bundler/server.cjs.js +15 -5
- package/dist/packages/backend-defaults/package.json.cjs.js +1 -1
- package/dist/packages/backend-plugin-api/package.json.cjs.js +1 -1
- package/dist/packages/backend-test-utils/package.json.cjs.js +1 -1
- package/dist/packages/catalog-client/package.json.cjs.js +1 -1
- package/dist/packages/cli/package.json.cjs.js +3 -2
- package/dist/packages/core-app-api/package.json.cjs.js +1 -1
- package/dist/packages/core-components/package.json.cjs.js +1 -1
- package/dist/packages/core-plugin-api/package.json.cjs.js +1 -1
- package/dist/packages/dev-utils/package.json.cjs.js +1 -1
- package/dist/packages/frontend-defaults/package.json.cjs.js +1 -1
- package/dist/packages/frontend-plugin-api/package.json.cjs.js +1 -1
- package/dist/packages/frontend-test-utils/package.json.cjs.js +1 -1
- package/dist/packages/test-utils/package.json.cjs.js +1 -1
- package/dist/packages/theme/package.json.cjs.js +1 -1
- package/dist/plugins/auth-backend/package.json.cjs.js +1 -1
- package/dist/plugins/auth-backend-module-guest-provider/package.json.cjs.js +1 -1
- package/dist/plugins/catalog-node/package.json.cjs.js +1 -1
- package/dist/plugins/scaffolder-node/package.json.cjs.js +1 -1
- package/dist/plugins/scaffolder-node-test-utils/package.json.cjs.js +1 -1
- package/package.json +30 -29
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
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
|
+
|
|
3
29
|
## 0.35.4-next.2
|
|
4
30
|
|
|
5
31
|
### Patch Changes
|
|
@@ -41,17 +41,25 @@ async function command(opts) {
|
|
|
41
41
|
minify: Boolean(opts.minify)
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
|
+
let isModuleFederationRemote = void 0;
|
|
44
45
|
if (role$1 === "frontend-dynamic-container") {
|
|
45
46
|
console.log(
|
|
46
47
|
chalk__default.default.yellow(
|
|
47
48
|
`\u26A0\uFE0F WARNING: The 'frontend-dynamic-container' package role is experimental and will receive immediate breaking changes in the future.`
|
|
48
49
|
)
|
|
49
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");
|
|
50
58
|
return buildFrontend.buildFrontend({
|
|
51
59
|
targetDir: paths.paths.targetDir,
|
|
52
60
|
configPaths: [],
|
|
53
61
|
writeStats: Boolean(opts.stats),
|
|
54
|
-
isModuleFederationRemote
|
|
62
|
+
isModuleFederationRemote,
|
|
55
63
|
webpack
|
|
56
64
|
});
|
|
57
65
|
}
|
|
@@ -39,11 +39,10 @@ async function startFrontend(options) {
|
|
|
39
39
|
verifyVersions: options.verifyVersions,
|
|
40
40
|
skipOpenBrowser: options.skipOpenBrowser,
|
|
41
41
|
linkedWorkspace: options.linkedWorkspace,
|
|
42
|
-
|
|
42
|
+
moduleFederationRemote: options.isModuleFederationRemote ? await moduleFederation.getModuleFederationRemoteOptions(
|
|
43
43
|
packageJson,
|
|
44
|
-
path.resolve(paths.paths.targetDir)
|
|
45
|
-
|
|
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
|
-
|
|
40
|
+
moduleFederationRemote: options.isModuleFederationRemote ? await moduleFederation.getModuleFederationRemoteOptions(
|
|
41
41
|
packageJson,
|
|
42
|
-
path.resolve(targetDir)
|
|
43
|
-
|
|
44
|
-
),
|
|
42
|
+
path.resolve(targetDir)
|
|
43
|
+
) : void 0,
|
|
45
44
|
...await config.loadCliConfig({
|
|
46
45
|
args: configPaths,
|
|
47
46
|
fromPackage: packageJson.name
|
|
@@ -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.
|
|
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:
|
|
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,
|
|
31
|
+
function resolveBaseUrl(config, moduleFederationRemote) {
|
|
32
32
|
const baseUrl = config.getOptionalString("app.baseUrl");
|
|
33
|
-
const defaultBaseUrl =
|
|
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,
|
|
41
|
-
const url = resolveBaseUrl(config,
|
|
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
|
-
|
|
80
|
+
moduleFederationRemote,
|
|
81
81
|
publicSubPath = "",
|
|
82
82
|
webpack
|
|
83
83
|
} = options;
|
|
84
84
|
const { plugins, loaders } = transforms.transforms(options);
|
|
85
|
-
const validBaseUrl = resolveBaseUrl(frontendConfig,
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
171
|
-
Object.entries(options.
|
|
172
|
-
k,
|
|
173
|
-
|
|
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
|
-
|
|
181
|
-
|
|
182
|
-
|
|
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.
|
|
283
|
+
uniqueName: options.moduleFederationRemote?.name,
|
|
341
284
|
path: paths.targetDist,
|
|
342
|
-
publicPath: options.
|
|
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
|
|
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
|
|
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 (
|
|
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.
|
|
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.
|
|
82
|
+
const url = config$1.resolveBaseUrl(frontendConfig, options.moduleFederationRemote);
|
|
82
83
|
const { host, port } = config$1.resolveEndpoint(
|
|
83
84
|
frontendConfig,
|
|
84
|
-
options.
|
|
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:
|
|
108
|
-
|
|
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.
|
|
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,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var version = "0.35.4
|
|
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.
|
|
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",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/cli",
|
|
3
|
-
"version": "0.35.4
|
|
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
|
|
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/
|
|
59
|
-
"@backstage/
|
|
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.
|
|
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",
|
|
@@ -147,22 +148,22 @@
|
|
|
147
148
|
"zod-validation-error": "^4.0.2"
|
|
148
149
|
},
|
|
149
150
|
"devDependencies": {
|
|
150
|
-
"@backstage/backend-plugin-api": "1.7.0
|
|
151
|
-
"@backstage/backend-test-utils": "1.11.0
|
|
152
|
-
"@backstage/catalog-client": "1.
|
|
153
|
-
"@backstage/config": "1.3.6",
|
|
154
|
-
"@backstage/core-app-api": "1.19.5
|
|
155
|
-
"@backstage/core-components": "0.18.7
|
|
156
|
-
"@backstage/core-plugin-api": "1.12.3
|
|
157
|
-
"@backstage/dev-utils": "1.1.20
|
|
158
|
-
"@backstage/errors": "1.2.7",
|
|
159
|
-
"@backstage/plugin-auth-backend": "0.27.0
|
|
160
|
-
"@backstage/plugin-auth-backend-module-guest-provider": "0.2.16
|
|
161
|
-
"@backstage/plugin-catalog-node": "2.0.0
|
|
162
|
-
"@backstage/plugin-scaffolder-node": "0.12.5
|
|
163
|
-
"@backstage/plugin-scaffolder-node-test-utils": "0.3.8
|
|
164
|
-
"@backstage/test-utils": "1.7.15
|
|
165
|
-
"@backstage/theme": "0.7.2
|
|
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",
|
|
166
167
|
"@jest/environment-jsdom-abstract": "^30.0.0",
|
|
167
168
|
"@pmmmwh/react-refresh-webpack-plugin": "^0.6.0",
|
|
168
169
|
"@types/cross-spawn": "^6.0.2",
|
|
@@ -197,7 +198,7 @@
|
|
|
197
198
|
},
|
|
198
199
|
"peerDependencies": {
|
|
199
200
|
"@jest/environment-jsdom-abstract": "^30.0.0",
|
|
200
|
-
"@module-federation/enhanced": "^0.
|
|
201
|
+
"@module-federation/enhanced": "^0.21.6",
|
|
201
202
|
"@pmmmwh/react-refresh-webpack-plugin": "^0.6.0",
|
|
202
203
|
"esbuild-loader": "^4.0.0",
|
|
203
204
|
"eslint-webpack-plugin": "^4.2.0",
|