@backstage/cli 0.33.2-next.0 → 0.34.0-next.2

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 (45) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/asset-types/asset-types.d.ts +0 -38
  3. package/config/nodeTransformHooks.mjs +12 -0
  4. package/dist/lib/version.cjs.js +20 -14
  5. package/dist/modules/build/commands/package/build/command.cjs.js +3 -3
  6. package/dist/modules/build/commands/package/start/startFrontend.cjs.js +4 -7
  7. package/dist/modules/build/commands/repo/build.cjs.js +2 -3
  8. package/dist/modules/build/lib/buildFrontend.cjs.js +7 -10
  9. package/dist/modules/build/lib/builder/config.cjs.js +0 -7
  10. package/dist/modules/build/lib/bundler/bundle.cjs.js +24 -29
  11. package/dist/modules/build/lib/bundler/config.cjs.js +40 -28
  12. package/dist/modules/build/lib/bundler/optimization.cjs.js +6 -5
  13. package/dist/modules/build/lib/bundler/packageDetection.cjs.js +4 -9
  14. package/dist/modules/build/lib/bundler/server.cjs.js +18 -22
  15. package/dist/modules/build/lib/bundler/transforms.cjs.js +7 -35
  16. package/dist/packages/cli/package.json.cjs.js +15 -19
  17. package/dist/packages/core-components/package.json.cjs.js +1 -1
  18. package/dist/packages/frontend-defaults/package.json.cjs.js +6 -0
  19. package/dist/packages/frontend-plugin-api/package.json.cjs.js +6 -0
  20. package/dist/packages/frontend-test-utils/package.json.cjs.js +6 -0
  21. package/package.json +46 -26
  22. package/templates/new-frontend-plugin/.eslintrc.js.hbs +1 -0
  23. package/templates/new-frontend-plugin/README.md.hbs +20 -0
  24. package/templates/new-frontend-plugin/dev/index.tsx +10 -0
  25. package/templates/new-frontend-plugin/package.json.hbs +49 -0
  26. package/templates/new-frontend-plugin/portable-template.yaml +5 -0
  27. package/templates/new-frontend-plugin/src/components/ExampleComponent/ExampleComponent.test.tsx.hbs +28 -0
  28. package/templates/new-frontend-plugin/src/components/ExampleComponent/ExampleComponent.tsx.hbs +37 -0
  29. package/templates/new-frontend-plugin/src/components/ExampleComponent/index.ts +1 -0
  30. package/templates/new-frontend-plugin/src/components/ExampleFetchComponent/ExampleFetchComponent.test.tsx.hbs +19 -0
  31. package/templates/new-frontend-plugin/src/components/ExampleFetchComponent/ExampleFetchComponent.tsx.hbs +308 -0
  32. package/templates/new-frontend-plugin/src/components/ExampleFetchComponent/index.ts +1 -0
  33. package/templates/new-frontend-plugin/src/index.ts.hbs +1 -0
  34. package/templates/new-frontend-plugin/src/plugin.test.ts.hbs +7 -0
  35. package/templates/new-frontend-plugin/src/plugin.tsx.hbs +26 -0
  36. package/templates/new-frontend-plugin/src/routes.ts +3 -0
  37. package/templates/new-frontend-plugin/src/setupTests.ts +1 -0
  38. package/templates/new-frontend-plugin-module/.eslintrc.js.hbs +1 -0
  39. package/templates/new-frontend-plugin-module/README.md.hbs +5 -0
  40. package/templates/new-frontend-plugin-module/package.json.hbs +35 -0
  41. package/templates/new-frontend-plugin-module/portable-template.yaml +5 -0
  42. package/templates/new-frontend-plugin-module/src/index.ts.hbs +1 -0
  43. package/templates/new-frontend-plugin-module/src/module.tsx.hbs +8 -0
  44. package/templates/new-frontend-plugin-module/src/setupTests.ts +1 -0
  45. package/dist/lib/svgrTemplate.cjs.js +0 -23
@@ -4,8 +4,8 @@ var chalk = require('chalk');
4
4
  var fs = require('fs-extra');
5
5
  var path = require('path');
6
6
  var openBrowser = require('react-dev-utils/openBrowser');
7
- var webpack = require('webpack');
8
- var WebpackDevServer = require('webpack-dev-server');
7
+ var core = require('@rspack/core');
8
+ var devServer = require('@rspack/dev-server');
9
9
  var paths$1 = require('../../../../lib/paths.cjs.js');
