@backstage/cli 0.28.0-next.2 → 0.28.0

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 (52) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/dist/commands/build/buildFrontend.cjs.js +3 -2
  3. package/dist/commands/build/command.cjs.js +5 -2
  4. package/dist/commands/repo/lint.cjs.js +18 -6
  5. package/dist/commands/repo/test.cjs.js +8 -5
  6. package/dist/lib/bundler/bundle.cjs.js +5 -4
  7. package/dist/lib/bundler/config.cjs.js +59 -37
  8. package/dist/lib/bundler/hasReactDomClient.cjs.js +5 -1
  9. package/dist/lib/bundler/optimization.cjs.js +10 -6
  10. package/dist/lib/bundler/server.cjs.js +47 -7
  11. package/dist/lib/bundler/transforms.cjs.js +7 -6
  12. package/dist/lib/version.cjs.js +30 -22
  13. package/dist/packages/backend-defaults/package.json.cjs.js +1 -1
  14. package/dist/packages/backend-plugin-api/package.json.cjs.js +1 -1
  15. package/dist/packages/backend-test-utils/package.json.cjs.js +1 -1
  16. package/dist/packages/catalog-client/package.json.cjs.js +6 -0
  17. package/dist/packages/cli/package.json.cjs.js +14 -2
  18. package/dist/packages/core-app-api/package.json.cjs.js +1 -1
  19. package/dist/packages/core-components/package.json.cjs.js +1 -1
  20. package/dist/packages/core-plugin-api/package.json.cjs.js +1 -1
  21. package/dist/packages/dev-utils/package.json.cjs.js +1 -1
  22. package/dist/packages/errors/package.json.cjs.js +6 -0
  23. package/dist/packages/test-utils/package.json.cjs.js +1 -1
  24. package/dist/packages/theme/package.json.cjs.js +1 -1
  25. package/dist/plugins/auth-backend/package.json.cjs.js +1 -1
  26. package/dist/plugins/auth-backend-module-guest-provider/package.json.cjs.js +1 -1
  27. package/dist/plugins/catalog-node/package.json.cjs.js +6 -0
  28. package/dist/plugins/scaffolder-node/package.json.cjs.js +1 -1
  29. package/dist/plugins/scaffolder-node-test-utils/package.json.cjs.js +6 -0
  30. package/package.json +52 -24
  31. package/templates/default-backend-plugin/README.md.hbs +22 -8
  32. package/templates/default-backend-plugin/dev/index.ts.hbs +60 -0
  33. package/templates/default-backend-plugin/package.json.hbs +5 -5
  34. package/templates/default-backend-plugin/src/index.ts.hbs +0 -1
  35. package/templates/default-backend-plugin/src/plugin.test.ts.hbs +85 -0
  36. package/templates/default-backend-plugin/src/plugin.ts.hbs +16 -14
  37. package/templates/default-backend-plugin/src/router.test.ts +67 -0
  38. package/templates/default-backend-plugin/src/router.ts +51 -0
  39. package/templates/default-backend-plugin/src/services/TodoListService/createTodoListService.ts +100 -0
  40. package/templates/default-backend-plugin/src/services/TodoListService/index.ts +1 -0
  41. package/templates/default-backend-plugin/src/services/TodoListService/types.ts +27 -0
  42. package/templates/scaffolder-module/package.json.hbs +3 -1
  43. package/templates/scaffolder-module/src/actions/example.test.ts +24 -0
  44. package/templates/scaffolder-module/src/actions/{example/example.ts → example.ts} +7 -3
  45. package/templates/scaffolder-module/src/index.ts.hbs +1 -1
  46. package/templates/scaffolder-module/src/{actions/example/module.ts → module.ts} +3 -3
  47. package/templates/default-backend-plugin/dev/index.ts +0 -9
  48. package/templates/default-backend-plugin/src/service/router.test.ts +0 -30
  49. package/templates/default-backend-plugin/src/service/router.ts +0 -28
  50. package/templates/scaffolder-module/src/actions/example/example.test.ts +0 -32
  51. package/templates/scaffolder-module/src/actions/example/index.ts +0 -7
  52. package/templates/scaffolder-module/src/actions/index.ts +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,58 @@
1
1
  # @backstage/cli
2
2
 
