@backstage/cli 0.28.1 → 0.29.0-next.1

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 (37) hide show
  1. package/CHANGELOG.md +67 -2
  2. package/config/jest.js +57 -29
  3. package/config/jestRejectNetworkRequests.js +59 -0
  4. package/config/nodeTransform.cjs +33 -0
  5. package/dist/commands/build/buildFrontend.cjs.js +8 -11
  6. package/dist/commands/buildWorkspace.cjs.js +1 -1
  7. package/dist/commands/index.cjs.js +9 -3
  8. package/dist/commands/repo/lint.cjs.js +15 -33
  9. package/dist/commands/repo/test.cjs.js +35 -33
  10. package/dist/commands/start/command.cjs.js +1 -0
  11. package/dist/commands/start/startBackend.cjs.js +23 -92
  12. package/dist/commands/start/startFrontend.cjs.js +6 -8
  13. package/dist/commands/versions/bump.cjs.js +9 -3
  14. package/dist/lib/bundler/config.cjs.js +20 -138
  15. package/dist/lib/bundler/linkWorkspaces.cjs.js +31 -0
  16. package/dist/lib/cache/SuccessCache.cjs.js +79 -0
  17. package/dist/lib/packager/createDistWorkspace.cjs.js +3 -3
  18. package/dist/lib/{experimental/startBackendExperimental.cjs.js → runner/runBackend.cjs.js} +6 -5
  19. package/dist/packages/backend-defaults/package.json.cjs.js +1 -1
  20. package/dist/packages/backend-plugin-api/package.json.cjs.js +1 -1
  21. package/dist/packages/backend-test-utils/package.json.cjs.js +1 -1
  22. package/dist/packages/catalog-client/package.json.cjs.js +1 -1
  23. package/dist/packages/cli/package.json.cjs.js +4 -6
  24. package/dist/packages/core-components/package.json.cjs.js +1 -1
  25. package/dist/packages/dev-utils/package.json.cjs.js +1 -1
  26. package/dist/packages/test-utils/package.json.cjs.js +1 -1
  27. package/dist/packages/theme/package.json.cjs.js +1 -1
  28. package/dist/plugins/auth-backend/package.json.cjs.js +1 -1
  29. package/dist/plugins/auth-backend-module-guest-provider/package.json.cjs.js +1 -1
  30. package/dist/plugins/catalog-node/package.json.cjs.js +1 -1
  31. package/dist/plugins/scaffolder-node/package.json.cjs.js +1 -1
  32. package/dist/plugins/scaffolder-node-test-utils/package.json.cjs.js +1 -1
  33. package/package.json +30 -32
  34. package/dist/lib/bundler/LinkedPackageResolvePlugin.cjs.js +0 -47
  35. package/dist/lib/bundler/backend.cjs.js +0 -36
  36. /package/dist/lib/{experimental → ipc}/IpcServer.cjs.js +0 -0
  37. /package/dist/lib/{experimental → ipc}/ServerDataStore.cjs.js +0 -0
@@ -2,40 +2,21 @@
2
2
 
3
3
  var os = require('os');
4
4
  var crypto = require('node:crypto');
5
- var fs = require('fs-extra');
6
5
  var yargs = require('yargs');
6
+ var jestCli = require('jest-cli');
7
7
  var path = require('path');
8
8
  var cliNode = require('@backstage/cli-node');
9
9
  var paths = require('../../lib/paths.cjs.js');
10
10
  var run = require('../../lib/run.cjs.js');
11
11
  var cliCommon = require('@backstage/cli-common');
12
+ var SuccessCache = require('../../lib/cache/SuccessCache.cjs.js');
12
13
 
13
14
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
14
15
 
15
16
  var os__default = /*#__PURE__*/_interopDefaultCompat(os);
16
17
  var crypto__default = /*#__PURE__*/_interopDefaultCompat(crypto);
17
- var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
18
18
  var yargs__default = /*#__PURE__*/_interopDefaultCompat(yargs);
19
19
 
