@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.
- package/CHANGELOG.md +67 -2
- package/config/jest.js +57 -29
- package/config/jestRejectNetworkRequests.js +59 -0
- package/config/nodeTransform.cjs +33 -0
- package/dist/commands/build/buildFrontend.cjs.js +8 -11
- package/dist/commands/buildWorkspace.cjs.js +1 -1
- package/dist/commands/index.cjs.js +9 -3
- package/dist/commands/repo/lint.cjs.js +15 -33
- package/dist/commands/repo/test.cjs.js +35 -33
- package/dist/commands/start/command.cjs.js +1 -0
- package/dist/commands/start/startBackend.cjs.js +23 -92
- package/dist/commands/start/startFrontend.cjs.js +6 -8
- package/dist/commands/versions/bump.cjs.js +9 -3
- package/dist/lib/bundler/config.cjs.js +20 -138
- package/dist/lib/bundler/linkWorkspaces.cjs.js +31 -0
- package/dist/lib/cache/SuccessCache.cjs.js +79 -0
- package/dist/lib/packager/createDistWorkspace.cjs.js +3 -3
- package/dist/lib/{experimental/startBackendExperimental.cjs.js → runner/runBackend.cjs.js} +6 -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 +4 -6
- package/dist/packages/core-components/package.json.cjs.js +1 -1
- package/dist/packages/dev-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 -32
- package/dist/lib/bundler/LinkedPackageResolvePlugin.cjs.js +0 -47
- package/dist/lib/bundler/backend.cjs.js +0 -36
- /package/dist/lib/{experimental → ipc}/IpcServer.cjs.js +0 -0
- /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
|
-
|
|
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
|
|
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(
|
|
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 (
|
|
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
|
|
277
|
+
await cache.write(outputSuccessCache);
|
|
276
278
|
}
|
|
277
279
|
};
|
|
278
280
|
}
|
|
@@ -2,109 +2,40 @@
|
|
|
2
2
|
|
|
3
3
|
var fs = require('fs-extra');
|
|
4
4
|
var paths = require('../../lib/paths.cjs.js');
|
|
5
|
-
var
|
|
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
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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
|
-
|
|
27
|
+
`The 'dev' directory is missing. Please create a proper dev/index.ts in order to start the plugin.`
|
|
94
28
|
);
|
|
95
|
-
|
|
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
|
-
|
|
106
|
-
|
|
107
|
-
|
|
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('
|
|
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('
|
|
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(
|
|
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
|
-
|
|
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
|
|
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
|
|
119
|
+
typescript: { configFile: paths.targetTsConfig, memoryLimit: 4096 }
|
|
128
120
|
}),
|
|
129
121
|
new ESLintPlugin__default.default({
|
|
130
|
-
context: paths
|
|
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
|
|
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:
|
|
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
|
|
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
|
|
300
|
+
context: paths.targetPath,
|
|
301
301
|
entry: [
|
|
302
302
|
require.resolve("@backstage/cli/config/webpack-public-path"),
|
|
303
303
|
...options.additionalEntryPoints ?? [],
|
|
304
|
-
paths
|
|
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
|
|
331
|
-
[paths
|
|
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
|
|
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
|