3
+ ## 0.28.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 264058c: The `repo test` command will no longer default to watch mode if the `--since` flag is provided.
8
+ - 55b8b84: **BREAKING**: The Jest configuration defined at `@backstage/cli/config/jest` no longer collects configuration defined in the `"jest"` field from all parent `package.json` files. Instead, it will only read and merge configuration from the `package.json` in the monorepo root if it exists, as well as the target package. In addition, configuration defined in the root `package.json` will now only be merged into each package configuration if it is a valid project-level configuration key.
9
+ - 6129076: **BREAKING**: Removed the following deprecated commands:
10
+
11
+ - `create`: Use `backstage-cli new` instead
12
+ - `create-plugin`: Use `backstage-cli new` instead
13
+ - `plugin:diff`: Use `backstage-cli fix` instead
14
+ - `test`: Use `backstage-cli repo test` or `backstage-cli package test` instead
15
+ - `versions:check`: Use `yarn dedupe` or `yarn-deduplicate` instead
16
+ - `clean`: Use `backstage-cli package clean` instead
17
+
18
+ In addition, the experimental `install` and `onboard` commands have been removed since they have not received any updates since their introduction and we're expecting usage to be low. If you where relying on these commands, please let us know by opening an issue towards the main Backstage repository.
19
+
20
+ ### Patch Changes
21
+
22
+ - ea16633: Preserve directory structure for CommonJS build output, just like ESM. This makes the build output more stable and easier to browse, and allows for more effective tree shaking and lazy imports.
23
+ - 520a383: Added functionality to the prepack script that will append the default export type for entry points to the `exports` object before publishing. This is to help with identifying the declarative integration points for plugins without needing to fetch or run the plugins first.
24
+ - 9625a97: The `scaffolder-module` template has been updated to use a more modern layout and new testing utilities for scaffolder actions.
25
+ - 03810d2: Remove unknown dependency `diff`
26
+ - cebee4f: Added support for a new experimental `EXPERIMENTAL_TRIM_NEXT_ENTRY` flag which removes any `./next` entry points present in packages when building and publishing.
27
+ - 54c8aa3: The check for `react-dom/client` will now properly always run from the target directory.
28
+ - b676cc9: feat: experimentally support using rspack instead under `EXPERIMENTAL_RSPACK` env flag
29
+ - 094eaa3: Remove references to in-repo backend-common
30
+ - 95999c5: The backend plugin template for the `new` command has been updated to provide more guidance and use a more modern structure.
31
+ - 7955f9b: Tweaked the new package feature detection to not be active when building backend packages.
32
+ - 4bfc2ce: Updated the Vite implementation behind the `EXPERIMENTAL_VITE` flag to work with more recent versions of Backstage.
33
+ - 720a2f9: Updated dependency `git-url-parse` to `^15.0.0`.
34
+ - 8f0898b: Updated dependency `esbuild` to `^0.24.0`.
35
+ - 2c5ecf5: Support `--max-warnings` flag for package linting
36
+ - 88407c3: Running `repo lint` with the `--successCache` flag now respects `.gitinore`, and it ignores projects without a `lint` script.
37
+ - 8fe740d: Added a new `--successCache` option to the `backstage-cli repo test` and `backstage-cli repo lint` commands. The cache keeps track of successful runs and avoids re-running for individual packages if they haven't changed. This option is intended only to be used in CI.
38
+
39
+ In addition a `--successCacheDir <path>` option has also been added to be able to override the default cache directory.
40
+
41
+ - 55b8b84: The Jest configuration will now search for a `src/setupTests.*` file with any valid script extension, not only `.ts`.
42
+ - 79ba5a8: The `LEGACY_BACKEND_START` flag is now deprecated.
43
+ - f0514c7: Disabled parsing of input source maps in the SWC transform for Jest.
44
+ - Updated dependencies
45
+ - @backstage/cli-node@0.2.9
46
+ - @backstage/eslint-plugin@0.1.10
47
+ - @backstage/integration@1.15.1
48
+ - @backstage/catalog-model@1.7.0
49
+ - @backstage/cli-common@0.1.14
50
+ - @backstage/config@1.2.0
51
+ - @backstage/config-loader@1.9.1
52
+ - @backstage/errors@1.2.4
53
+ - @backstage/release-manifests@0.0.11
54
+ - @backstage/types@1.1.1
55
+
3
56
  ## 0.28.0-next.2
4
57
 
5
58
  ### Patch Changes
@@ -34,7 +34,7 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
34
34
  var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