20
- const CACHE_FILE_NAME = "test-cache.json";
21
- async function readCache(dir) {
22
- try {
23
- const data = await fs__default.default.readJson(path.resolve(dir, CACHE_FILE_NAME));
24
- if (!Array.isArray(data)) {
25
- return void 0;
26
- }
27
- if (data.some((x) => typeof x !== "string")) {
28
- return void 0;
29
- }
30
- return data;
31
- } catch {
32
- return void 0;
33
- }
34
- }
35
- function writeCache(dir, cache) {
36
- fs__default.default.mkdirpSync(dir);
37
- fs__default.default.writeJsonSync(path.resolve(dir, CACHE_FILE_NAME), cache, { spaces: 2 });
38
- }
39
20
  async function readPackageTreeHashes(graph) {
40
21
  const pkgs = Array.from(graph.values()).map((pkg) => ({
41
22
  ...pkg,
@@ -110,6 +91,7 @@ function removeOptionArg(args, option, size = 2) {
110
91
  } while (changed);
111
92
  }
112
93
  async function command(opts, cmd) {
94
+ const testGlobal = global;
113
95
  let parent = cmd;
114
96
  while (parent.parent) {
115
97
  parent = parent.parent;
@@ -117,21 +99,44 @@ async function command(opts, cmd) {
117
99
  const allArgs = parent.args;
118
100
  const args = allArgs.slice(allArgs.indexOf("test") + 1);
119
101
  const hasFlags = createFlagFinder(args);
102
+ const { _: parsedArgs } = await yargs__default.default(args).options(jestCli.yargsOptions).argv;
120
103
  if (!hasFlags("-c", "--config")) {
121
104
  args.push("--config", paths.paths.resolveOwn("config/jest.js"));
122
105
  }
123
106
  if (!hasFlags("--passWithNoTests")) {
124
107
  args.push("--passWithNoTests");
125
108
  }
109
+ let isSingleWatchMode = args.includes("--watch");
126
110
  if (!opts.since && !process.env.CI && !hasFlags("--coverage", "--watch", "--watchAll")) {
127
111
  const isGitRepo = () => run.runCheck("git", "rev-parse", "--is-inside-work-tree");
128
112
  const isMercurialRepo = () => run.runCheck("hg", "--cwd", ".", "root");
129
113
  if (await isGitRepo() || await isMercurialRepo()) {
114
+ isSingleWatchMode = true;
130
115
  args.push("--watch");
131
116
  } else {
132
117
  args.push("--watchAll");
133
118
  }
134
119
  }
120
+ if (isSingleWatchMode && parsedArgs.length > 0) {
121
+ testGlobal.__backstageCli_watchProjectFilter = {
122
+ async filter(projectConfigs) {
123
+ const selectedProjects2 = [];
124
+ const usedArgs = /* @__PURE__ */ new Set();
125
+ for (const project of projectConfigs) {
126
+ for (const arg of parsedArgs) {
127
+ if (cliCommon.isChildPath(project.rootDir, String(arg))) {
128
+ selectedProjects2.push(project);
129
+ usedArgs.add(arg);
130
+ }
131
+ }
132
+ }
133
+ if (usedArgs.size !== parsedArgs.length) {
134
+ return projectConfigs;
135
+ }
136
+ return selectedProjects2;
137
+ }
138
+ };
139
+ }
135
140
  if (!hasFlags("--workerIdleMemoryLimit")) {
136
141
  args.push("--workerIdleMemoryLimit=1000M");
137
142
  }
@@ -180,14 +185,9 @@ async function command(opts, cmd) {
180
185
  args.push("--help");
181
186
  process.stdout._handle.setBlocking(true);
182
187
  }
183
- const jestCli = require("jest-cli");
184
188
  if (opts.successCache) {
185
189
  removeOptionArg(args, "--successCache", 1);
186
190
  removeOptionArg(args, "--successCacheDir");
187
- const cacheDir = path.resolve(
188
- opts.successCacheDir ?? "node_modules/.cache/backstage-cli"
189
- );
190
- const { _: parsedArgs } = await yargs__default.default(args).options(jestCli.yargsOptions).argv;
191
191
  if (parsedArgs.length > 0) {
192
192
  throw new Error(
193
193
  `The --successCache flag can not be combined with the following arguments: ${parsedArgs.join(
@@ -200,14 +200,14 @@ async function command(opts, cmd) {
200
200
  `The --successCache flag can not be combined with the --shard flag`
201
201
  );
202
202
  }
203
+ const cache = new SuccessCache.SuccessCache("test", opts.successCacheDir);
203
204
  const graph = await getPackageGraph();
204
205
  const projectHashes = /* @__PURE__ */ new Map();
205
206
  const outputSuccessCache = new Array();
206
- const globalWithCache = global;
207
- globalWithCache.__backstageCli_jestSuccessCache = {
207
+ testGlobal.__backstageCli_jestSuccessCache = {
208
208
  // This is called by `config/jest.js` after the project configs have been gathered
209
209
  async filterConfigs(projectConfigs, globalRootConfig) {
210
- const cache = await readCache(cacheDir);
210
+ const cacheEntries = await cache.read();
211
211
  const lockfile = await cliNode.Lockfile.load(
212
212
  paths.paths.resolveTargetRoot("yarn.lock")
213
213
  );
@@ -217,7 +217,9 @@ async function command(opts, cmd) {
217
217
  baseHash.update("\0");
218
218
  baseHash.update(process.version);
219
219
  baseHash.update("\0");
220
- baseHash.update(JSON.stringify(globalRootConfig));
220
+ baseHash.update(
221
+ SuccessCache.SuccessCache.trimPaths(JSON.stringify(globalRootConfig))
222
+ );
221
223
  const baseSha = baseHash.digest("hex");
222
224
  return projectConfigs.filter((project) => {
223
225
  const packageName = project.displayName;
@@ -235,11 +237,11 @@ async function command(opts, cmd) {
235
237
  const depHash = getPackageTreeHash(depPkg.name);
236
238
  hash.update(`${depName}:${depHash}`);
237
239
  }
238
- hash.update(JSON.stringify(project));
240
+ hash.update(SuccessCache.SuccessCache.trimPaths(JSON.stringify(project)));
239
241
  hash.update(lockfile.getDependencyTreeHash(packageName));
240
242
  const sha = hash.digest("hex");
241
243
  projectHashes.set(packageName, sha);
242
- if (cache?.includes(sha)) {
244
+ if (cacheEntries.has(sha)) {
243
245
  if (!selectedProjects || selectedProjects.includes(packageName)) {
244
246
  console.log(`Skipped ${packageName} due to cache hit`);
245
247
  }
@@ -272,7 +274,7 @@ async function command(opts, cmd) {
272
274
  outputSuccessCache.push(sha);
273
275
  }
274
276
  }
275
- await writeCache(cacheDir, outputSuccessCache);
277
+ await cache.write(outputSuccessCache);
276
278
  }
277
279
  };
278
280
  }
@@ -9,6 +9,7 @@ async function command(opts) {
9
9
  const options = {
10
10
  configPaths: opts.config,
11
11
  checksEnabled: Boolean(opts.check),
12
+ linkedWorkspace: opts.link,
12
13
  inspectEnabled: opts.inspect,
13
14
  inspectBrkEnabled: opts.inspectBrk,
14
15
  require: opts.require
@@ -2,109 +2,40 @@
2
2
 
3
3
  var fs = require('fs-extra');
4
4
  var paths = require('../../lib/paths.cjs.js');
5
- var backend = require('../../lib/bundler/backend.cjs.js');
6
- require('yn');
7
- require('path');
8
- require('webpack');
9
- require('react-dev-utils/FileSizeReporter');
10
- require('react-dev-utils/formatWebpackMessages');
11
- require('chalk');
12
- require('eslint-webpack-plugin');
13
- require('fork-ts-checker-webpack-plugin');
14
- require('html-webpack-plugin');
15
- require('@module-federation/enhanced/webpack');
16
- require('@backstage/cli-common');
17
- require('react-dev-utils/ModuleScopePlugin');
18
- require('run-script-webpack-plugin');
19
- require('@pmmmwh/react-refresh-webpack-plugin');
20
- require('@manypkg/get-packages');
21
- require('webpack-node-externals');
22
- require('../../lib/bundler/optimization.cjs.js');
23
- require('lodash/pickBy');
24
- require('../../lib/run.cjs.js');
25
- require('mini-css-extract-plugin');
26
- require('../../lib/version.cjs.js');
27
- require('../../lib/bundler/packageDetection.cjs.js');
28
- require('react-dev-utils/openBrowser');
29
- require('webpack-dev-server');
30
- require('@backstage/config-loader');
31
- require('@backstage/config');
32
- require('@backstage/cli-node');
33
- var startBackendExperimental = require('../../lib/experimental/startBackendExperimental.cjs.js');
5
+ var runBackend = require('../../lib/runner/runBackend.cjs.js');
34
6
 
35
7
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
36
8
 
37
9
  var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
38
10
 
39
11
  async function startBackend(options) {
40
- if (!process.env.LEGACY_BACKEND_START) {
41
- const waitForExit = await startBackendExperimental.startBackendExperimental({
42
- entry: "src/index",
43
- checksEnabled: false,
44
- // not supported
45
- inspectEnabled: options.inspectEnabled,
46
- inspectBrkEnabled: options.inspectBrkEnabled,
47
- require: options.require
48
- });
49
- await waitForExit();
50
- } else {
51
- console.warn(
52
- "LEGACY_BACKEND_START is deprecated and will be removed in a future release"
53
- );
54
- const waitForExit = await cleanDistAndServeBackend({
55
- entry: "src/index",
56
- checksEnabled: options.checksEnabled,
57
- inspectEnabled: options.inspectEnabled,
58
- inspectBrkEnabled: options.inspectBrkEnabled,
59
- require: options.require
60
- });
61
- await waitForExit();
62
- }
12
+ const waitForExit = await runBackend.runBackend({
13
+ entry: "src/index",
14
+ inspectEnabled: options.inspectEnabled,
15
+ inspectBrkEnabled: options.inspectBrkEnabled,
16
+ linkedWorkspace: options.linkedWorkspace,
17
+ require: options.require
18
+ });
19
+ await waitForExit();
63
20
  }
64
21
  async function startBackendPlugin(options) {
65
- if (!process.env.LEGACY_BACKEND_START) {
66
- const hasDevIndexEntry = await fs__default.default.pathExists(
67
- paths.paths.resolveTarget("dev", "index.ts")
68
- );
69
- if (!hasDevIndexEntry) {
70
- console.warn(
71
- `The 'dev' directory is missing. Please create a proper dev/index.ts in order to start the plugin.`
72
- );
73
- return;
74
- }
75
- const waitForExit = await startBackendExperimental.startBackendExperimental({
76
- entry: "dev/index",
77
- checksEnabled: false,
78
- // not supported
79
- inspectEnabled: options.inspectEnabled,
80
- inspectBrkEnabled: options.inspectBrkEnabled,
81
- require: options.require
82
- });
83
- await waitForExit();
84
- } else {
85
- const hasEntry = await fs__default.default.pathExists(paths.paths.resolveTarget("src", "run.ts"));
86
- if (!hasEntry) {
87
- console.warn(
88
- `src/run.ts is missing. Please create the file or run the command without LEGACY_BACKEND_START`
89
- );
90
- return;
91
- }
22
+ const hasDevIndexEntry = await fs__default.default.pathExists(
23
+ paths.paths.resolveTarget("dev", "index.ts")
24
+ );
25
+ if (!hasDevIndexEntry) {
92
26
  console.warn(
93
- "LEGACY_BACKEND_START is deprecated and will be removed in a future release"
27
+ `The 'dev' directory is missing. Please create a proper dev/index.ts in order to start the plugin.`
94
28
  );
95
- const waitForExit = await cleanDistAndServeBackend({
96
- entry: "src/run",
97
- checksEnabled: options.checksEnabled,
98
- inspectEnabled: options.inspectEnabled,
99
- inspectBrkEnabled: options.inspectBrkEnabled,
100
- require: options.require
101
- });
102
- await waitForExit();
29
+ return;
103
30
  }
104
- }
105
- async function cleanDistAndServeBackend(options) {
106
- await fs__default.default.remove(paths.paths.resolveTarget("dist"));
107
- return backend.serveBackend(options);
31
+ const waitForExit = await runBackend.runBackend({
32
+ entry: "dev/index",
33
+ inspectEnabled: options.inspectEnabled,
34
+ inspectBrkEnabled: options.inspectBrkEnabled,
35
+ require: options.require,
36
+ linkedWorkspace: options.linkedWorkspace
37
+ });
38
+ await waitForExit();
108
39
  }
109
40
 
110
41
  exports.startBackend = startBackend;
@@ -1,28 +1,25 @@
1
1
  'use strict';
2
2
 
3
3
  var fs = require('fs-extra');
4
- require('webpack');
4
+ require('yn');
5
5
  require('path');
6
+ require('webpack');
7
+ require('react-dev-utils/FileSizeReporter');
8
+ require('react-dev-utils/formatWebpackMessages');
6
9
  require('chalk');
7
10
  require('eslint-webpack-plugin');
8
11
  require('fork-ts-checker-webpack-plugin');
9
12
  require('html-webpack-plugin');
10
13
  require('@module-federation/enhanced/webpack');
11
- require('@backstage/cli-common');
12
14
  require('react-dev-utils/ModuleScopePlugin');
13
- require('run-script-webpack-plugin');
14
15
  require('@pmmmwh/react-refresh-webpack-plugin');
15
16
  var paths = require('../../lib/paths.cjs.js');
16
- require('@manypkg/get-packages');
17
- require('webpack-node-externals');
18
17
  require('../../lib/bundler/optimization.cjs.js');
19
18
  require('lodash/pickBy');
20
19
  require('../../lib/run.cjs.js');
21
20
  require('mini-css-extract-plugin');
22
21
  require('../../lib/version.cjs.js');
23
- require('yn');
24
- require('react-dev-utils/FileSizeReporter');
25
- require('react-dev-utils/formatWebpackMessages');
22
+ require('@manypkg/get-packages');
26
23
  require('../../lib/bundler/packageDetection.cjs.js');
27
24
  var moduleFederation = require('../../lib/bundler/moduleFederation.cjs.js');
28
25
  var server = require('../../lib/bundler/server.cjs.js');
@@ -35,6 +32,7 @@ async function startFrontend(options) {
35
32
  configPaths: options.configPaths,
36
33
  verifyVersions: options.verifyVersions,
37
34
  skipOpenBrowser: options.skipOpenBrowser,
35
+ linkedWorkspace: options.linkedWorkspace,
38
36
  moduleFederation: moduleFederation.getModuleFederationOptions(
39
37
  name,
40
38
  options.isModuleFederationRemote
@@ -160,7 +160,10 @@ var bump = async (opts) => {
160
160
  });
161
161
  console.log();
162
162
  if (pattern === DEFAULT_PATTERN_GLOB) {
163
- await bumpBackstageJsonVersion(releaseManifest.releaseVersion);
163
+ await bumpBackstageJsonVersion(
164
+ releaseManifest.releaseVersion,
165
+ hasYarnPlugin
166
+ );
164
167
  } else {
165
168
  console.log(
166
169
  chalk__default.default.yellow(
@@ -306,7 +309,7 @@ async function getBackstageJson() {
306
309
  throw e;
307
310
  });
308
311
  }
309
- async function bumpBackstageJsonVersion(version) {
312
+ async function bumpBackstageJsonVersion(version, useYarnPlugin) {
310
313
  const backstageJson = await getBackstageJson();
311
314
  const prevVersion = backstageJson?.version;
312
315
  if (prevVersion === version) {
@@ -316,7 +319,10 @@ async function bumpBackstageJsonVersion(version) {
316
319
  if (prevVersion) {
317
320
  const from = encodeURIComponent(prevVersion);
318
321
  const to = encodeURIComponent(version);
319
- const link = `https://backstage.github.io/upgrade-helper/?from=${from}&to=${to}`;
322
+ let link = `https://backstage.github.io/upgrade-helper/?from=${from}&to=${to}`;
323
+ if (useYarnPlugin) {
324
+ link += "&yarnPlugin=1";
325
+ }
320
326
  console.log(
321
327
  yellow(
322
328
  `Upgraded from release ${green(prevVersion)} to ${green(
@@ -7,23 +7,18 @@ var ESLintPlugin = require('eslint-webpack-plugin');
7
7
  var ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
8
8
  var HtmlWebpackPlugin = require('html-webpack-plugin');
9
9
  var webpack = require('@module-federation/enhanced/webpack');
10
- var LinkedPackageResolvePlugin = require('./LinkedPackageResolvePlugin.cjs.js');
11
10
  var ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
12
- var runScriptWebpackPlugin = require('run-script-webpack-plugin');
13
11
  var ReactRefreshPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
14
12
  var paths = require('../paths.cjs.js');
15
13
  var fs = require('fs-extra');
16
- var getPackages = require('@manypkg/get-packages');
17
- var cliCommon = require('@backstage/cli-common');
18
- var nodeExternals = require('webpack-node-externals');
19
14
  var optimization = require('./optimization.cjs.js');
20
15
  var pickBy = require('lodash/pickBy');
21
- var entryPoints = require('../entryPoints.cjs.js');
22
16
  var run = require('../run.cjs.js');
23
17
  var transforms = require('./transforms.cjs.js');
24
18
  var version = require('../version.cjs.js');
25
19
  var yn = require('yn');
26
20
  var hasReactDomClient = require('./hasReactDomClient.cjs.js');
21
+ var linkWorkspaces = require('./linkWorkspaces.cjs.js');
27
22
 
28
23
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
29
24
 
@@ -35,7 +30,6 @@ var HtmlWebpackPlugin__default = /*#__PURE__*/_interopDefaultCompat(HtmlWebpackP
35
30
  var ModuleScopePlugin__default = /*#__PURE__*/_interopDefaultCompat(ModuleScopePlugin);
36
31
  var ReactRefreshPlugin__default = /*#__PURE__*/_interopDefaultCompat(ReactRefreshPlugin);
37
32
  var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
38
- var nodeExternals__default = /*#__PURE__*/_interopDefaultCompat(nodeExternals);
39
33
  var pickBy__default = /*#__PURE__*/_interopDefaultCompat(pickBy);
40
34
  var yn__default = /*#__PURE__*/_interopDefaultCompat(yn);
41
35
 
@@ -84,7 +78,7 @@ async function readBuildInfo() {
84
78
  commit: commit ?? "unknown"
85
79
  };
86
80
  }
87
- async function createConfig(paths$1, options) {
81
+ async function createConfig(paths, options) {
88
82
  const {
89
83
  checksEnabled,
90
84
  isDev,
@@ -94,8 +88,6 @@ async function createConfig(paths$1, options) {
94
88
  rspack
95
89
  } = options;
96
90
  const { plugins, loaders } = transforms.transforms(options);
97
- const { packages } = await getPackages.getPackages(paths.paths.targetDir);
98
- const externalPkgs = packages.filter((p) => !cliCommon.isChildPath(paths$1.root, p.dir));
99
91
  const validBaseUrl = resolveBaseUrl(frontendConfig, moduleFederation);
100
92
  let publicPath = validBaseUrl.pathname.replace(/\/$/, "");
101
93
  if (publicSubPath) {
@@ -124,10 +116,10 @@ async function createConfig(paths$1, options) {
124
116
  if (checksEnabled) {
125
117
  plugins.push(
126
118
  new ForkTsCheckerWebpackPlugin__default.default({
127
- typescript: { configFile: paths$1.targetTsConfig, memoryLimit: 4096 }
119
+ typescript: { configFile: paths.targetTsConfig, memoryLimit: 4096 }
128
120
  }),
129
121
  new ESLintPlugin__default.default({
130
- context: paths$1.targetPath,
122
+ context: paths.targetPath,
131
123
  files: ["**/*.(ts|tsx|mts|cts|js|jsx|mjs|cjs)"]
132
124
  })
133
125
  );
@@ -146,7 +138,7 @@ async function createConfig(paths$1, options) {
146
138
  meta: {
147
139
  "backstage-app-mode": options?.appMode ?? "public"
148
140
  },
149
- template: paths$1.targetHtml,
141
+ template: paths.targetHtml,
150
142
  templateParameters: {
151
143
  publicPath,
152
144
  config: frontendConfig
@@ -163,7 +155,7 @@ async function createConfig(paths$1, options) {
163
155
  minify: false,
164
156
  publicPath: "<%= publicPath %>",
165
157
  filename: "index.html.tmpl",
166
- template: `raw-loader!${paths$1.targetHtml}`
158
+ template: `${require.resolve("raw-loader")}!${paths.targetHtml}`
167
159
  })
168
160
  );
169
161
  }
@@ -175,7 +167,7 @@ async function createConfig(paths$1, options) {
175
167
  ...isRemote && {
176
168
  filename: "remoteEntry.js",
177
169
  exposes: {
178
- ".": paths$1.targetEntry
170
+ ".": paths.targetEntry
179
171
  }
180
172
  },
181
173
  name: options.moduleFederation.name,
@@ -245,6 +237,14 @@ async function createConfig(paths$1, options) {
245
237
  "process.env.HAS_REACT_DOM_CLIENT": JSON.stringify(hasReactDomClient.hasReactDomClient())
246
238
  })
247
239
  );
240
+ if (options.linkedWorkspace) {
241
+ plugins.push(
242
+ ...await linkWorkspaces.createWorkspaceLinkingPlugins(
243
+ bundler,
244
+ options.linkedWorkspace
245
+ )
246
+ );
247
+ }
248
248
  const reactRefreshFiles = rspack ? [] : [
249
249
  require.resolve(
250
250
  "@pmmmwh/react-refresh-webpack-plugin/lib/runtime/RefreshUtils.js"
@@ -297,11 +297,11 @@ async function createConfig(paths$1, options) {
297
297
  // we check the gzip size instead
298
298
  },
299
299
  devtool: isDev ? "eval-cheap-module-source-map" : "source-map",
300
- context: paths$1.targetPath,
300
+ context: paths.targetPath,
301
301
  entry: [
302
302
  require.resolve("@backstage/cli/config/webpack-public-path"),
303
303
  ...options.additionalEntryPoints ?? [],
304
- paths$1.targetEntry
304
+ paths.targetEntry
305
305
  ],
306
306
  resolve: {
307
307
  extensions: [".ts", ".tsx", ".mjs", ".js", ".jsx", ".json", ".wasm"],
@@ -325,10 +325,9 @@ async function createConfig(paths$1, options) {
325
325
  // FIXME: see also https://github.com/web-infra-dev/rspack/issues/3408
326
326
  ...!rspack && {
327
327
  plugins: [
328
- new LinkedPackageResolvePlugin.LinkedPackageResolvePlugin(paths$1.rootNodeModules, externalPkgs),
329
328
  new ModuleScopePlugin__default.default(
330
- [paths$1.targetSrc, paths$1.targetDev],
331
- [paths$1.targetPackageJson, ...reactRefreshFiles]
329
+ [paths.targetSrc, paths.targetDev],
330
+ [paths.targetPackageJson, ...reactRefreshFiles]
332
331
  )
333
332
  ]
334
333
  }
@@ -338,7 +337,7 @@ async function createConfig(paths$1, options) {
338
337
  },
339
338
  output: {
340
339
  uniqueName: options.moduleFederation?.name,
341
- path: paths$1.targetDist,
340
+ path: paths.targetDist,
342
341
  publicPath: options.moduleFederation?.mode === "remote" ? "auto" : `${publicPath}/`,
343
342
  filename: isDev ? "[name].js" : "static/[name].[fullhash:8].js",
344
343
  chunkFilename: isDev ? "[name].chunk.js" : "static/[name].[chunkhash:8].chunk.js",
@@ -367,124 +366,7 @@ async function createConfig(paths$1, options) {
367
366
  }
368
367
  };
369
368
  }
370
- async function createBackendConfig(paths$1, options) {
371
- const { checksEnabled, isDev } = options;
372
- const { packages } = await getPackages.getPackages(paths.paths.targetDir);
373
- const localPackageEntryPoints = packages.flatMap((p) => {
374
- const entryPoints$1 = entryPoints.readEntryPoints(p.packageJson);
375
- return entryPoints$1.map((e) => path.posix.join(p.packageJson.name, e.mount));
376
- });
377
- const moduleDirs = packages.map((p) => path.resolve(p.dir, "node_modules"));
378
- const externalPkgs = packages.filter((p) => !cliCommon.isChildPath(paths$1.root, p.dir));
379
- const { loaders } = transforms.transforms({ ...options, isBackend: true });
380
- const runScriptNodeArgs = new Array();
381
- if (options.inspectEnabled) {
382
- const inspect = typeof options.inspectEnabled === "string" ? `--inspect=${options.inspectEnabled}` : "--inspect";
383
- runScriptNodeArgs.push(inspect);
384
- } else if (options.inspectBrkEnabled) {
385
- const inspect = typeof options.inspectBrkEnabled === "string" ? `--inspect-brk=${options.inspectBrkEnabled}` : "--inspect-brk";
386
- runScriptNodeArgs.push(inspect);
387
- }
388
- if (options.require) {
389
- runScriptNodeArgs.push(`--require=${options.require}`);
390
- }
391
- return {
392
- mode: isDev ? "development" : "production",
393
- profile: false,
394
- ...isDev ? {
395
- watch: true,
396
- watchOptions: {
397
- ignored: /node_modules\/(?!\@backstage)/
398
- }
399
- } : {},
400
- externals: [
401
- nodeExternalsWithResolve({
402
- modulesDir: paths$1.rootNodeModules,
403
- additionalModuleDirs: moduleDirs,
404
- allowlist: ["webpack/hot/poll?100", ...localPackageEntryPoints]
405
- })
406
- ],
407
- target: "node",
408
- node: {
409
- /* eslint-disable-next-line no-restricted-syntax */
410
- __dirname: true,
411
- __filename: true,
412
- global: true
413
- },
414
- bail: false,
415
- performance: {
416
- hints: false
417
- // we check the gzip size instead
418
- },
419
- devtool: isDev ? "eval-cheap-module-source-map" : "source-map",
420
- context: paths$1.targetPath,
421
- entry: [
422
- "webpack/hot/poll?100",
423
- paths$1.targetRunFile ? paths$1.targetRunFile : paths$1.targetEntry
424
- ],
425
- resolve: {
426
- extensions: [".ts", ".mjs", ".js", ".json"],
427
- mainFields: ["main"],
428
- modules: [paths$1.rootNodeModules, ...moduleDirs],
429
- plugins: [
430
- new LinkedPackageResolvePlugin.LinkedPackageResolvePlugin(paths$1.rootNodeModules, externalPkgs),
431
- new ModuleScopePlugin__default.default(
432
- [paths$1.targetSrc, paths$1.targetDev],
433
- [paths$1.targetPackageJson]
434
- )
435
- ]
436
- },
437
- module: {
438
- rules: loaders
439
- },
440
- output: {
441
- path: paths$1.targetDist,
442
- filename: isDev ? "[name].js" : "[name].[hash:8].js",
443
- chunkFilename: isDev ? "[name].chunk.js" : "[name].[chunkhash:8].chunk.js",
444
- ...isDev ? {
445
- devtoolModuleFilenameTemplate: (info) => `file:///${path.resolve(info.absoluteResourcePath).replace(
446
- /\\/g,
447
- "/"
448
- )}`
449
- } : {}
450
- },
451
- plugins: [
452
- new runScriptWebpackPlugin.RunScriptWebpackPlugin({
453
- name: "main.js",
454
- nodeArgs: runScriptNodeArgs.length > 0 ? runScriptNodeArgs : void 0,
455
- args: process.argv.slice(3)
456
- // drop `node backstage-cli backend:dev`
457
- }),
458
- new webpack__default.default.HotModuleReplacementPlugin(),
459
- ...checksEnabled ? [
460
- new ForkTsCheckerWebpackPlugin__default.default({
461
- typescript: { configFile: paths$1.targetTsConfig }
462
- }),
463
- new ESLintPlugin__default.default({
464
- files: ["**/*.(ts|tsx|mts|cts|js|jsx|mjs|cjs)"]
465
- })
466
- ] : []
467
- ]
468
- };
469
- }
470
- function nodeExternalsWithResolve(options) {
471
- let currentContext;
472
- const externals = nodeExternals__default.default({
473
- ...options,
474
- importType(request) {
475
- const resolved = require.resolve(request, {
476
- paths: [currentContext]
477
- });
478
- return `commonjs ${resolved}`;
479
- }
480
- });
481
- return ({ context, request }, callback) => {
482
- currentContext = context;
483
- return externals(context, request, callback);
484
- };
485
- }
486
369
 
487
- exports.createBackendConfig = createBackendConfig;
488
370
  exports.createConfig = createConfig;
489
371
  exports.resolveBaseUrl = resolveBaseUrl;
490
372
  exports.resolveEndpoint = resolveEndpoint;
@@ -0,0 +1,31 @@
1
+ 'use strict';
2
+
3
+ var path = require('path');
4
+ var getPackages = require('@manypkg/get-packages');
5
+ var paths = require('../paths.cjs.js');
6
+
7
+ async function createWorkspaceLinkingPlugins(bundler, workspace) {
8
+ const { packages: linkedPackages, root: linkedRoot } = await getPackages.getPackages(
9
+ workspace
10
+ );
11
+ const replacementRegex = new RegExp(
12
+ `^(?:${linkedPackages.map((pkg) => pkg.packageJson.name).join("|")})(?:/.*)?$`
13
+ );
14
+ return [
15
+ // Any imports of a package that is present in the linked workspace will
16
+ // be redirected to be resolved within the context of the linked workspace
17
+ new bundler.NormalModuleReplacementPlugin(replacementRegex, (resource) => {
18
+ resource.context = linkedRoot.dir;
19
+ }),
20
+ // react and react-dom are always resolved from the target directory
21
+ // Note: this often requires that the linked and target workspace use the same versions of React
22
+ new bundler.NormalModuleReplacementPlugin(/^react(?:-dom)?$/, (resource) => {
23
+ if (!path.relative(linkedRoot.dir, resource.context).startsWith("..")) {
24
+ resource.context = paths.paths.targetDir;
25
+ }
26
+ })
27
+ ];
28
+ }
29
+
30
+ exports.createWorkspaceLinkingPlugins = createWorkspaceLinkingPlugins;
31
+ //# sourceMappingURL=linkWorkspaces.cjs.js.map