10
10
  var config = require('../../../config/lib/config.cjs.js');
11
11
  var config$1 = require('./config.cjs.js');
@@ -17,8 +17,6 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
17
17
  var chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
18
18
  var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
19
19
  var openBrowser__default = /*#__PURE__*/_interopDefaultCompat(openBrowser);
20
- var webpack__default = /*#__PURE__*/_interopDefaultCompat(webpack);
21
- var WebpackDevServer__default = /*#__PURE__*/_interopDefaultCompat(WebpackDevServer);
22
20
 
23
21
  async function serveBundle(options) {
24
22
  const paths$2 = paths.resolveBundlingPaths(options);
@@ -38,14 +36,14 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be
38
36
  const { name } = await fs__default.default.readJson(
39
37
  path.resolve(options.targetDir ?? paths$1.paths.targetDir, "package.json")
40
38
  );
41
- let webpackServer = void 0;
39
+ let devServer$1 = void 0;
42
40
  let latestFrontendAppConfigs = [];
43
41
  const triggerReload = () => {
44
- if (webpackServer) {
45
- webpackServer.invalidate();
46
- if (process.env.EXPERIMENTAL_RSPACK) {
47
- webpackServer.sendMessage(
48
- webpackServer.webSocketServer?.clients ?? [],
42
+ if (devServer$1) {
43
+ devServer$1.invalidate();
44
+ if (!process.env.LEGACY_WEBPACK_BUILD) {
45
+ devServer$1.sendMessage(
46
+ devServer$1.webSocketServer?.clients ?? [],
49
47
  "static-changed"
50
48
  );
51
49
  }
@@ -92,14 +90,14 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be
92
90
  triggerReload();
93
91
  }
94
92
  });
95
- const rspack = process.env.EXPERIMENTAL_RSPACK ? require("@rspack/core") : void 0;
93
+ const webpack = process.env.LEGACY_WEBPACK_BUILD ? require("webpack") : void 0;
96
94
  const commonConfigOptions = {
97
95
  ...options,
98
96
  checksEnabled: options.checksEnabled,
99
97
  isDev: true,
100
98
  baseUrl: url,
101
99
  frontendConfig,
102
- rspack,
100
+ webpack,
103
101
  getFrontendAppConfigs: () => {
104
102
  return latestFrontendAppConfigs;
105
103
  }
@@ -109,12 +107,10 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be
109
107
  additionalEntryPoints: detectedModulesEntryPoint,
110
108
  moduleFederation: options.moduleFederation
111
109
  });
112
- const bundler = rspack ?? webpack__default.default;
113
- const DevServer = rspack ? require("@rspack/dev-server").RspackDevServer : WebpackDevServer__default.default;
114
- if (rspack) {
115
- console.log(
116
- chalk__default.default.yellow(`\u26A0\uFE0F WARNING: Using experimental RSPack dev server.`)
117
- );
110
+ const bundler = webpack ?? core.rspack;
111
+ const DevServer = webpack ? require("webpack-dev-server") : devServer.RspackDevServer;
112
+ if (webpack) {
113
+ console.log(chalk__default.default.yellow(`\u26A0\uFE0F WARNING: Using legacy WebPack dev server.`));
118
114
  }
119
115
  const publicPaths = await paths.resolveOptionalBundlingPaths({
120
116
  entry: "src/index-public-experimental",
@@ -128,7 +124,7 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be
128
124
  );
129
125
  }
130
126
  const compiler = publicPaths ? bundler([config$2, await config$1.createConfig(publicPaths, commonConfigOptions)]) : bundler(config$2);
131
- webpackServer = new DevServer(
127
+ devServer$1 = new DevServer(
132
128
  {
133
129
  hot: !process.env.CI,
134
130
  devMiddleware: {
@@ -172,8 +168,8 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be
172
168
  compiler
173
169
  );
174
170
  await new Promise(async (resolve, reject) => {
175
- if (webpackServer) {
176
- webpackServer.startCallback((err) => {
171
+ if (devServer$1) {
172
+ devServer$1.startCallback((err) => {
177
173
  if (err) {
178
174
  reject(err);
179
175
  return;
@@ -190,7 +186,7 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be
190
186
  const waitForExit = async () => {
191
187
  for (const signal of ["SIGINT", "SIGTERM"]) {
192
188
  process.on(signal, () => {
193
- webpackServer?.stop();
189
+ devServer$1?.stop();
194
190
  process.exit();
195
191
  });
196
192
  }
@@ -1,15 +1,10 @@
1
1
  'use strict';
2
2
 
3
- var MiniCssExtractPlugin = require('mini-css-extract-plugin');
4
- var svgrTemplate = require('../../../../lib/svgrTemplate.cjs.js');
5
-
6
- function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
7
-
8
- var MiniCssExtractPlugin__default = /*#__PURE__*/_interopDefaultCompat(MiniCssExtractPlugin);
3
+ var core = require('@rspack/core');
9
4
 
10
5
  const transforms = (options) => {
11
- const { isDev, isBackend, rspack } = options;
12
- const CssExtractRspackPlugin = rspack ? rspack.CssExtractRspackPlugin : MiniCssExtractPlugin__default.default;
6
+ const { isDev, isBackend, webpack } = options;
7
+ const CssExtractPlugin = webpack ? require("mini-css-extract-plugin") : core.CssExtractRspackPlugin;
13
8
  function insertBeforeJssStyles(element) {
14
9
  const head = document.head;
15
10
  const firstJssNode = head.querySelector("style[data-jss]");
@@ -25,7 +20,7 @@ const transforms = (options) => {
25
20
  exclude: /node_modules/,
26
21
  use: [
27
22
  {
28
- loader: rspack ? "builtin:swc-loader" : require.resolve("swc-loader"),
23
+ loader: webpack ? require.resolve("swc-loader") : "builtin:swc-loader",
29
24
  options: {
30
25
  jsc: {
31
26
  target: "es2022",
@@ -51,7 +46,7 @@ const transforms = (options) => {
51
46
  exclude: /node_modules/,
52
47
  use: [
53
48
  {
54
- loader: rspack ? "builtin:swc-loader" : require.resolve("swc-loader"),
49
+ loader: webpack ? require.resolve("swc-loader") : "builtin:swc-loader",
55
50
  options: {
56
51
  jsc: {
57
52
  target: "es2022",
@@ -78,29 +73,6 @@ const transforms = (options) => {
78
73
  fullySpecified: false
79
74
  }
80
75
  },
81
- {
82
- test: [/\.icon\.svg$/],
83
- use: [
84
- {
85
- loader: rspack ? "builtin:swc-loader" : require.resolve("swc-loader"),
86
- options: {
87
- jsc: {
88
- target: "es2022",
89
- externalHelpers: !isBackend,
90
- parser: {
91
- syntax: "ecmascript",
92
- jsx: !isBackend,
93
- dynamicImport: true
94
- }
95
- }
96
- }
97
- },
98
- {
99
- loader: require.resolve("@svgr/webpack"),
100
- options: { babel: false, template: svgrTemplate.svgrTemplate }
101
- }
102
- ]
103
- },
104
76
  {
105
77
  test: [
106
78
  /\.bmp$/,
@@ -145,7 +117,7 @@ const transforms = (options) => {
145
117
  options: {
146
118
  insert: insertBeforeJssStyles
147
119
  }
148
- } : CssExtractRspackPlugin.loader,
120
+ } : CssExtractPlugin.loader,
149
121
  {
150
122
  loader: require.resolve("css-loader"),
151
123
  options: {
@@ -158,7 +130,7 @@ const transforms = (options) => {
158
130
  const plugins = new Array();
159
131
  if (!isDev) {
160
132
  plugins.push(
161
- new CssExtractRspackPlugin({
133
+ new CssExtractPlugin({
162
134
  filename: "static/[name].[contenthash:8].css",
163
135
  chunkFilename: "static/[name].[id].[contenthash:8].css",
164
136
  insert: insertBeforeJssStyles
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "0.33.2-next.0";
3
+ var version = "0.34.0-next.2";
4
4
  var dependencies = {
5
5
  "@backstage/catalog-model": "workspace:^",
6
6
  "@backstage/cli-common": "workspace:^",
@@ -18,20 +18,16 @@ var dependencies = {
18
18
  "@octokit/graphql-schema": "^13.7.0",
19
19
  "@octokit/oauth-app": "^4.2.0",
20
20
  "@octokit/request": "^8.0.0",
21
- "@pmmmwh/react-refresh-webpack-plugin": "^0.5.7",
22
21
  "@rollup/plugin-commonjs": "^26.0.0",
23
22
  "@rollup/plugin-json": "^6.0.0",
24
23
  "@rollup/plugin-node-resolve": "^15.0.0",
25
24
  "@rollup/plugin-yaml": "^4.0.0",
25
+ "@rspack/core": "^1.4.11",
26
+ "@rspack/dev-server": "^1.1.4",
27
+ "@rspack/plugin-react-refresh": "^1.4.3",
26
28
  "@spotify/eslint-config-base": "^15.0.0",
27
29
  "@spotify/eslint-config-react": "^15.0.0",
28
30
  "@spotify/eslint-config-typescript": "^15.0.0",
29
- "@sucrase/webpack-loader": "^2.0.0",
30
- "@svgr/core": "6.5.x",
31
- "@svgr/plugin-jsx": "6.5.x",
32
- "@svgr/plugin-svgo": "6.5.x",
33
- "@svgr/rollup": "6.5.x",
34
- "@svgr/webpack": "6.5.x",
35
31
  "@swc/core": "^1.3.46",
36
32
  "@swc/helpers": "^0.5.0",
37
33
  "@swc/jest": "^0.2.22",
@@ -51,7 +47,6 @@ var dependencies = {
51
47
  "css-loader": "^6.5.1",
52
48
  "ctrlc-windows": "^2.1.0",
53
49
  esbuild: "^0.25.0",
54
- "esbuild-loader": "^4.0.0",
55
50
  eslint: "^8.6.0",
56
51
  "eslint-config-prettier": "^9.0.0",
57
52
  "eslint-formatter-friendly": "^7.0.0",
@@ -62,9 +57,8 @@ var dependencies = {
62
57
  "eslint-plugin-react": "^7.37.2",
63
58
  "eslint-plugin-react-hooks": "^5.0.0",
64
59
  "eslint-plugin-unused-imports": "^4.1.4",
65
- "eslint-webpack-plugin": "^4.2.0",
60
+ "eslint-rspack-plugin": "^4.2.1",
66
61
  express: "^4.17.1",
67
- "fork-ts-checker-webpack-plugin": "^9.0.0",
68
62
  "fs-extra": "^11.2.0",
69
63
  "git-url-parse": "^15.0.0",
70
64
  glob: "^7.1.7",
@@ -80,7 +74,6 @@ var dependencies = {
80
74
  "jest-runtime": "^29.0.2",
81
75
  "json-schema": "^0.4.0",
82
76
  lodash: "^4.17.21",
83
- "mini-css-extract-plugin": "^2.4.2",
84
77
  minimatch: "^9.0.0",
85
78
  "node-stdlib-browser": "^1.3.1",
86
79
  "npm-packlist": "^5.0.0",
@@ -104,12 +97,10 @@ var dependencies = {
104
97
  sucrase: "^3.20.2",
105
98
  "swc-loader": "^0.2.3",
106
99
  tar: "^6.1.12",
107
- "terser-webpack-plugin": "^5.1.3",
100
+ "ts-checker-rspack-plugin": "^1.1.5",
108
101
  "ts-morph": "^24.0.0",
109
102
  undici: "^7.2.3",
110
103
  util: "^0.12.3",
111
- webpack: "^5.94.0",
112
- "webpack-dev-server": "^5.0.0",
113
104
  yaml: "^2.0.0",
114
105
  yargs: "^16.2.0",
115
106
  "yml-loader": "^2.1.0",
@@ -134,9 +125,7 @@ var devDependencies = {
134
125
  "@backstage/plugin-scaffolder-node-test-utils": "workspace:^",
135
126
  "@backstage/test-utils": "workspace:^",
136
127
  "@backstage/theme": "workspace:^",
137
- "@rspack/core": "^1.3.9",
138
- "@rspack/dev-server": "^1.1.1",
139
- "@rspack/plugin-react-refresh": "^1.4.2",
128
+ "@pmmmwh/react-refresh-webpack-plugin": "^0.5.7",
140
129
  "@types/cross-spawn": "^6.0.2",
141
130
  "@types/ejs": "^3.1.3",
142
131
  "@types/express": "^4.17.6",
@@ -154,8 +143,15 @@ var devDependencies = {
154
143
  "@types/webpack-sources": "^3.2.3",
155
144
  "@types/yarnpkg__lockfile": "^1.1.4",
156
145
  del: "^8.0.0",
146
+ "esbuild-loader": "^4.0.0",
147
+ "eslint-webpack-plugin": "^4.2.0",
148
+ "fork-ts-checker-webpack-plugin": "^9.0.0",
149
+ "mini-css-extract-plugin": "^2.4.2",
157
150
  msw: "^1.0.0",
158
- nodemon: "^3.0.1"
151
+ nodemon: "^3.0.1",
152
+ "terser-webpack-plugin": "^5.1.3",
153
+ webpack: "~5.96.0",
154
+ "webpack-dev-server": "^5.0.0"
159
155
  };
160
156
 
161
157
  exports.dependencies = dependencies;
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "0.17.5-next.0";
3
+ var version = "0.17.5-next.2";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map
@@ -0,0 +1,6 @@
1
+ 'use strict';
2
+
3
+ var version = "0.3.0-next.3";
4
+
5
+ exports.version = version;
6
+ //# sourceMappingURL=package.json.cjs.js.map
@@ -0,0 +1,6 @@
1
+ 'use strict';
2
+
3
+ var version = "0.11.0-next.2";
4
+
5
+ exports.version = version;
6
+ //# sourceMappingURL=package.json.cjs.js.map
@@ -0,0 +1,6 @@
1
+ 'use strict';
2
+
3
+ var version = "0.3.5-next.2";
4
+
5
+ exports.version = version;
6
+ //# sourceMappingURL=package.json.cjs.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/cli",
3
- "version": "0.33.2-next.0",
3
+ "version": "0.34.0-next.2",
4
4
  "description": "CLI for developing Backstage plugins and apps",
5
5
  "backstage": {
6
6
  "role": "cli"
@@ -63,20 +63,16 @@
63
63
  "@octokit/graphql-schema": "^13.7.0",
64
64
  "@octokit/oauth-app": "^4.2.0",
65
65
  "@octokit/request": "^8.0.0",
66
- "@pmmmwh/react-refresh-webpack-plugin": "^0.5.7",
67
66
  "@rollup/plugin-commonjs": "^26.0.0",
68
67
  "@rollup/plugin-json": "^6.0.0",
69
68
  "@rollup/plugin-node-resolve": "^15.0.0",
70
69
  "@rollup/plugin-yaml": "^4.0.0",
70
+ "@rspack/core": "^1.4.11",
71
+ "@rspack/dev-server": "^1.1.4",
72
+ "@rspack/plugin-react-refresh": "^1.4.3",
71
73
  "@spotify/eslint-config-base": "^15.0.0",
72
74
  "@spotify/eslint-config-react": "^15.0.0",
73
75
  "@spotify/eslint-config-typescript": "^15.0.0",
74
- "@sucrase/webpack-loader": "^2.0.0",
75
- "@svgr/core": "6.5.x",
76
- "@svgr/plugin-jsx": "6.5.x",
77
- "@svgr/plugin-svgo": "6.5.x",
78
- "@svgr/rollup": "6.5.x",
79
- "@svgr/webpack": "6.5.x",
80
76
  "@swc/core": "^1.3.46",
81
77
  "@swc/helpers": "^0.5.0",
82
78
  "@swc/jest": "^0.2.22",
@@ -96,7 +92,6 @@
96
92
  "css-loader": "^6.5.1",
97
93
  "ctrlc-windows": "^2.1.0",
98
94
  "esbuild": "^0.25.0",
99
- "esbuild-loader": "^4.0.0",
100
95
  "eslint": "^8.6.0",
101
96
  "eslint-config-prettier": "^9.0.0",
102
97
  "eslint-formatter-friendly": "^7.0.0",
@@ -107,9 +102,8 @@
107
102
  "eslint-plugin-react": "^7.37.2",
108
103
  "eslint-plugin-react-hooks": "^5.0.0",
109
104
  "eslint-plugin-unused-imports": "^4.1.4",
110
- "eslint-webpack-plugin": "^4.2.0",
105
+ "eslint-rspack-plugin": "^4.2.1",
111
106
  "express": "^4.17.1",
112
- "fork-ts-checker-webpack-plugin": "^9.0.0",
113
107
  "fs-extra": "^11.2.0",
114
108
  "git-url-parse": "^15.0.0",
115
109
  "glob": "^7.1.7",
@@ -125,7 +119,6 @@
125
119
  "jest-runtime": "^29.0.2",
126
120
  "json-schema": "^0.4.0",
127
121
  "lodash": "^4.17.21",
128
- "mini-css-extract-plugin": "^2.4.2",
129
122
  "minimatch": "^9.0.0",
130
123
  "node-stdlib-browser": "^1.3.1",
131
124
  "npm-packlist": "^5.0.0",
@@ -149,12 +142,10 @@
149
142
  "sucrase": "^3.20.2",
150
143
  "swc-loader": "^0.2.3",
151
144
  "tar": "^6.1.12",
152
- "terser-webpack-plugin": "^5.1.3",
145
+ "ts-checker-rspack-plugin": "^1.1.5",
153
146
  "ts-morph": "^24.0.0",
154
147
  "undici": "^7.2.3",
155
148
  "util": "^0.12.3",
156
- "webpack": "^5.94.0",
157
- "webpack-dev-server": "^5.0.0",
158
149
  "yaml": "^2.0.0",
159
150
  "yargs": "^16.2.0",
160
151
  "yml-loader": "^2.1.0",
@@ -168,7 +159,7 @@
168
159
  "@backstage/catalog-client": "1.11.0-next.0",
169
160
  "@backstage/config": "1.3.3",
170
161
  "@backstage/core-app-api": "1.18.0",
171
- "@backstage/core-components": "0.17.5-next.0",
162
+ "@backstage/core-components": "0.17.5-next.2",
172
163
  "@backstage/core-plugin-api": "1.10.9",
173
164
  "@backstage/dev-utils": "1.1.13-next.1",
174
165
  "@backstage/errors": "1.2.7",
@@ -179,9 +170,7 @@
179
170
  "@backstage/plugin-scaffolder-node-test-utils": "0.3.2-next.0",
180
171
  "@backstage/test-utils": "1.7.11-next.0",
181
172
  "@backstage/theme": "0.6.8-next.0",
182
- "@rspack/core": "^1.3.9",
183
- "@rspack/dev-server": "^1.1.1",
184
- "@rspack/plugin-react-refresh": "^1.4.2",
173
+ "@pmmmwh/react-refresh-webpack-plugin": "^0.5.7",
185
174
  "@types/cross-spawn": "^6.0.2",
186
175
  "@types/ejs": "^3.1.3",
187
176
  "@types/express": "^4.17.6",
@@ -199,22 +188,53 @@
199
188
  "@types/webpack-sources": "^3.2.3",
200
189
  "@types/yarnpkg__lockfile": "^1.1.4",
201
190
  "del": "^8.0.0",
191
+ "esbuild-loader": "^4.0.0",
192
+ "eslint-webpack-plugin": "^4.2.0",
193
+ "fork-ts-checker-webpack-plugin": "^9.0.0",
194
+ "mini-css-extract-plugin": "^2.4.2",
202
195
  "msw": "^1.0.0",
203
- "nodemon": "^3.0.1"
196
+ "nodemon": "^3.0.1",
197
+ "terser-webpack-plugin": "^5.1.3",
198
+ "webpack": "~5.96.0",
199
+ "webpack-dev-server": "^5.0.0"
204
200
  },
205
201
  "peerDependencies": {
206
- "@rspack/core": "^1.2.8",
207
- "@rspack/dev-server": "^1.0.9",
208
- "@rspack/plugin-react-refresh": "^1.0.0"
202
+ "@module-federation/enhanced": "^0.9.0",
203
+ "@pmmmwh/react-refresh-webpack-plugin": "^0.5.7",
204
+ "esbuild-loader": "^4.0.0",
205
+ "eslint-webpack-plugin": "^4.2.0",
206
+ "fork-ts-checker-webpack-plugin": "^9.0.0",
207
+ "mini-css-extract-plugin": "^2.4.2",
208
+ "terser-webpack-plugin": "^5.1.3",
209
+ "webpack": "~5.96.0",
210
+ "webpack-dev-server": "^5.0.0"
209
211
  },
210
212
  "peerDependenciesMeta": {
211
- "@rspack/core": {
213
+ "@module-federation/enhanced": {
214
+ "optional": true
215
+ },
216
+ "@pmmmwh/react-refresh-webpack-plugin": {
217
+ "optional": true
218
+ },
219
+ "esbuild-loader": {
220
+ "optional": true
221
+ },
222
+ "eslint-webpack-plugin": {
223
+ "optional": true
224
+ },
225
+ "fork-ts-checker-webpack-plugin": {
226
+ "optional": true
227
+ },
228
+ "mini-css-extract-plugin": {
229
+ "optional": true
230
+ },
231
+ "terser-webpack-plugin": {
212
232
  "optional": true
213
233
  },
214
- "@rspack/dev-server": {
234
+ "webpack": {
215
235
  "optional": true
216
236
  },
217
- "@rspack/plugin-react-refresh": {
237
+ "webpack-dev-server": {
218
238
  "optional": true
219
239
  }
220
240
  },
@@ -0,0 +1 @@
1
+ module.exports = require('@backstage/cli/config/eslint-factory')(__dirname);
@@ -0,0 +1,20 @@
1
+ # {{pluginId}}
2
+
3
+ Welcome to the {{pluginId}} plugin!
4
+
5
+ _This plugin was created through the Backstage CLI_
6
+
7
+ ## Getting started
8
+
9
+ Your plugin has been added to the app in this repository, meaning you'll be able
10
+ to access it by running `yarn start` in the root directory, and then navigating
11
+ to [/{{pluginId}}](http://localhost:3000/{{pluginId}}).
12
+
13
+ This plugin is built with Backstage's [new frontend
14
+ system](https://backstage.io/docs/frontend-system/architecture/index), and you
15
+ can find more information about building plugins in the [plugin builder
16
+ documentation](https://backstage.io/docs/frontend-system/building-plugins/index).
17
+
18
+ You can also serve the plugin in isolation by running `yarn start` in the plugin directory.
19
+ This method of serving the plugin provides quicker iteration speed and a faster startup and hot reloads.
20
+ It is only meant for local development, and the setup for it can be found inside the [/dev](./dev) directory.
@@ -0,0 +1,10 @@
1
+ import { createApp } from '@backstage/frontend-defaults';
2
+ import ReactDOM from 'react-dom';
3
+
4
+ import plugin from '../src';
5
+
6
+ const app = createApp({
7
+ features: [plugin],
8
+ });
9
+
10
+ ReactDOM.render(app.createRoot(), document.getElementById('root'));
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "{{packageName}}",
3
+ "main": "src/index.ts",
4
+ "types": "src/index.ts",
5
+ "publishConfig": {
6
+ "access": "public",
7
+ "main": "dist/index.esm.js",
8
+ "types": "dist/index.d.ts"
9
+ },
10
+ "backstage": {
11
+ "role": "frontend-plugin",
12
+ "pluginId": "{{pluginId}}"
13
+ },
14
+ "sideEffects": false,
15
+ "scripts": {
16
+ "start": "backstage-cli package start",
17
+ "build": "backstage-cli package build",
18
+ "lint": "backstage-cli package lint",
19
+ "test": "backstage-cli package test",
20
+ "clean": "backstage-cli package clean",
21
+ "prepack": "backstage-cli package prepack",
22
+ "postpack": "backstage-cli package postpack"
23
+ },
24
+ "dependencies": {
25
+ "@backstage/core-components": "{{versionQuery '@backstage/core-components'}}",
26
+ "@backstage/frontend-plugin-api": "{{versionQuery '@backstage/frontend-plugin-api'}}",
27
+ "@backstage/theme": "{{versionQuery '@backstage/theme'}}",
28
+ "@material-ui/core": "{{versionQuery '@material-ui/core' '4.12.2'}}",
29
+ "@material-ui/icons": "{{versionQuery '@material-ui/icons' '4.9.1'}}",
30
+ "@material-ui/lab": "{{versionQuery '@material-ui/lab' '4.0.0-alpha.61'}}",
31
+ "react-use": "{{versionQuery 'react-use' '17.2.4'}}"
32
+ },
33
+ "peerDependencies": {
34
+ "react": "{{versionQuery 'react' '^16.13.1 || ^17.0.0 || ^18.0.0'}}"
35
+ },
36
+ "devDependencies": {
37
+ "@backstage/cli": "{{versionQuery '@backstage/cli'}}",
38
+ "@backstage/frontend-defaults": "{{versionQuery '@backstage/frontend-defaults'}}",
39
+ "@backstage/frontend-test-utils": "{{versionQuery '@backstage/frontend-test-utils'}}",
40
+ "@testing-library/jest-dom": "{{versionQuery '@testing-library/jest-dom' '6.0.0'}}",
41
+ "@testing-library/react": "{{versionQuery '@testing-library/react' '14.0.0'}}",
42
+ "@testing-library/user-event": "{{versionQuery '@testing-library/user-event' '14.0.0'}}",
43
+ "msw": "{{versionQuery 'msw' '1.0.0'}}",
44
+ "react": "{{versionQuery 'react' '^16.13.1 || ^17.0.0 || ^18.0.0'}}"
45
+ },
46
+ "files": [
47
+ "dist"
48
+ ]
49
+ }
@@ -0,0 +1,5 @@
1
+ name: frontend-plugin
2
+ role: frontend-plugin
3
+ description: A new frontend plugin
4
+ values:
5
+ pluginVar: '{{ camelCase pluginId }}Plugin'
@@ -0,0 +1,28 @@
1
+ import { ExampleComponent } from './ExampleComponent';
2
+ import { rest } from 'msw';
3
+ import { setupServer } from 'msw/node';
4
+ import { screen } from '@testing-library/react';
5
+ import {
6
+ registerMswTestHooks,
7
+ renderInTestApp,
8
+ } from '@backstage/frontend-test-utils';
9
+
10
+ describe('ExampleComponent', () => {
11
+ const server = setupServer();
12
+ // Enable sane handlers for network requests
13
+ registerMswTestHooks(server);
14
+
15
+ // setup mock response
16
+ beforeEach(() => {
17
+ server.use(
18
+ rest.get('/*', (_, res, ctx) => res(ctx.status(200), ctx.json({}))),
19
+ );
20
+ });
21
+
22
+ it('should render', async () => {
23
+ await renderInTestApp(<ExampleComponent />);
24
+ expect(
25
+ screen.getByText('Welcome to {{pluginId}}!'),
26
+ ).toBeInTheDocument();
27
+ });
28
+ });
@@ -0,0 +1,37 @@
1
+ import { Typography, Grid } from '@material-ui/core';
2
+ import {
3
+ InfoCard,
4
+ Header,
5
+ Page,
6
+ Content,
7
+ ContentHeader,
8
+ HeaderLabel,
9
+ SupportButton,
10
+ } from '@backstage/core-components';
11
+ import { ExampleFetchComponent } from '../ExampleFetchComponent';
12
+
13
+ export const ExampleComponent = () => (
14
+ <Page themeId="tool">
15
+ <Header title="Welcome to {{pluginId}}!" subtitle="Optional subtitle">
16
+ <HeaderLabel label="Owner" value="Team X" />
17
+ <HeaderLabel label="Lifecycle" value="Alpha" />
18
+ </Header>
19
+ <Content>
20
+ <ContentHeader title="Plugin title">
21
+ <SupportButton>A description of your plugin goes here.</SupportButton>
22
+ </ContentHeader>
23
+ <Grid container spacing={3} direction="column">
24
+ <Grid item>
25
+ <InfoCard title="Information card">
26
+ <Typography variant="body1">
27
+ All content should be wrapped in a card like this.
28
+ </Typography>
29
+ </InfoCard>
30
+ </Grid>
31
+ <Grid item>
32
+ <ExampleFetchComponent />
33
+ </Grid>
34
+ </Grid>
35
+ </Content>
36
+ </Page>
37
+ );
@@ -0,0 +1 @@
1
+ export { ExampleComponent } from './ExampleComponent';
@@ -0,0 +1,19 @@
1
+ import { renderInTestApp } from '@backstage/frontend-test-utils';
2
+ import { ExampleFetchComponent } from './ExampleFetchComponent';
3
+
4
+ describe('ExampleFetchComponent', () => {
5
+ it('renders the user table', async () => {
6
+ const { getAllByText, getByAltText, getByText, findByRole } =
7
+ await renderInTestApp(<ExampleFetchComponent />);
8
+
9
+ // Wait for the table to render
10
+ const table = await findByRole('table');
11
+ const nationality = getAllByText('GB');
12
+ // Assert that the table contains the expected user data
13
+ expect(table).toBeInTheDocument();
14
+ expect(getByAltText('Carolyn')).toBeInTheDocument();
15
+ expect(getByText('Carolyn Moore')).toBeInTheDocument();
16
+ expect(getByText('carolyn.moore@example.com')).toBeInTheDocument();
17
+ expect(nationality[0]).toBeInTheDocument();
18
+ });
19
+ });