35
35
 
36
36
  async function buildFrontend(options) {
37
- const { targetDir, writeStats, configPaths } = options;
37
+ const { targetDir, writeStats, configPaths, rspack } = options;
38
38
  const { name } = await fs__default.default.readJson(path.resolve(targetDir, "package.json"));
39
39
  await bundle.buildBundle({
40
40
  targetDir,
@@ -48,7 +48,8 @@ async function buildFrontend(options) {
48
48
  ...await config.loadCliConfig({
49
49
  args: configPaths,
50
50
  fromPackage: name
51
- })
51
+ }),
52
+ rspack
52
53
  });
53
54
  }
54
55
 
@@ -15,6 +15,7 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
15
15
  var chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
16
16
 
17
17
  async function command(opts) {
18
+ const rspack = process.env.EXPERIMENTAL_RSPACK ? require("@rspack/core") : void 0;
18
19
  const role$1 = await role.findRoleFromCommand(opts);
19
20
  if (role$1 === "frontend" || role$1 === "backend") {
20
21
  const configPaths = opts.config.map((arg) => {
@@ -27,7 +28,8 @@ async function command(opts) {
27
28
  return buildFrontend.buildFrontend({
28
29
  targetDir: paths.paths.targetDir,
29
30
  configPaths,
30
- writeStats: Boolean(opts.stats)
31
+ writeStats: Boolean(opts.stats),
32
+ rspack
31
33
  });
32
34
  }
33
35
  return buildBackend.buildBackend({
@@ -47,7 +49,8 @@ async function command(opts) {
47
49
  targetDir: paths.paths.targetDir,
48
50
  configPaths: [],
49
51
  writeStats: Boolean(opts.stats),
50
- isModuleFederationRemote: true
52
+ isModuleFederationRemote: true,
53
+ rspack
51
54
  });
52
55
  }
53
56
  const roleInfo = cliNode.PackageRoles.getRoleInfo(role$1);
@@ -79,7 +79,7 @@ async function command(opts, cmd) {
79
79
  cacheContext.lockfile.getDependencyTreeHash(pkg.packageJson.name)
80
80
  );
81
81
  hash.update("\0");
82
- hash.update(JSON.stringify(lintOptions));
82
+ hash.update(JSON.stringify(lintOptions ?? {}));
83
83
  hash.update("\0");
84
84
  hash.update(process.version);
85
85
  hash.update("\0");
@@ -91,17 +91,25 @@ async function command(opts, cmd) {
91
91
  })
92
92
  );
93
93
  const resultsList = await parallel.runWorkerQueueThreads({
94
- items,
94
+ items: items.filter((item) => item.lintOptions),
95
+ // Filter out packages without lint script
95
96
  workerData: {
96
97
  fix: Boolean(opts.fix),
97
98
  format: opts.format,
98
99
  shouldCache: Boolean(cacheContext),
99
- successCache: cacheContext?.cache
100
+ successCache: cacheContext?.cache,
101
+ rootDir: paths.paths.targetRoot
100
102
  },
101
- workerFactory: async ({ fix, format, shouldCache, successCache }) => {
103
+ workerFactory: async ({
104
+ fix,
105
+ format,
106
+ shouldCache,
107
+ successCache,
108
+ rootDir
109
+ }) => {
102
110
  const { ESLint } = require("eslint");
103
111
  const crypto = require("crypto");
104
- const recursiveReadDir = require("recursive-readdir");
112
+ const globby = require("globby");
105
113
  const { readFile } = require("fs/promises");
106
114
  const { relative: workerRelativePath } = require("path");
107
115
  return async ({
@@ -119,7 +127,11 @@ async function command(opts, cmd) {
119
127
  });
120
128
  let sha = void 0;
121
129
  if (shouldCache) {
122
- const result = await recursiveReadDir(fullDir);
130
+ const result = await globby(relativeDir, {
131
+ gitignore: true,
132
+ onlyFiles: true,
133
+ cwd: rootDir
134
+ });
123
135
  const hash = crypto.createHash("sha1");
124
136
  hash.update(parentHash);
125
137
  hash.update("\0");
@@ -116,7 +116,7 @@ async function command(opts, cmd) {
116
116
  if (!hasFlags("--passWithNoTests")) {
117
117
  args.push("--passWithNoTests");
118
118
  }
119
- if (!process.env.CI && !hasFlags("--coverage", "--watch", "--watchAll")) {
119
+ if (!opts.since && !process.env.CI && !hasFlags("--coverage", "--watch", "--watchAll")) {
120
120
  const isGitRepo = () => run.runCheck("git", "rev-parse", "--is-inside-work-tree");
121
121
  const isMercurialRepo = () => run.runCheck("hg", "--cwd", ".", "root");
122
122
  if (await isGitRepo() || await isMercurialRepo()) {
@@ -143,23 +143,24 @@ async function command(opts, cmd) {
143
143
  packageGraph = cliNode.PackageGraph.fromPackages(packages);
144
144
  return packageGraph;
145
145
  }
146
+ let selectedProjects = void 0;
146
147
  if (opts.since && !hasFlags("--selectProjects")) {
147
148
  const graph = await getPackageGraph();
148
149
  const changedPackages = await graph.listChangedPackages({
149
150
  ref: opts.since,
150
151
  analyzeLockfile: true
151
152
  });
152
- const packageNames = Array.from(
153
+ selectedProjects = Array.from(
153
154
  graph.collectPackageNames(
154
155
  changedPackages.map((pkg) => pkg.name),
155
156
  (pkg) => pkg.allLocalDependents.keys()
156
157
  )
157
158
  );
158
- if (packageNames.length === 0) {
159
+ if (selectedProjects.length === 0) {
159
160
  console.log(`No packages changed since ${opts.since}`);
160
161
  return;
161
162
  }
162
- args.push("--selectProjects", ...packageNames);
163
+ args.push("--selectProjects", ...selectedProjects);
163
164
  }
164
165
  if (!process.env.NODE_ENV) {
165
166
  process.env.NODE_ENV = "test";
@@ -232,7 +233,9 @@ async function command(opts, cmd) {
232
233
  const sha = hash.digest("hex");
233
234
  projectHashes.set(packageName, sha);
234
235
  if (cache?.includes(sha)) {
235
- console.log(`Skipped ${packageName} due to cache hit`);
236
+ if (!selectedProjects || selectedProjects.includes(packageName)) {
237
+ console.log(`Skipped ${packageName} due to cache hit`);
238
+ }
236
239
  outputSuccessCache.push(sha);
237
240
  return void 0;
238
241
  }
@@ -26,7 +26,7 @@ function applyContextToError(error, moduleName) {
26
26
  ${error}`;
27
27
  }
28
28
  async function buildBundle(options) {
29
- const { statsJsonEnabled, schema: configSchema } = options;
29
+ const { statsJsonEnabled, schema: configSchema, rspack } = options;
30
30
  const paths$1 = paths.resolveBundlingPaths(options);
31
31
  const publicPaths = await paths.resolveOptionalBundlingPaths({
32
32
  targetDir: options.targetDir,
@@ -91,7 +91,7 @@ async function buildBundle(options) {
91
91
  { spaces: 2 }
92
92
  );
93
93
  }
94
- const { stats } = await build(configs, isCi);
94
+ const { stats } = await build(configs, isCi, rspack);
95
95
  if (!stats) {
96
96
  throw new Error("No stats returned");
97
97
  }
@@ -119,10 +119,11 @@ async function buildBundle(options) {
119
119
  );
120
120
  }
121
121
  }
122
- async function build(configs, isCi) {
122
+ async function build(configs, isCi, rspack) {
123
+ const bundler = rspack ?? webpack__default.default;
123
124
  const stats = await new Promise(
124
125
  (resolve, reject) => {
125
- webpack__default.default(configs, (err, buildStats) => {
126
+ bundler(configs, (err, buildStats) => {
126
127
  if (err) {
127
128
  if (err.message) {
128
129
  const { errors: errors2 } = formatWebpackMessages__default.default({
@@ -2,11 +2,11 @@
2
2
 
3
3
  var path = require('path');
4
4
  var chalk = require('chalk');
5
- var webpack = require('webpack');
5
+ var webpack$1 = require('webpack');
6
6
  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
- var webpack$1 = require('@module-federation/enhanced/webpack');
9
+ var webpack = require('@module-federation/enhanced/webpack');
10
10
  var LinkedPackageResolvePlugin = require('./LinkedPackageResolvePlugin.cjs.js');
11
11
  var ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
12
12
  var runScriptWebpackPlugin = require('run-script-webpack-plugin');
@@ -28,7 +28,7 @@ var hasReactDomClient = require('./hasReactDomClient.cjs.js');
28
28
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
29
29
 
30
30
  var chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
31
- var webpack__default = /*#__PURE__*/_interopDefaultCompat(webpack);
31
+ var webpack__default = /*#__PURE__*/_interopDefaultCompat(webpack$1);
32
32
  var ESLintPlugin__default = /*#__PURE__*/_interopDefaultCompat(ESLintPlugin);
33
33
  var ForkTsCheckerWebpackPlugin__default = /*#__PURE__*/_interopDefaultCompat(ForkTsCheckerWebpackPlugin);
34
34
  var HtmlWebpackPlugin__default = /*#__PURE__*/_interopDefaultCompat(HtmlWebpackPlugin);
@@ -90,7 +90,8 @@ async function createConfig(paths$1, options) {
90
90
  isDev,
91
91
  frontendConfig,
92
92
  moduleFederation,
93
- publicSubPath = ""
93
+ publicSubPath = "",
94
+ rspack
94
95
  } = options;
95
96
  const { plugins, loaders } = transforms.transforms(options);
96
97
  const { packages } = await getPackages.getPackages(paths.paths.targetDir);
@@ -105,15 +106,20 @@ async function createConfig(paths$1, options) {
105
106
  options.frontendConfig,
106
107
  options.moduleFederation
107
108
  );
108
- plugins.push(
109
- new ReactRefreshPlugin__default.default({
110
- overlay: {
111
- sockProtocol: "ws",
112
- sockHost: host,
113
- sockPort: port
114
- }
115
- })
116
- );
109
+ if (rspack) {
110
+ const RspackReactRefreshPlugin = require("@rspack/plugin-react-refresh");
111
+ plugins.push(new RspackReactRefreshPlugin());
112
+ } else {
113
+ plugins.push(
114
+ new ReactRefreshPlugin__default.default({
115
+ overlay: {
116
+ sockProtocol: "ws",
117
+ sockHost: host,
118
+ sockPort: port
119
+ }
120
+ })
121
+ );
122
+ }
117
123
  }
118
124
  if (checksEnabled) {
119
125
  plugins.push(
@@ -126,14 +132,16 @@ async function createConfig(paths$1, options) {
126
132
  })
127
133
  );
128
134
  }
135
+ const bundler = rspack ? rspack : webpack__default.default;
129
136
  plugins.push(
130
- new webpack.ProvidePlugin({
137
+ new bundler.ProvidePlugin({
131
138
  process: require.resolve("process/browser"),
132
139
  Buffer: ["buffer", "Buffer"]
133
140
  })
134
141
  );
135
142
  if (options.moduleFederation?.mode !== "remote") {
136
143
  plugins.push(
144
+ // `rspack.HtmlRspackPlugin` does not support object type `templateParameters` value, `frontendConfig` in this case
137
145
  new HtmlWebpackPlugin__default.default({
138
146
  meta: {
139
147
  "backstage-app-mode": options?.appMode ?? "public"
@@ -161,8 +169,9 @@ async function createConfig(paths$1, options) {
161
169
  }
162
170
  if (options.moduleFederation) {
163
171
  const isRemote = options.moduleFederation?.mode === "remote";
172
+ const AdaptedModuleFederationPlugin = rspack ? rspack.container.ModuleFederationPlugin : webpack.ModuleFederationPlugin;
164
173
  plugins.push(
165
- new webpack$1.ModuleFederationPlugin({
174
+ new AdaptedModuleFederationPlugin({
166
175
  ...isRemote && {
167
176
  filename: "remoteEntry.js",
168
177
  exposes: {
@@ -222,9 +231,12 @@ async function createConfig(paths$1, options) {
222
231
  }
223
232
  const buildInfo = await readBuildInfo();
224
233
  plugins.push(
225
- new webpack__default.default.DefinePlugin({
234
+ new bundler.DefinePlugin({
226
235
  "process.env.BUILD_INFO": JSON.stringify(buildInfo),
227
- "process.env.APP_CONFIG": webpack__default.default.DefinePlugin.runtimeValue(
236
+ "process.env.APP_CONFIG": rspack ? (
237
+ // FIXME: see also https://github.com/web-infra-dev/rspack/issues/5606
238
+ JSON.stringify(options.getFrontendAppConfigs())
239
+ ) : bundler.DefinePlugin.runtimeValue(
228
240
  () => JSON.stringify(options.getFrontendAppConfigs()),
229
241
  true
230
242
  ),
@@ -233,11 +245,13 @@ async function createConfig(paths$1, options) {
233
245
  "process.env.HAS_REACT_DOM_CLIENT": JSON.stringify(hasReactDomClient.hasReactDomClient())
234
246
  })
235
247
  );
236
- const reactRefreshFiles = [
248
+ const reactRefreshFiles = rspack ? [] : [
237
249
  require.resolve(
238
250
  "@pmmmwh/react-refresh-webpack-plugin/lib/runtime/RefreshUtils.js"
239
251
  ),
240
- require.resolve("@pmmmwh/react-refresh-webpack-plugin/overlay/index.js"),
252
+ require.resolve(
253
+ "@pmmmwh/react-refresh-webpack-plugin/overlay/index.js"
254
+ ),
241
255
  require.resolve("react-refresh")
242
256
  ];
243
257
  const mode = isDev ? "development" : "production";
@@ -254,15 +268,16 @@ async function createConfig(paths$1, options) {
254
268
  ];
255
269
  optimization$1.nodeEnv = false;
256
270
  plugins.push(
257
- new webpack__default.default.DefinePlugin({
258
- "process.env.NODE_ENV": webpack__default.default.DefinePlugin.runtimeValue(
259
- ({ module }) => {
260
- if (reactPackageDirs.some((val) => module.resource.startsWith(val))) {
261
- return '"development"';
262
- }
263
- return `"${mode}"`;
271
+ new bundler.DefinePlugin({
272
+ "process.env.NODE_ENV": rspack ? (
273
+ // FIXME: see also https://github.com/web-infra-dev/rspack/issues/5606
274
+ JSON.stringify(mode)
275
+ ) : webpack__default.default.DefinePlugin.runtimeValue(({ module }) => {
276
+ if (reactPackageDirs.some((val) => module.resource.startsWith(val))) {
277
+ return '"development"';
264
278
  }
265
- )
279
+ return `"${mode}"`;
280
+ })
266
281
  })
267
282
  );
268
283
  }
@@ -307,13 +322,16 @@ async function createConfig(paths$1, options) {
307
322
  http: false,
308
323
  util: require.resolve("util/")
309
324
  },
310
- plugins: [
311
- new LinkedPackageResolvePlugin.LinkedPackageResolvePlugin(paths$1.rootNodeModules, externalPkgs),
312
- new ModuleScopePlugin__default.default(
313
- [paths$1.targetSrc, paths$1.targetDev],
314
- [paths$1.targetPackageJson, ...reactRefreshFiles]
315
- )
316
- ]
325
+ // FIXME: see also https://github.com/web-infra-dev/rspack/issues/3408
326
+ ...!rspack && {
327
+ plugins: [
328
+ new LinkedPackageResolvePlugin.LinkedPackageResolvePlugin(paths$1.rootNodeModules, externalPkgs),
329
+ new ModuleScopePlugin__default.default(
330
+ [paths$1.targetSrc, paths$1.targetDev],
331
+ [paths$1.targetPackageJson, ...reactRefreshFiles]
332
+ )
333
+ ]
334
+ }
317
335
  },
318
336
  module: {
319
337
  rules: loaders
@@ -332,17 +350,21 @@ async function createConfig(paths$1, options) {
332
350
  } : {}
333
351
  },
334
352
  experiments: {
335
- lazyCompilation: yn__default.default(process.env.EXPERIMENTAL_LAZY_COMPILATION)
353
+ lazyCompilation: !rspack && yn__default.default(process.env.EXPERIMENTAL_LAZY_COMPILATION),
354
+ ...rspack && {
355
+ // We're still using `style-loader` for custom `insert` option
356
+ css: false
357
+ }
336
358
  },
337
359
  plugins,
338
- ...withCache ? {
360
+ ...withCache && {
339
361
  cache: {
340
362
  type: "filesystem",
341
363
  buildDependencies: {
342
364
  config: [__filename]
343
365
  }
344
366
  }
345
- } : {}
367
+ }
346
368
  };
347
369
  }
348
370
  async function createBackendConfig(paths$1, options) {
@@ -1,8 +1,12 @@
1
1
  'use strict';
2
2
 
3
+ var paths = require('../paths.cjs.js');
4
+
3
5
  function hasReactDomClient() {
4
6
  try {
5
- require.resolve("react-dom/client");
7
+ require.resolve("react-dom/client", {
8
+ paths: [paths.paths.targetDir]
9
+ });
6
10
  return true;
7
11
  } catch {
8
12
  return false;
@@ -2,21 +2,23 @@
2
2
 
3
3
  const { EsbuildPlugin } = require("esbuild-loader");
4
4
  const optimization = (options) => {
5
- const { isDev } = options;
5
+ const { isDev, rspack } = options;
6
+ const MinifyPlugin = rspack ? rspack.SwcJsMinimizerRspackPlugin : EsbuildPlugin;
6
7
  return {
7
8
  minimize: !isDev,
8
9
  minimizer: [
9
- new EsbuildPlugin({
10
+ new MinifyPlugin({
10
11
  target: "ES2022",
11
12
  format: "iife",
12
13
  exclude: "remoteEntry.js"
13
14
  }),
14
15
  // Avoid iife wrapping of module federation remote entry as it breaks the variable assignment
15
- new EsbuildPlugin({
16
+ new MinifyPlugin({
16
17
  target: "ES2022",
17
18
  format: void 0,
18
19
  include: "remoteEntry.js"
19
- })
20
+ }),
21
+ rspack && new rspack.LightningCssMinimizerRspackPlugin()
20
22
  ],
21
23
  runtimeChunk: "single",
22
24
  splitChunks: {
@@ -42,8 +44,10 @@ const optimization = (options) => {
42
44
  priority: 10,
43
45
  minSize: 1e5,
44
46
  minChunks: 1,
45
- maxAsyncRequests: Infinity,
46
- maxInitialRequests: Infinity
47
+ ...!rspack && {
48
+ maxAsyncRequests: Infinity,
49
+ maxInitialRequests: Infinity
50
+ }
47
51
  },
48
52
  // filename is not included in type, but we need it
49
53
  // Group together the smallest modules
@@ -81,12 +81,14 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be
81
81
  viteServer?.restart();
82
82
  }
83
83
  });
84
+ const rspack = process.env.EXPERIMENTAL_RSPACK ? require("@rspack/core") : void 0;
84
85
  const commonConfigOptions = {
85
86
  ...options,
86
87
  checksEnabled: options.checksEnabled,
87
88
  isDev: true,
88
89
  baseUrl: url,
89
90
  frontendConfig,
91
+ rspack,
90
92
  getFrontendAppConfigs: () => {
91
93
  return latestFrontendAppConfigs;
92
94
  }
@@ -99,22 +101,58 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be
99
101
  if (process.env.EXPERIMENTAL_VITE) {
100
102
  const vite = require("vite");
101
103
  const { default: viteReact } = require("@vitejs/plugin-react");
102
- const {
103
- nodePolyfills: viteNodePolyfills
104
- } = require("vite-plugin-node-polyfills");
104
+ const { default: viteYaml } = require("@modyfi/vite-plugin-yaml");
105
+ const { nodePolyfills: viteNodePolyfills } = require("vite-plugin-node-polyfills");
105
106
  const { createHtmlPlugin: viteHtml } = require("vite-plugin-html");
106
107
  viteServer = await vite.createServer({
107
108
  define: {
108
- global: "window",
109
109
  "process.argv": JSON.stringify(process.argv),
110
110
  "process.env.APP_CONFIG": JSON.stringify(cliConfig.frontendAppConfigs),
111
111
  // This allows for conditional imports of react-dom/client, since there's no way
112
112
  // to check for presence of it in source code without module resolution errors.
113
113
  "process.env.HAS_REACT_DOM_CLIENT": JSON.stringify(hasReactDomClient.hasReactDomClient())
114
114
  },
115
+ optimizeDeps: {
116
+ esbuildOptions: {
117
+ plugins: [
118
+ {
119
+ name: "custom-define",
120
+ setup(build) {
121
+ const define = build.initialOptions.define ||= {};
122
+ define["process.env.HAS_REACT_DOM_CLIENT"] = JSON.stringify(
123
+ hasReactDomClient.hasReactDomClient()
124
+ );
125
+ define["process.env.NODE_ENV"] = JSON.stringify("development");
126
+ }
127
+ }
128
+ ]
129
+ }
130
+ },
115
131
  plugins: [
116
132
  viteReact(),
117
- viteNodePolyfills(),
133
+ viteNodePolyfills({
134
+ include: [
135
+ "buffer",
136
+ "events",
137
+ "fs",
138
+ "http",
139
+ "https",
140
+ "os",
141
+ "path",
142
+ "process",
143
+ "querystring",
144
+ "stream",
145
+ "url",
146
+ "util",
147
+ "zlib"
148
+ ],
149
+ globals: {
150
+ global: true,
151
+ Buffer: true,
152
+ process: true
153
+ }
154
+ }),
155
+ viteYaml(),
118
156
  viteHtml({
119
157
  entry: paths$2.targetEntry,
120
158
  // todo(blam): we should look at contributing to thPe plugin here
@@ -136,6 +174,8 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be
136
174
  root: paths$2.targetPath
137
175
  });
138
176
  } else {
177
+ const bundler = rspack ?? webpack__default.default;
178
+ const DevServer = rspack ? require("@rspack/dev-server").RspackDevServer : WebpackDevServer__default.default;
139
179
  const publicPaths = await paths.resolveOptionalBundlingPaths({
140
180
  entry: "src/index-public-experimental",
141
181
  dist: "dist/public"
@@ -147,8 +187,8 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be
147
187
  )
148
188
  );
149
189
  }
150
- const compiler = publicPaths ? webpack__default.default([config$2, await config$1.createConfig(publicPaths, commonConfigOptions)]) : webpack__default.default(config$2);
151
- webpackServer = new WebpackDevServer__default.default(
190
+ const compiler = publicPaths ? bundler([config$2, await config$1.createConfig(publicPaths, commonConfigOptions)]) : bundler(config$2);
191
+ webpackServer = new DevServer(
152
192
  {
153
193
  hot: !process.env.CI,
154
194
  devMiddleware: {
@@ -8,7 +8,8 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
8
8
  var MiniCssExtractPlugin__default = /*#__PURE__*/_interopDefaultCompat(MiniCssExtractPlugin);
9
9
 
10
10
  const transforms = (options) => {
11
- const { isDev, isBackend } = options;
11
+ const { isDev, isBackend, rspack } = options;
12
+ const CssExtractRspackPlugin = rspack ? rspack.CssExtractRspackPlugin : MiniCssExtractPlugin__default.default;
12
13
  function insertBeforeJssStyles(element) {
13
14
  const head = document.head;
14
15
  const firstJssNode = head.querySelector("style[data-jss]");
@@ -24,7 +25,7 @@ const transforms = (options) => {
24
25
  exclude: /node_modules/,
25
26
  use: [
26
27
  {
27
- loader: require.resolve("swc-loader"),
28
+ loader: rspack ? "builtin:swc-loader" : require.resolve("swc-loader"),
28
29
  options: {
29
30
  jsc: {
30
31
  target: "es2022",
@@ -50,7 +51,7 @@ const transforms = (options) => {
50
51
  exclude: /node_modules/,
51
52
  use: [
52
53
  {
53
- loader: require.resolve("swc-loader"),
54
+ loader: rspack ? "builtin:swc-loader" : require.resolve("swc-loader"),
54
55
  options: {
55
56
  jsc: {
56
57
  target: "es2022",
@@ -81,7 +82,7 @@ const transforms = (options) => {
81
82
  test: [/\.icon\.svg$/],
82
83
  use: [
83
84
  {
84
- loader: require.resolve("swc-loader"),
85
+ loader: rspack ? "builtin:swc-loader" : require.resolve("swc-loader"),
85
86
  options: {
86
87
  jsc: {
87
88
  target: "es2022",
@@ -143,7 +144,7 @@ const transforms = (options) => {
143
144
  options: {
144
145
  insert: insertBeforeJssStyles
145
146
  }
146
- } : MiniCssExtractPlugin__default.default.loader,
147
+ } : CssExtractRspackPlugin.loader,
147
148
  {
148
149
  loader: require.resolve("css-loader"),
149
150
  options: {
@@ -156,7 +157,7 @@ const transforms = (options) => {
156
157
  const plugins = new Array();
157
158
  if (!isDev) {
158
159
  plugins.push(
159
- new MiniCssExtractPlugin__default.default({
160
+ new CssExtractRspackPlugin({
160
161
  filename: "static/[name].[contenthash:8].css",
161
162
  chunkFilename: "static/[name].[id].[contenthash:8].css",
162
163
  insert: insertBeforeJssStyles