@nocobase/build 2.1.0-beta.15 → 2.1.0-beta.16

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/lib/build.js CHANGED
@@ -28,12 +28,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
28
28
  var build_exports = {};
29
29
  __export(build_exports, {
30
30
  build: () => build,
31
- buildPackage: () => buildPackage,
32
31
  buildPackages: () => buildPackages
33
32
  });
34
33
  module.exports = __toCommonJS(build_exports);
35
34
  var import_chalk = __toESM(require("chalk"));
36
- var import_execa = __toESM(require("execa"));
37
35
  var import_path = __toESM(require("path"));
38
36
  var import_buildCjs = require("./buildCjs");
39
37
  var import_buildClient = require("./buildClient");
@@ -46,107 +44,297 @@ var import_utils = require("./utils");
46
44
  var import_addlicense = require("./utils/addlicense");
47
45
  var import_getPackages = require("./utils/getPackages");
48
46
  const BUILD_ERROR = "build-error";
47
+ const DEFAULT_LAYER_CONCURRENCY = 2;
48
+ const DEFAULT_PLUGIN_LAYER_CONCURRENCY = 1;
49
+ const ENABLE_BUILD_PROFILE = process.env.BUILD_PROFILE === "true";
49
50
  async function build(pkgs) {
51
+ const profile = ENABLE_BUILD_PROFILE ? (0, import_utils.createBuildProfileCollector)() : null;
52
+ const buildStart = (0, import_utils.nowMs)();
50
53
  const isDev = process.argv.includes("--development");
51
54
  process.env.NODE_ENV = isDev ? "development" : "production";
52
- let packages = (0, import_getPackages.getPackages)(pkgs);
53
- const cachePkg = (0, import_utils.readFromCache)(BUILD_ERROR);
54
- if (process.argv.includes("--retry") && cachePkg?.pkg) {
55
- packages = packages.slice(packages.findIndex((item) => item.name === cachePkg.pkg));
55
+ try {
56
+ let packages = (0, import_getPackages.getPackages)(pkgs);
57
+ const cachePkg = (0, import_utils.readFromCache)(BUILD_ERROR);
58
+ if (process.argv.includes("--retry") && cachePkg?.pkg) {
59
+ packages = packages.slice(packages.findIndex((item) => item.name === cachePkg.pkg));
60
+ }
61
+ const cliPackages = packages.find((item) => item.name === "@nocobase/cli");
62
+ if (cliPackages) {
63
+ const log = (0, import_utils.getPkgLog)(cliPackages.name);
64
+ log('running package script "build" (clean + tsc)');
65
+ await (0, import_utils.runScript)(["build"], cliPackages.location);
66
+ if (packages.length === 1) {
67
+ return;
68
+ }
69
+ }
70
+ if (packages.length === 0) {
71
+ let msg = "";
72
+ if (pkgs.length) {
73
+ msg = `'${pkgs.join(", ")}' did not match any packages`;
74
+ } else {
75
+ msg = "No package matched";
76
+ }
77
+ console.warn(import_chalk.default.yellow(`[@nocobase/build]: ${msg}`));
78
+ return;
79
+ }
80
+ const pluginPackages = (0, import_constant.getPluginPackages)(packages);
81
+ const cjsPackages = (0, import_constant.getCjsPackages)(packages);
82
+ const presetsPackages = (0, import_constant.getPresetsPackages)(packages);
83
+ await buildPackages(cjsPackages, "lib", import_buildCjs.buildCjs, {
84
+ sourceConcurrency: DEFAULT_LAYER_CONCURRENCY,
85
+ declarationConcurrency: 1,
86
+ stageName: "core cjs",
87
+ profile
88
+ });
89
+ const clientCore = packages.find((item) => item.location === import_constant.CORE_CLIENT);
90
+ if (clientCore) {
91
+ await buildSinglePackage(clientCore, "es", import_buildClient.buildClient, {
92
+ stageName: "core client",
93
+ profile
94
+ });
95
+ }
96
+ const esmPackages = packages.filter((pkg) => import_constant.ESM_PACKAGES.includes(pkg.name));
97
+ await buildPackages(esmPackages, "lib", import_buildCjs.buildCjs, {
98
+ sourceConcurrency: DEFAULT_LAYER_CONCURRENCY,
99
+ declarationConcurrency: 1,
100
+ stageName: "esm cjs",
101
+ profile
102
+ });
103
+ await buildPackages(esmPackages, "es", import_buildEsm.buildEsm, {
104
+ sourceConcurrency: DEFAULT_LAYER_CONCURRENCY,
105
+ declarationConcurrency: 1,
106
+ stageName: "esm",
107
+ profile
108
+ });
109
+ await buildPackages(pluginPackages, "dist", import_buildPlugin.buildPlugin, {
110
+ sourceConcurrency: DEFAULT_PLUGIN_LAYER_CONCURRENCY,
111
+ declarationConcurrency: 1,
112
+ stageName: "plugins",
113
+ profile
114
+ });
115
+ await buildPackages(presetsPackages, "lib", import_buildCjs.buildCjs, {
116
+ sourceConcurrency: DEFAULT_LAYER_CONCURRENCY,
117
+ declarationConcurrency: 1,
118
+ stageName: "presets",
119
+ profile
120
+ });
121
+ const appClient = packages.find((item) => item.location === import_constant.CORE_APP);
122
+ if (appClient) {
123
+ await (0, import_utils.runProfiledStage)(profile, "app shell", async () => {
124
+ await (0, import_utils.runScript)(["rsbuild", "build", "--config", import_path.default.join(import_constant.CORE_APP, "client", "rsbuild.config.ts")], import_constant.ROOT_PATH, {
125
+ APP_ROOT: import_path.default.join(import_constant.CORE_APP, "client"),
126
+ ANALYZE: process.env.BUILD_ANALYZE === "true" ? "1" : void 0
127
+ });
128
+ });
129
+ }
130
+ (0, import_utils.writeToCache)(BUILD_ERROR, {});
131
+ } finally {
132
+ if (profile) {
133
+ (0, import_utils.printBuildProfile)(profile, (0, import_utils.nowMs)() - buildStart);
134
+ }
56
135
  }
57
- if (packages.length === 0) {
58
- let msg = "";
59
- if (pkgs.length) {
60
- msg = `'${pkgs.join(", ")}' did not match any packages`;
61
- } else {
62
- msg = "No package matched";
136
+ }
137
+ async function buildPackages(packages, targetDir, doBuildPackage, options = {}) {
138
+ const {
139
+ sourceConcurrency = DEFAULT_LAYER_CONCURRENCY,
140
+ declarationConcurrency = 1,
141
+ stageName = "packages",
142
+ profile = null
143
+ } = options;
144
+ const layers = (0, import_getPackages.groupPackagesByTopoLevel)(packages);
145
+ const shouldRunDeclaration = !process.argv.includes("--no-dts") && !process.argv.includes("--only-tar");
146
+ await (0, import_utils.runProfiledStage)(profile, `${stageName} source`, async () => {
147
+ for (let index = 0; index < layers.length; index++) {
148
+ const layer = layers[index];
149
+ console.log(import_chalk.default.cyan(`[@nocobase/build]: ${stageName} source layer ${index + 1}/${layers.length} (${layer.length} packages)`));
150
+ const layerStart = (0, import_utils.nowMs)();
151
+ await (0, import_utils.runWithConcurrency)(layer, sourceConcurrency, async (pkg) => {
152
+ await buildPackageSourceLifecycle(pkg, targetDir, doBuildPackage, profile);
153
+ });
154
+ const layerDurationMs = (0, import_utils.nowMs)() - layerStart;
155
+ if (profile) {
156
+ profile.layers.push({
157
+ stageName: `${stageName} source`,
158
+ layerIndex: index + 1,
159
+ layerCount: layers.length,
160
+ packageCount: layer.length,
161
+ durationMs: layerDurationMs
162
+ });
163
+ }
164
+ if (ENABLE_BUILD_PROFILE) {
165
+ console.log(import_chalk.default.gray(`[@nocobase/build]: ${stageName} source layer ${index + 1}/${layers.length} finished in ${(0, import_utils.formatDuration)(layerDurationMs)}`));
166
+ }
63
167
  }
64
- console.warn(import_chalk.default.yellow(`[@nocobase/build]: ${msg}`));
168
+ });
169
+ if (!shouldRunDeclaration) {
65
170
  return;
66
171
  }
67
- const pluginPackages = (0, import_constant.getPluginPackages)(packages);
68
- const cjsPackages = (0, import_constant.getCjsPackages)(packages);
69
- const presetsPackages = (0, import_constant.getPresetsPackages)(packages);
70
- await buildPackages(cjsPackages, "lib", import_buildCjs.buildCjs);
71
- const clientCore = packages.find((item) => item.location === import_constant.CORE_CLIENT);
72
- if (clientCore) {
73
- await buildPackage(clientCore, "es", import_buildClient.buildClient);
74
- }
75
- const esmPackages = packages.filter((pkg) => import_constant.ESM_PACKAGES.includes(pkg.name));
76
- await buildPackages(esmPackages, "lib", import_buildCjs.buildCjs);
77
- await buildPackages(esmPackages, "es", import_buildEsm.buildEsm);
78
- await buildPackages(pluginPackages, "dist", import_buildPlugin.buildPlugin);
79
- await buildPackages(presetsPackages, "lib", import_buildCjs.buildCjs);
80
- const appClient = packages.find((item) => item.location === import_constant.CORE_APP);
81
- if (appClient) {
82
- await runScript(["umi", "build"], import_constant.ROOT_PATH, {
83
- APP_ROOT: import_path.default.join(import_constant.CORE_APP, "client"),
84
- ANALYZE: process.env.BUILD_ANALYZE === "true" ? "1" : void 0
85
- });
86
- }
87
- (0, import_utils.writeToCache)(BUILD_ERROR, {});
172
+ await (0, import_utils.runProfiledStage)(profile, `${stageName} declaration`, async () => {
173
+ for (let index = 0; index < layers.length; index++) {
174
+ const layer = layers[index];
175
+ console.log(import_chalk.default.cyan(`[@nocobase/build]: ${stageName} declaration layer ${index + 1}/${layers.length} (${layer.length} packages)`));
176
+ const layerStart = (0, import_utils.nowMs)();
177
+ await (0, import_utils.runWithConcurrency)(layer, declarationConcurrency, async (pkg) => {
178
+ await buildPackageDeclarationLifecycle(pkg, targetDir, profile);
179
+ });
180
+ const layerDurationMs = (0, import_utils.nowMs)() - layerStart;
181
+ if (profile) {
182
+ profile.layers.push({
183
+ stageName: `${stageName} declaration`,
184
+ layerIndex: index + 1,
185
+ layerCount: layers.length,
186
+ packageCount: layer.length,
187
+ durationMs: layerDurationMs
188
+ });
189
+ }
190
+ if (ENABLE_BUILD_PROFILE) {
191
+ console.log(import_chalk.default.gray(`[@nocobase/build]: ${stageName} declaration layer ${index + 1}/${layers.length} finished in ${(0, import_utils.formatDuration)(layerDurationMs)}`));
192
+ }
193
+ }
194
+ });
88
195
  }
89
- async function buildPackages(packages, targetDir, doBuildPackage) {
90
- for await (const pkg of packages) {
91
- (0, import_utils.writeToCache)(BUILD_ERROR, { pkg: pkg.name });
92
- await buildPackage(pkg, targetDir, doBuildPackage);
196
+ async function buildSinglePackage(pkg, targetDir, doBuildPackage, options) {
197
+ const { stageName, profile = null } = options;
198
+ await (0, import_utils.runProfiledStage)(profile, `${stageName} source`, async () => {
199
+ await buildPackageSourceLifecycle(pkg, targetDir, doBuildPackage, profile);
200
+ });
201
+ if (process.argv.includes("--no-dts") || process.argv.includes("--only-tar")) {
202
+ return;
93
203
  }
204
+ await (0, import_utils.runProfiledStage)(profile, `${stageName} declaration`, async () => {
205
+ await buildPackageDeclarationLifecycle(pkg, targetDir, profile);
206
+ });
94
207
  }
95
- async function buildPackage(pkg, targetDir, doBuildPackage) {
208
+ async function buildPackageSourceLifecycle(pkg, targetDir, doBuildPackage, profile = null) {
96
209
  const sourcemap = process.argv.includes("--sourcemap");
97
- const noDeclaration = process.argv.includes("--no-dts");
98
210
  const hasTar = process.argv.includes("--tar");
99
211
  const onlyTar = process.argv.includes("--only-tar");
100
212
  const log = (0, import_utils.getPkgLog)(pkg.name);
101
213
  const packageJson = (0, import_utils.getPackageJson)(pkg.location);
102
214
  if (onlyTar) {
215
+ const packageStart2 = (0, import_utils.nowMs)();
103
216
  await (0, import_tarPlugin.tarPlugin)(pkg.location, log);
217
+ if (profile) {
218
+ profile.packages.push({
219
+ name: pkg.name,
220
+ targetDir,
221
+ kind: "source",
222
+ durationMs: (0, import_utils.nowMs)() - packageStart2,
223
+ status: "success",
224
+ phases: { tar: (0, import_utils.nowMs)() - packageStart2 }
225
+ });
226
+ }
104
227
  return;
105
228
  }
106
229
  log(`${import_chalk.default.bold((0, import_utils.toUnixPath)(pkg.location.replace(import_constant.PACKAGES_PATH, "").slice(1)))} build start`);
107
230
  const userConfig = (0, import_utils.getUserConfig)(pkg.location);
231
+ const packageStart = (0, import_utils.nowMs)();
232
+ const phaseDurations = {};
233
+ let status = "success";
234
+ const runPhase = async (phaseName, task) => {
235
+ const phaseStart = (0, import_utils.nowMs)();
236
+ await task();
237
+ phaseDurations[phaseName] = (phaseDurations[phaseName] || 0) + ((0, import_utils.nowMs)() - phaseStart);
238
+ };
108
239
  if (packageJson?.scripts?.prebuild) {
109
240
  log("prebuild");
110
- await runScript(["prebuild"], pkg.location);
111
- await packageJson.prebuild(pkg.location);
241
+ await runPhase("prebuild", async () => {
242
+ await (0, import_utils.runScript)(["prebuild"], pkg.location);
243
+ await packageJson.prebuild(pkg.location);
244
+ });
112
245
  }
113
246
  if (userConfig.beforeBuild) {
114
247
  log("beforeBuild");
115
- await userConfig.beforeBuild(log);
116
- }
117
- await doBuildPackage(pkg.location, userConfig, sourcemap, log);
118
- if (!noDeclaration) {
119
- log("build declaration");
120
- await (0, import_buildDeclaration.buildDeclaration)(pkg.location, targetDir);
121
- }
122
- if (packageJson?.scripts?.postbuild) {
123
- log("postbuild");
124
- await runScript(["postbuild"], pkg.location);
125
- }
126
- if (userConfig.afterBuild) {
127
- log("afterBuild");
128
- await userConfig.afterBuild(log);
248
+ await runPhase("beforeBuild", async () => {
249
+ await userConfig.beforeBuild(log);
250
+ });
129
251
  }
130
- await (0, import_addlicense.addLicense)(import_path.default.join(pkg.location, targetDir), log);
131
- if (hasTar) {
132
- await (0, import_tarPlugin.tarPlugin)(pkg.location, log);
252
+ try {
253
+ await runPhase("build", async () => {
254
+ await doBuildPackage(pkg.location, userConfig, sourcemap, log);
255
+ });
256
+ if (packageJson?.scripts?.postbuild) {
257
+ log("postbuild");
258
+ await runPhase("postbuild", async () => {
259
+ await (0, import_utils.runScript)(["postbuild"], pkg.location);
260
+ });
261
+ }
262
+ if (userConfig.afterBuild) {
263
+ log("afterBuild");
264
+ await runPhase("afterBuild", async () => {
265
+ await userConfig.afterBuild(log);
266
+ });
267
+ }
268
+ await runPhase("addLicense", async () => {
269
+ await (0, import_addlicense.addLicense)(import_path.default.join(pkg.location, targetDir), log);
270
+ });
271
+ if (hasTar) {
272
+ await runPhase("tar", async () => {
273
+ await (0, import_tarPlugin.tarPlugin)(pkg.location, log);
274
+ });
275
+ }
276
+ } catch (error) {
277
+ status = "failed";
278
+ (0, import_utils.writeToCache)(BUILD_ERROR, { pkg: pkg.name });
279
+ throw error;
280
+ } finally {
281
+ if (profile) {
282
+ profile.packages.push({
283
+ name: pkg.name,
284
+ targetDir,
285
+ kind: "source",
286
+ durationMs: (0, import_utils.nowMs)() - packageStart,
287
+ status,
288
+ phases: phaseDurations
289
+ });
290
+ if (ENABLE_BUILD_PROFILE) {
291
+ const summary = Object.entries(phaseDurations).sort((a, b) => b[1] - a[1]).map(([name, duration]) => `${name}=${(0, import_utils.formatDuration)(duration)}`).join(", ");
292
+ console.log(
293
+ import_chalk.default.gray(
294
+ `[@nocobase/build:profile] ${pkg.name} ${status} in ${(0, import_utils.formatDuration)((0, import_utils.nowMs)() - packageStart)}${summary ? ` (${summary})` : ""}`
295
+ )
296
+ );
297
+ }
298
+ }
133
299
  }
134
300
  }
135
- function runScript(args, cwd, envs = {}) {
136
- return (0, import_execa.default)("yarn", args, {
137
- cwd,
138
- stdio: "inherit",
139
- env: {
140
- ...process.env,
141
- ...envs,
142
- sourcemap: process.argv.includes("--sourcemap") ? "sourcemap" : void 0,
143
- NODE_ENV: process.env.NODE_ENV || "production"
301
+ async function buildPackageDeclarationLifecycle(pkg, targetDir, profile = null) {
302
+ const log = (0, import_utils.getPkgLog)(pkg.name);
303
+ const packageStart = (0, import_utils.nowMs)();
304
+ const phaseDurations = {};
305
+ let status = "success";
306
+ try {
307
+ log("build declaration");
308
+ const phaseStart = (0, import_utils.nowMs)();
309
+ await (0, import_buildDeclaration.buildDeclaration)(pkg.location, targetDir);
310
+ phaseDurations.declaration = (0, import_utils.nowMs)() - phaseStart;
311
+ } catch (error) {
312
+ status = "failed";
313
+ (0, import_utils.writeToCache)(BUILD_ERROR, { pkg: pkg.name });
314
+ throw error;
315
+ } finally {
316
+ if (profile) {
317
+ profile.packages.push({
318
+ name: pkg.name,
319
+ targetDir,
320
+ kind: "declaration",
321
+ durationMs: (0, import_utils.nowMs)() - packageStart,
322
+ status,
323
+ phases: phaseDurations
324
+ });
325
+ if (ENABLE_BUILD_PROFILE) {
326
+ const summary = Object.entries(phaseDurations).sort((a, b) => b[1] - a[1]).map(([name, duration]) => `${name}=${(0, import_utils.formatDuration)(duration)}`).join(", ");
327
+ console.log(
328
+ import_chalk.default.gray(
329
+ `[@nocobase/build:profile] ${pkg.name} declaration ${status} in ${(0, import_utils.formatDuration)((0, import_utils.nowMs)() - packageStart)}${summary ? ` (${summary})` : ""}`
330
+ )
331
+ );
332
+ }
144
333
  }
145
- });
334
+ }
146
335
  }
147
336
  // Annotate the CommonJS export names for ESM import in node:
148
337
  0 && (module.exports = {
149
338
  build,
150
- buildPackage,
151
339
  buildPackages
152
340
  });
@@ -31,13 +31,14 @@ __export(buildClient_exports, {
31
31
  buildLocale: () => buildLocale
32
32
  });
33
33
  module.exports = __toCommonJS(buildClient_exports);
34
- var import_plugin_react = __toESM(require("@vitejs/plugin-react"));
34
+ var import_core = require("@rsbuild/core");
35
+ var import_plugin_less = require("@rsbuild/plugin-less");
36
+ var import_plugin_react = require("@rsbuild/plugin-react");
37
+ var import_plugin_svgr = require("@rsbuild/plugin-svgr");
35
38
  var import_fast_glob = __toESM(require("fast-glob"));
36
39
  var import_fs_extra = __toESM(require("fs-extra"));
37
40
  var import_path = __toESM(require("path"));
38
41
  var import_tsup = require("tsup");
39
- var import_vite = require("vite");
40
- var import_vite_plugin_lib_inject_css = require("vite-plugin-lib-inject-css");
41
42
  var import_constant = require("./constant");
42
43
  var import_utils = require("./utils");
43
44
  async function buildClient(cwd, userConfig, sourcemap = false, log) {
@@ -45,7 +46,7 @@ async function buildClient(cwd, userConfig, sourcemap = false, log) {
45
46
  const cwdWin = cwd.replaceAll(/\\/g, "/");
46
47
  const cwdUnix = cwd.replaceAll(/\//g, "\\");
47
48
  const external = function(id) {
48
- if (id.startsWith(".") || id.startsWith(cwdUnix) || id.startsWith(cwdWin)) {
49
+ if (!id || import_path.default.isAbsolute(id) || id.startsWith(".") || id.startsWith(cwdUnix) || id.startsWith(cwdWin)) {
49
50
  return false;
50
51
  }
51
52
  return true;
@@ -54,35 +55,12 @@ async function buildClient(cwd, userConfig, sourcemap = false, log) {
54
55
  await buildClientLib(cwd, userConfig, sourcemap, external, log);
55
56
  await buildLocale(cwd, userConfig, log);
56
57
  }
57
- function buildClientEsm(cwd, userConfig, sourcemap, external, log) {
58
+ async function buildClientEsm(cwd, userConfig, sourcemap, external, log) {
58
59
  log("build client esm");
59
60
  const entry = import_path.default.join(cwd, "src/index.ts").replaceAll(/\\/g, "/");
60
61
  const outDir = import_path.default.resolve(cwd, "es");
61
- return (0, import_vite.build)(
62
- userConfig.modifyViteConfig({
63
- mode: process.env.NODE_ENV || "production",
64
- define: (0, import_utils.getEnvDefine)(),
65
- build: {
66
- minify: process.env.NODE_ENV === "production",
67
- outDir,
68
- cssCodeSplit: true,
69
- emptyOutDir: true,
70
- sourcemap,
71
- lib: {
72
- entry,
73
- formats: ["es"],
74
- fileName: "index"
75
- },
76
- target: ["es2015", "edge88", "firefox78", "chrome87", "safari14"],
77
- rollupOptions: {
78
- cache: true,
79
- treeshake: true,
80
- external
81
- }
82
- },
83
- plugins: [(0, import_plugin_react.default)(), (0, import_vite_plugin_lib_inject_css.libInjectCss)()]
84
- })
85
- );
62
+ await buildClientWithRsbuild(cwd, userConfig, sourcemap, external, entry, outDir, "esm");
63
+ await injectEntryStyleReference(import_path.default.join(outDir, "index.mjs"), 'import "./index.css";');
86
64
  }
87
65
  async function buildClientLib(cwd, userConfig, sourcemap, external, log) {
88
66
  log("build client lib");
@@ -91,32 +69,114 @@ async function buildClientLib(cwd, userConfig, sourcemap, external, log) {
91
69
  const entry = import_path.default.join(esDir, "index.ts");
92
70
  import_fs_extra.default.removeSync(entry);
93
71
  import_fs_extra.default.linkSync(import_path.default.join(cwd, "es/index.mjs"), entry);
94
- await (0, import_vite.build)(
95
- userConfig.modifyViteConfig({
96
- mode: process.env.NODE_ENV || "production",
97
- esbuild: {
98
- format: "cjs"
72
+ try {
73
+ await buildClientWithRsbuild(cwd, userConfig, sourcemap, external, entry, outDir, "cjs");
74
+ } finally {
75
+ import_fs_extra.default.removeSync(entry);
76
+ }
77
+ await injectEntryStyleReference(import_path.default.join(outDir, "index.js"), 'require("./index.css");');
78
+ }
79
+ async function buildClientWithRsbuild(cwd, userConfig, sourcemap, external, entry, outDir, format) {
80
+ const config = createClientRsbuildConfig(cwd, entry, outDir, sourcemap, external, format);
81
+ const rsbuild = await (0, import_core.createRsbuild)({
82
+ cwd,
83
+ config: userConfig.modifyRsbuildConfig?.(config) ?? config
84
+ });
85
+ const result = await rsbuild.build();
86
+ await result.close();
87
+ }
88
+ function createClientRsbuildConfig(cwd, entry, outDir, sourcemap, external, format) {
89
+ return {
90
+ plugins: [(0, import_plugin_react.pluginReact)(), (0, import_plugin_less.pluginLess)(), (0, import_plugin_svgr.pluginSvgr)()],
91
+ source: {
92
+ entry: {
93
+ index: {
94
+ import: entry,
95
+ html: false
96
+ }
97
+ },
98
+ tsconfigPath: import_path.default.join(cwd, "tsconfig.json"),
99
+ define: (0, import_utils.getEnvDefine)(),
100
+ decorators: {
101
+ version: "legacy"
102
+ }
103
+ },
104
+ output: {
105
+ target: "web",
106
+ distPath: {
107
+ root: outDir,
108
+ js: ".",
109
+ jsAsync: ".",
110
+ css: ".",
111
+ cssAsync: ".",
112
+ svg: ".",
113
+ font: ".",
114
+ image: ".",
115
+ media: ".",
116
+ assets: "."
99
117
  },
100
- build: {
101
- outDir,
102
- minify: process.env.NODE_ENV === "production",
103
- sourcemap,
104
- lib: {
105
- entry: import_path.default.join(cwd, "es/index.ts"),
106
- formats: ["cjs"],
107
- fileName: "index"
108
- },
109
- rollupOptions: {
110
- external
118
+ filename: {
119
+ js: format === "esm" ? "[name].mjs" : "[name].js",
120
+ css: "[name].css",
121
+ svg: "[name][ext][query]",
122
+ font: "[name][ext][query]",
123
+ image: "[name][ext][query]",
124
+ media: "[name][ext][query]",
125
+ assets: "[name][ext][query]"
126
+ },
127
+ cleanDistPath: true,
128
+ sourceMap: sourcemap,
129
+ minify: process.env.NODE_ENV === "production",
130
+ emitCss: true,
131
+ externals: [
132
+ function({ request }, callback) {
133
+ if (request && external(request)) {
134
+ return callback(null, true);
135
+ }
136
+ callback();
111
137
  }
138
+ ]
139
+ },
140
+ performance: {
141
+ chunkSplit: {
142
+ strategy: "all-in-one"
112
143
  }
113
- })
114
- );
115
- import_fs_extra.default.removeSync(entry);
116
- const css = import_fast_glob.default.sync("*.css", { cwd: esDir, absolute: true });
117
- css.forEach((file) => {
118
- import_fs_extra.default.copySync(file, import_path.default.join(outDir, import_path.default.basename(file)));
119
- });
144
+ },
145
+ tools: {
146
+ rspack(config) {
147
+ config.output = config.output || {};
148
+ config.output.asyncChunks = false;
149
+ if (format === "esm") {
150
+ config.output.library = { type: "module" };
151
+ config.output.module = true;
152
+ config.output.chunkFormat = "module";
153
+ config.output.chunkLoading = "import";
154
+ config.output.workerChunkLoading = "import";
155
+ config.experiments = {
156
+ ...config.experiments,
157
+ outputModule: true
158
+ };
159
+ config.externalsType = "module-import";
160
+ } else {
161
+ config.output.library = { type: "commonjs-static" };
162
+ }
163
+ config.performance = false;
164
+ config.stats = "errors-warnings";
165
+ }
166
+ }
167
+ };
168
+ }
169
+ async function injectEntryStyleReference(entryFile, styleReference) {
170
+ const cssFile = import_path.default.join(import_path.default.dirname(entryFile), "index.css");
171
+ if (!import_fs_extra.default.existsSync(entryFile) || !import_fs_extra.default.existsSync(cssFile)) {
172
+ return;
173
+ }
174
+ const content = await import_fs_extra.default.readFile(entryFile, "utf8");
175
+ if (content.startsWith(styleReference)) {
176
+ return;
177
+ }
178
+ await import_fs_extra.default.writeFile(entryFile, `${styleReference}
179
+ ${content}`);
120
180
  }
121
181
  function buildLocale(cwd, userConfig, log) {
122
182
  log("build client locale");
@@ -53,7 +53,11 @@ const diagnosticHost = {
53
53
  getCanonicalFileName: (fileName) => import_typescript.default.sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase(),
54
54
  getNewLine: () => import_typescript.default.sys.newLine
55
55
  };
56
+ let cachedBaseCompilerOptions = null;
56
57
  function loadCompilerOptions() {
58
+ if (cachedBaseCompilerOptions) {
59
+ return { ...cachedBaseCompilerOptions };
60
+ }
57
61
  const configPath = import_path.default.join(import_constant.ROOT_PATH, "tsconfig.json");
58
62
  const configFile = import_typescript.default.readConfigFile(configPath, import_typescript.default.sys.readFile);
59
63
  if (configFile.error) {
@@ -70,7 +74,8 @@ function loadCompilerOptions() {
70
74
  ...parsedConfig.options
71
75
  };
72
76
  delete options.paths;
73
- return options;
77
+ cachedBaseCompilerOptions = Object.freeze({ ...options });
78
+ return { ...cachedBaseCompilerOptions };
74
79
  }
75
80
  const buildDeclaration = async (cwd, targetDir) => {
76
81
  const srcPath = import_path.default.join(cwd, "src");
@@ -92,7 +97,17 @@ const buildDeclaration = async (cwd, targetDir) => {
92
97
  outDir: targetPath,
93
98
  rootDir: srcPath
94
99
  };
95
- const program = import_typescript.default.createProgram(files, compilerOptions);
100
+ const host = import_typescript.default.createCompilerHost(compilerOptions);
101
+ const originalDirectoryExists = host.directoryExists?.bind(host);
102
+ const rootPrefix = import_constant.ROOT_PATH.endsWith(import_path.default.sep) ? import_constant.ROOT_PATH : import_constant.ROOT_PATH + import_path.default.sep;
103
+ host.directoryExists = (dirPath) => {
104
+ const resolved = import_path.default.resolve(dirPath);
105
+ if (resolved !== import_constant.ROOT_PATH && !resolved.startsWith(rootPrefix) && resolved.includes(`${import_path.default.sep}node_modules`)) {
106
+ return false;
107
+ }
108
+ return originalDirectoryExists ? originalDirectoryExists(dirPath) : import_typescript.default.sys.directoryExists(dirPath);
109
+ };
110
+ const program = import_typescript.default.createProgram(files, compilerOptions, host);
96
111
  const emitResult = program.emit(void 0, void 0, void 0, true);
97
112
  const diagnostics = import_typescript.default.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
98
113
  if (diagnostics.length) {
@@ -51,10 +51,29 @@ var import_utils = require("./utils");
51
51
  var import_buildPluginUtils = require("./utils/buildPluginUtils");
52
52
  var import_getDepsConfig = require("./utils/getDepsConfig");
53
53
  var import_obfuscationResult = require("./utils/obfuscationResult");
54
+ var import_injectPublicPathPlugin = require("./injectPublicPathPlugin");
54
55
  const validExts = [".ts", ".tsx", ".js", ".jsx", ".mjs"];
55
- const serverGlobalFiles = ["src/**", "!src/client/**", ...import_constant.globExcludeFiles];
56
- const clientGlobalFiles = ["src/**", "!src/server/**", ...import_constant.globExcludeFiles];
56
+ const serverGlobalFiles = ["src/**", "!src/client/**", "!src/client-v2/**", ...import_constant.globExcludeFiles];
57
57
  const sourceGlobalFiles = ["src/**/*.{ts,js,tsx,jsx,mjs}", "!src/**/__tests__", "!src/**/__benchmarks__"];
58
+ const pluginClientLaneConfig = {
59
+ client: {
60
+ distDir: "client",
61
+ entryDir: "client",
62
+ rootEntryFile: "client.js",
63
+ externalSubpaths: ["client"]
64
+ },
65
+ "client-v2": {
66
+ distDir: "client-v2",
67
+ entryDir: "client-v2",
68
+ rootEntryFile: "client-v2.js",
69
+ externalSubpaths: ["client", "client-v2"]
70
+ }
71
+ };
72
+ function getClientGlobalFiles(lane) {
73
+ const entryDir = pluginClientLaneConfig[lane].entryDir;
74
+ const excludedClientDirs = Object.values(pluginClientLaneConfig).map((item) => item.entryDir).filter((dir) => dir !== entryDir).map((dir) => `!src/${dir}/**`);
75
+ return ["src/**", "!src/server/**", ...excludedClientDirs, ...import_constant.globExcludeFiles];
76
+ }
58
77
  const external = [
59
78
  // nocobase
60
79
  "@nocobase/ai",
@@ -152,7 +171,8 @@ const external = [
152
171
  "@langchain/anthropic",
153
172
  "@langchain/google-genai",
154
173
  "@langchain/deepseek",
155
- "@langchain/ollama"
174
+ "@langchain/ollama",
175
+ "@langchain/mcp-adapters"
156
176
  ];
157
177
  const pluginPrefix = (process.env.PLUGIN_PACKAGE_PREFIX || "@nocobase/plugin-,@nocobase/preset-,@nocobase/plugin-pro-").split(",");
158
178
  const target_dir = "dist";
@@ -243,7 +263,19 @@ function deleteServerFiles(cwd, log) {
243
263
  deep: 1,
244
264
  onlyDirectories: true
245
265
  });
246
- [...files, ...dirs].forEach((item) => {
266
+ const extraClientDirs = import_fast_glob.default.globSync(["client-v2"], {
267
+ cwd: import_path.default.join(cwd, target_dir),
268
+ absolute: true,
269
+ deep: 1,
270
+ onlyDirectories: true
271
+ });
272
+ [...files, ...dirs.filter((item) => !extraClientDirs.includes(item)), ...extraClientDirs].forEach((item) => {
273
+ if (item.endsWith(`${import_path.default.sep}client-v2`)) {
274
+ return;
275
+ }
276
+ if (item.endsWith(`${import_path.default.sep}client`)) {
277
+ return;
278
+ }
247
279
  import_fs_extra.default.removeSync(item);
248
280
  });
249
281
  }
@@ -468,9 +500,27 @@ async function buildProPluginServer(cwd, userConfig, sourcemap, log) {
468
500
  import_fs_extra.default.removeSync(tsconfig.path);
469
501
  await buildServerDeps(cwd, serverFiles, log);
470
502
  }
471
- async function buildPluginClient(cwd, userConfig, sourcemap, log, isCommercial = false) {
472
- log("build plugin client");
503
+ async function buildPluginClient(cwd, userConfig, sourcemap, log, lane = "client", isCommercial = false) {
504
+ const laneConfig = pluginClientLaneConfig[lane];
505
+ const entryDir = import_path.default.join(cwd, "src", laneConfig.entryDir);
506
+ const rootEntryFile = import_path.default.join(cwd, laneConfig.rootEntryFile);
507
+ if (!import_fs_extra.default.existsSync(rootEntryFile)) {
508
+ log("skip plugin %s build, root entry not found", lane);
509
+ return false;
510
+ }
511
+ if (!import_fs_extra.default.existsSync(entryDir)) {
512
+ log("Missing %s. Please create it.", import_chalk.default.red(`src/${laneConfig.entryDir}`));
513
+ process.exit(-1);
514
+ }
515
+ const entry = import_fast_glob.default.globSync("index.{ts,tsx,js,jsx}", { absolute: false, cwd: entryDir });
516
+ if (!entry[0]) {
517
+ log("Missing %s entry file.", import_chalk.default.red(`src/${laneConfig.entryDir}/index.{ts,tsx,js,jsx}`));
518
+ process.exit(-1);
519
+ return false;
520
+ }
521
+ log("build plugin %s", lane);
473
522
  const packageJson = (0, import_utils.getPackageJson)(cwd);
523
+ const clientGlobalFiles = getClientGlobalFiles(lane);
474
524
  const clientFiles = import_fast_glob.default.globSync(clientGlobalFiles, { cwd, absolute: true });
475
525
  if (isCommercial) {
476
526
  const commercialFiles = import_fast_glob.default.globSync(clientGlobalFiles, {
@@ -483,22 +533,23 @@ async function buildPluginClient(cwd, userConfig, sourcemap, log, isCommercial =
483
533
  const sourcePackages = (0, import_buildPluginUtils.getPackagesFromFiles)(clientFileSource);
484
534
  const excludePackages = (0, import_buildPluginUtils.getExcludePackages)(sourcePackages, external, pluginPrefix);
485
535
  (0, import_buildPluginUtils.checkRequire)(clientFiles, log);
486
- (0, import_buildPluginUtils.buildCheck)({ cwd, packageJson, entry: "client", files: clientFiles, log });
487
- const outDir = import_path.default.join(cwd, target_dir, "client");
536
+ (0, import_buildPluginUtils.buildCheck)({ cwd, packageJson, entry: lane, files: clientFiles, log });
537
+ const outDir = import_path.default.join(cwd, target_dir, laneConfig.distDir);
488
538
  const globals = excludePackages.reduce((prev, curr) => {
489
539
  if (curr.startsWith("@nocobase")) {
490
- prev[`${curr}/client`] = `${curr}/client`;
540
+ laneConfig.externalSubpaths.forEach((subpath) => {
541
+ prev[`${curr}/${subpath}`] = `${curr}/${subpath}`;
542
+ });
491
543
  }
492
544
  prev[curr] = curr;
493
545
  return prev;
494
546
  }, {});
495
- const entry = import_fast_glob.default.globSync("index.{ts,tsx,js,jsx}", { absolute: false, cwd: import_path.default.join(cwd, "src/client") });
496
547
  const outputFileName = "index.js";
497
548
  const compiler = (0, import_core.rspack)({
498
549
  mode: "production",
499
550
  // mode: "development",
500
551
  context: cwd,
501
- entry: "./src/client/" + entry[0],
552
+ entry: `./src/${laneConfig.entryDir}/` + entry[0],
502
553
  target: ["web", "es5"],
503
554
  output: {
504
555
  path: outDir,
@@ -580,18 +631,6 @@ async function buildPluginClient(cwd, userConfig, sourcemap, log, isCommercial =
580
631
  // *.svg?react
581
632
  use: ["@svgr/webpack"]
582
633
  },
583
- {
584
- test: /\.(?:js|mjs|cjs|ts|tsx)$/,
585
- exclude: /node_modules/,
586
- use: {
587
- loader: "babel-loader",
588
- options: {
589
- targets: "defaults",
590
- // presets: [['@babel/preset-env']],
591
- plugins: ["react-imported-component/babel"]
592
- }
593
- }
594
- },
595
634
  {
596
635
  test: /\.jsx$/,
597
636
  exclude: /[\\/]node_modules[\\/]/,
@@ -671,27 +710,7 @@ async function buildPluginClient(cwd, userConfig, sourcemap, log, isCommercial =
671
710
  "process.env.NODE_ENV": JSON.stringify("production"),
672
711
  "process.env.NODE_DEBUG": false
673
712
  }),
674
- {
675
- apply(compiler2) {
676
- compiler2.hooks.compilation.tap("CustomPublicPathPlugin", (compilation) => {
677
- compilation.hooks.runtimeModule.tap("CustomPublicPathPlugin", (module2) => {
678
- if (module2.name === "auto_public_path") {
679
- module2.source = {
680
- source: `
681
- __webpack_require__.p = (function() {
682
- var publicPath = window['__webpack_public_path__'] || '/';
683
- // \u786E\u4FDD\u8DEF\u5F84\u4EE5 / \u7ED3\u5C3E
684
- if (!publicPath.endsWith('/')) {
685
- publicPath += '/';
686
- }
687
- return publicPath + 'static/plugins/${packageJson.name}/dist/client/';
688
- })();`
689
- };
690
- }
691
- });
692
- });
693
- }
694
- },
713
+ new import_injectPublicPathPlugin.AutoInjectPublicPathPlugin(packageJson.name, laneConfig.distDir),
695
714
  process.env.BUILD_ANALYZE === "true" && new import_rspack_plugin.RsdoctorRspackPlugin({
696
715
  // plugin options
697
716
  // supports: {
@@ -728,10 +747,12 @@ __webpack_require__.p = (function() {
728
747
  }
729
748
  async function buildPlugin(cwd, userConfig, sourcemap, log) {
730
749
  if (cwd.includes("/pro-plugins/") && import_fs_extra.default.existsSync(import_path.default.join(process.cwd(), "packages/pro-plugins/", import_constant.PLUGIN_COMMERCIAL))) {
731
- await buildPluginClient(cwd, userConfig, sourcemap, log, true);
750
+ await buildPluginClient(cwd, userConfig, sourcemap, log, "client", true);
751
+ await buildPluginClient(cwd, userConfig, sourcemap, log, "client-v2", true);
732
752
  await buildProPluginServer(cwd, userConfig, sourcemap, log);
733
753
  } else {
734
- await buildPluginClient(cwd, userConfig, sourcemap, log);
754
+ await buildPluginClient(cwd, userConfig, sourcemap, log, "client");
755
+ await buildPluginClient(cwd, userConfig, sourcemap, log, "client-v2");
735
756
  await buildPluginServer(cwd, userConfig, sourcemap, log);
736
757
  }
737
758
  writeExternalPackageVersion(cwd, log);
package/lib/constant.js CHANGED
@@ -30,6 +30,7 @@ __export(constant_exports, {
30
30
  CJS_EXCLUDE_PACKAGES: () => CJS_EXCLUDE_PACKAGES,
31
31
  CORE_APP: () => CORE_APP,
32
32
  CORE_CLIENT: () => CORE_CLIENT,
33
+ CORE_CLIENT_V2: () => CORE_CLIENT_V2,
33
34
  ESM_PACKAGES: () => ESM_PACKAGES,
34
35
  EsbuildSupportExts: () => EsbuildSupportExts,
35
36
  NODE_MODULES: () => NODE_MODULES,
@@ -90,20 +91,31 @@ const getPluginPackages = (packages) => packages.filter((item) => PLUGINS_DIR.so
90
91
  const getPresetsPackages = (packages) => packages.filter((item) => item.location.startsWith(PRESETS_DIR));
91
92
  const CORE_APP = import_path.default.join(PACKAGES_PATH, "core/app");
92
93
  const CORE_CLIENT = import_path.default.join(PACKAGES_PATH, "core/client");
93
- const ESM_PACKAGES = ["@nocobase/test"];
94
+ const CORE_CLIENT_V2 = import_path.default.join(PACKAGES_PATH, "core/client-v2");
95
+ const ESM_PACKAGES = ["@nocobase/client-v2", "@nocobase/test"];
94
96
  const CJS_EXCLUDE_PACKAGES = [
95
97
  import_path.default.join(PACKAGES_PATH, "core/build"),
98
+ import_path.default.join(PACKAGES_PATH, "core/cli-v1"),
96
99
  import_path.default.join(PACKAGES_PATH, "core/cli"),
97
- CORE_CLIENT
100
+ CORE_CLIENT,
101
+ CORE_CLIENT_V2
98
102
  ];
99
103
  const getCjsPackages = (packages) => packages.filter((item) => !PLUGINS_DIR.some((dir) => item.location.startsWith(dir))).filter((item) => !item.location.startsWith(PRESETS_DIR)).filter((item) => !ESM_PACKAGES.includes(item.name)).filter((item) => !CJS_EXCLUDE_PACKAGES.includes(item.location));
100
104
  const tarIncludesFiles = ["package.json", "README.md", "LICENSE", "dist", "!node_modules"];
101
- const TAR_OUTPUT_DIR = process.env.TAR_PATH ? process.env.TAR_PATH : import_path.default.join(ROOT_PATH, "storage", "tar");
105
+ function resolveStorageRoot() {
106
+ const raw = process.env.STORAGE_PATH;
107
+ if (raw) {
108
+ return import_path.default.isAbsolute(raw) ? raw : import_path.default.resolve(process.cwd(), raw);
109
+ }
110
+ return import_path.default.join(ROOT_PATH, "storage");
111
+ }
112
+ const TAR_OUTPUT_DIR = process.env.TAR_PATH || import_path.default.join(resolveStorageRoot(), "tar");
102
113
  // Annotate the CommonJS export names for ESM import in node:
103
114
  0 && (module.exports = {
104
115
  CJS_EXCLUDE_PACKAGES,
105
116
  CORE_APP,
106
117
  CORE_CLIENT,
118
+ CORE_CLIENT_V2,
107
119
  ESM_PACKAGES,
108
120
  EsbuildSupportExts,
109
121
  NODE_MODULES,
package/lib/index.d.ts CHANGED
@@ -7,15 +7,14 @@
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
9
 
10
-
10
+ import type { RsbuildConfig } from '@rsbuild/core'
11
11
  import { Options as TsupConfig } from 'tsup'
12
- import { InlineConfig as ViteConfig } from 'vite'
13
12
 
14
13
  export type PkgLog = (msg: string, ...args: any[]) => void;
15
14
 
16
15
  interface UserConfig {
17
16
  modifyTsupConfig?: (config: TsupConfig) => TsupConfig;
18
- modifyViteConfig?: (config: ViteConfig) => ViteConfig;
17
+ modifyRsbuildConfig?: (config: RsbuildConfig) => RsbuildConfig;
19
18
  beforeBuild?: (log: PkgLog) => void | Promise<void>;
20
19
  afterBuild?: (log: PkgLog) => void | Promise<void>;
21
20
  }
@@ -0,0 +1,109 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var injectPublicPathPlugin_exports = {};
19
+ __export(injectPublicPathPlugin_exports, {
20
+ AutoInjectPublicPathPlugin: () => AutoInjectPublicPathPlugin
21
+ });
22
+ module.exports = __toCommonJS(injectPublicPathPlugin_exports);
23
+ function createPluginClientPublicPathDataUri(packageName, clientDistDir) {
24
+ const code = `
25
+ var publicPath = '';
26
+ var currentScript = typeof document !== 'undefined' ? document.currentScript : null;
27
+ if (currentScript && currentScript.src) {
28
+ publicPath = currentScript.src
29
+ .replace(/^blob:/, '')
30
+ .replace(/#.*$/, '')
31
+ .replace(/\\?.*$/, '')
32
+ .replace(/\\/[^\\/]+$/, '/');
33
+ }
34
+ if (!publicPath) {
35
+ var runtimeAssetBase = window['__webpack_public_path__'] || '';
36
+ if (runtimeAssetBase) {
37
+ if (runtimeAssetBase.charAt(runtimeAssetBase.length - 1) !== '/') {
38
+ runtimeAssetBase += '/';
39
+ }
40
+ publicPath = runtimeAssetBase + 'static/plugins/${packageName}/dist/${clientDistDir}/';
41
+ }
42
+ }
43
+ if (!publicPath) {
44
+ publicPath = window['__nocobase_public_path__'] || '';
45
+ if (!publicPath && window.location && window.location.pathname) {
46
+ var marker = '/v2/';
47
+ var pathname = window.location.pathname || '/';
48
+ var index = pathname.indexOf(marker);
49
+ publicPath = index >= 0 ? pathname.slice(0, index + 1) : '/';
50
+ }
51
+ if (publicPath) {
52
+ publicPath = publicPath.replace(/\\/v2\\/?$/, '/');
53
+ }
54
+ if (!publicPath) {
55
+ publicPath = '/';
56
+ }
57
+ if (publicPath.charAt(publicPath.length - 1) !== '/') {
58
+ publicPath += '/';
59
+ }
60
+ publicPath += 'static/plugins/${packageName}/dist/${clientDistDir}/';
61
+ }
62
+ __webpack_public_path__ = publicPath;
63
+ `;
64
+ return `data:text/javascript,${encodeURIComponent(code)}`;
65
+ }
66
+ function prependPluginClientPublicPathEntry(entry, packageName, clientDistDir) {
67
+ const dataUri = createPluginClientPublicPathDataUri(packageName, clientDistDir);
68
+ if (typeof entry === "string") {
69
+ return [dataUri, entry];
70
+ }
71
+ if (Array.isArray(entry)) {
72
+ return [dataUri, ...entry];
73
+ }
74
+ if (!entry || typeof entry !== "object") {
75
+ return entry;
76
+ }
77
+ const entryConfig = entry;
78
+ if (entryConfig.import) {
79
+ return {
80
+ ...entryConfig,
81
+ import: Array.isArray(entryConfig.import) ? [dataUri, ...entryConfig.import] : [dataUri, entryConfig.import]
82
+ };
83
+ }
84
+ return Object.fromEntries(
85
+ Object.entries(entryConfig).map(([name, value]) => [
86
+ name,
87
+ prependPluginClientPublicPathEntry(value, packageName, clientDistDir)
88
+ ])
89
+ );
90
+ }
91
+ class AutoInjectPublicPathPlugin {
92
+ constructor(pluginName, clientDistDir = "client") {
93
+ this.pluginName = pluginName;
94
+ this.clientDistDir = clientDistDir;
95
+ }
96
+ apply(compiler) {
97
+ compiler.hooks.environment.tap("AutoInjectPublicPathPlugin", () => {
98
+ compiler.options.entry = prependPluginClientPublicPathEntry(
99
+ compiler.options.entry,
100
+ this.pluginName,
101
+ this.clientDistDir
102
+ );
103
+ });
104
+ }
105
+ }
106
+ // Annotate the CommonJS export names for ESM import in node:
107
+ 0 && (module.exports = {
108
+ AutoInjectPublicPathPlugin
109
+ });
@@ -54,7 +54,7 @@ function isNotBuiltinModule(packageName) {
54
54
  return !import_module.builtinModules.includes(packageName);
55
55
  }
56
56
  const isValidPackageName = (str) => {
57
- const pattern = /^(?:@[a-zA-Z0-9_-]+\/)?[a-zA-Z0-9_-]+$/;
57
+ const pattern = /^(?:@[a-zA-Z0-9._-]+\/)?[a-zA-Z0-9._-]+$/;
58
58
  return pattern.test(str);
59
59
  };
60
60
  function getPackageNameFromString(str) {
@@ -76,7 +76,7 @@ function getDepsConfig(cwd, outDir, depsName, external) {
76
76
  acc[depEntryPath] = {
77
77
  nccConfig: {
78
78
  minify: true,
79
- target: "es5",
79
+ target: "es2020",
80
80
  quiet: true,
81
81
  externals: {}
82
82
  },
@@ -28,6 +28,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
28
28
  var getPackages_exports = {};
29
29
  __export(getPackages_exports, {
30
30
  getPackages: () => getPackages,
31
+ groupPackagesByTopoLevel: () => groupPackagesByTopoLevel,
31
32
  sortPackages: () => sortPackages
32
33
  });
33
34
  module.exports = __toCommonJS(getPackages_exports);
@@ -76,8 +77,55 @@ function sortPackages(packages) {
76
77
  }
77
78
  return sorter.nodes;
78
79
  }
80
+ function groupPackagesByTopoLevel(packages) {
81
+ const filteredPackages = packages.filter((pkg) => pkg.name !== "@nocobase/docs");
82
+ const packageMap = new Map(filteredPackages.map((pkg) => [pkg.name, pkg]));
83
+ const dependencyMap = /* @__PURE__ */ new Map();
84
+ const reverseDependencyMap = /* @__PURE__ */ new Map();
85
+ for (const pkg of filteredPackages) {
86
+ const pkgJson = require(`${pkg.location}/package.json`);
87
+ const internalDeps = Object.keys({
88
+ ...pkgJson.dependencies,
89
+ ...pkgJson.devDependencies,
90
+ ...pkgJson.peerDependencies
91
+ }).filter((dep) => packageMap.has(dep));
92
+ dependencyMap.set(pkg.name, new Set(internalDeps));
93
+ for (const dep of internalDeps) {
94
+ if (!reverseDependencyMap.has(dep)) {
95
+ reverseDependencyMap.set(dep, /* @__PURE__ */ new Set());
96
+ }
97
+ reverseDependencyMap.get(dep).add(pkg.name);
98
+ }
99
+ }
100
+ const remainingDeps = new Map(
101
+ Array.from(dependencyMap.entries()).map(([name, deps]) => [name, new Set(deps)])
102
+ );
103
+ const pending = new Set(filteredPackages.map((pkg) => pkg.name));
104
+ const layers = [];
105
+ while (pending.size > 0) {
106
+ const layer = Array.from(pending).filter((name) => (remainingDeps.get(name)?.size ?? 0) === 0).map((name) => packageMap.get(name)).filter(Boolean);
107
+ if (layer.length === 0) {
108
+ throw new Error(
109
+ `Unable to group packages by topo level, possible circular dependency among: ${Array.from(pending).join(", ")}`
110
+ );
111
+ }
112
+ layers.push(layer);
113
+ for (const pkg of layer) {
114
+ pending.delete(pkg.name);
115
+ const dependents = reverseDependencyMap.get(pkg.name);
116
+ if (!dependents) {
117
+ continue;
118
+ }
119
+ for (const dependent of dependents) {
120
+ remainingDeps.get(dependent)?.delete(pkg.name);
121
+ }
122
+ }
123
+ }
124
+ return layers;
125
+ }
79
126
  // Annotate the CommonJS export names for ESM import in node:
80
127
  0 && (module.exports = {
81
128
  getPackages,
129
+ groupPackagesByTopoLevel,
82
130
  sortPackages
83
131
  });
@@ -27,17 +27,25 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
27
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
28
  var utils_exports = {};
29
29
  __export(utils_exports, {
30
+ createBuildProfileCollector: () => createBuildProfileCollector,
30
31
  defineConfig: () => defineConfig,
32
+ formatDuration: () => formatDuration,
31
33
  getEnvDefine: () => getEnvDefine,
32
34
  getPackageJson: () => getPackageJson,
33
35
  getPkgLog: () => getPkgLog,
34
36
  getUserConfig: () => getUserConfig,
37
+ nowMs: () => nowMs,
38
+ printBuildProfile: () => printBuildProfile,
35
39
  readFromCache: () => readFromCache,
40
+ runProfiledStage: () => runProfiledStage,
41
+ runScript: () => runScript,
42
+ runWithConcurrency: () => runWithConcurrency,
36
43
  toUnixPath: () => toUnixPath,
37
44
  writeToCache: () => writeToCache
38
45
  });
39
46
  module.exports = __toCommonJS(utils_exports);
40
47
  var import_chalk = __toESM(require("chalk"));
48
+ var import_execa = __toESM(require("execa"));
41
49
  var import_path = __toESM(require("path"));
42
50
  var import_fast_glob = __toESM(require("fast-glob"));
43
51
  var import_fs_extra = __toESM(require("fs-extra"));
@@ -86,7 +94,7 @@ function defineConfig(config) {
86
94
  function getUserConfig(cwd) {
87
95
  const config = defineConfig({
88
96
  modifyTsupConfig: (config2) => config2,
89
- modifyViteConfig: (config2) => config2
97
+ modifyRsbuildConfig: (config2) => config2
90
98
  });
91
99
  const buildConfigs = import_fast_glob.default.sync(["build.config.js", "build.config.ts"], { cwd });
92
100
  if (buildConfigs.length > 1) {
@@ -121,14 +129,128 @@ function getEnvDefine() {
121
129
  "process.env.APP_ENV": process.env.APP_ENV
122
130
  };
123
131
  }
132
+ function createBuildProfileCollector() {
133
+ return {
134
+ stages: [],
135
+ layers: [],
136
+ packages: []
137
+ };
138
+ }
139
+ async function runProfiledStage(profile, stageName, task) {
140
+ const startedAt = nowMs();
141
+ await task();
142
+ if (profile) {
143
+ profile.stages.push({
144
+ name: stageName,
145
+ durationMs: nowMs() - startedAt
146
+ });
147
+ }
148
+ }
149
+ async function runWithConcurrency(items, concurrency, worker) {
150
+ const queue = [...items];
151
+ const workers = Array.from({ length: Math.min(concurrency, queue.length) }, async () => {
152
+ while (queue.length > 0) {
153
+ const item = queue.shift();
154
+ if (!item) {
155
+ return;
156
+ }
157
+ await worker(item);
158
+ }
159
+ });
160
+ await Promise.all(workers);
161
+ }
162
+ function printBuildProfile(profile, totalDurationMs) {
163
+ const phaseTotals = /* @__PURE__ */ new Map();
164
+ for (const pkg of profile.packages) {
165
+ for (const [phaseName, duration] of Object.entries(pkg.phases)) {
166
+ phaseTotals.set(phaseName, (phaseTotals.get(phaseName) || 0) + duration);
167
+ }
168
+ }
169
+ console.log(import_chalk.default.cyan(`[@nocobase/build:profile] total build time ${formatDuration(totalDurationMs)}`));
170
+ if (profile.stages.length > 0) {
171
+ console.log(import_chalk.default.cyan("[@nocobase/build:profile] stage totals"));
172
+ for (const stage of [...profile.stages].sort((a, b) => b.durationMs - a.durationMs)) {
173
+ console.log(import_chalk.default.gray(` ${stage.name}: ${formatDuration(stage.durationMs)}`));
174
+ }
175
+ }
176
+ if (profile.layers.length > 0) {
177
+ console.log(import_chalk.default.cyan("[@nocobase/build:profile] slowest layers"));
178
+ for (const layer of [...profile.layers].sort((a, b) => b.durationMs - a.durationMs).slice(0, 12)) {
179
+ console.log(
180
+ import_chalk.default.gray(
181
+ ` ${layer.stageName} layer ${layer.layerIndex}/${layer.layerCount} (${layer.packageCount} packages): ${formatDuration(layer.durationMs)}`
182
+ )
183
+ );
184
+ }
185
+ }
186
+ if (phaseTotals.size > 0) {
187
+ console.log(import_chalk.default.cyan("[@nocobase/build:profile] aggregated package phases"));
188
+ for (const [phaseName, duration] of [...phaseTotals.entries()].sort((a, b) => b[1] - a[1])) {
189
+ console.log(import_chalk.default.gray(` ${phaseName}: ${formatDuration(duration)}`));
190
+ }
191
+ }
192
+ if (profile.packages.length > 0) {
193
+ const sourcePackages = profile.packages.filter((pkg) => pkg.kind === "source");
194
+ const declarationPackages = profile.packages.filter((pkg) => pkg.kind === "declaration");
195
+ console.log(import_chalk.default.cyan("[@nocobase/build:profile] slowest source packages"));
196
+ for (const pkg of [...sourcePackages].sort((a, b) => b.durationMs - a.durationMs).slice(0, 20)) {
197
+ const summary = Object.entries(pkg.phases).sort((a, b) => b[1] - a[1]).slice(0, 4).map(([name, duration]) => `${name}=${formatDuration(duration)}`).join(", ");
198
+ console.log(
199
+ import_chalk.default.gray(
200
+ ` ${pkg.name} [${pkg.status}] ${formatDuration(pkg.durationMs)}${summary ? ` (${summary})` : ""}`
201
+ )
202
+ );
203
+ }
204
+ console.log(import_chalk.default.cyan("[@nocobase/build:profile] slowest declaration packages"));
205
+ for (const pkg of [...declarationPackages].sort((a, b) => b.durationMs - a.durationMs).slice(0, 20)) {
206
+ const summary = Object.entries(pkg.phases).sort((a, b) => b[1] - a[1]).slice(0, 4).map(([name, duration]) => `${name}=${formatDuration(duration)}`).join(", ");
207
+ console.log(
208
+ import_chalk.default.gray(
209
+ ` ${pkg.name} [${pkg.status}] ${formatDuration(pkg.durationMs)}${summary ? ` (${summary})` : ""}`
210
+ )
211
+ );
212
+ }
213
+ }
214
+ }
215
+ function nowMs() {
216
+ return Date.now();
217
+ }
218
+ function formatDuration(durationMs) {
219
+ if (durationMs >= 6e4) {
220
+ return `${(durationMs / 6e4).toFixed(2)}m`;
221
+ }
222
+ if (durationMs >= 1e3) {
223
+ return `${(durationMs / 1e3).toFixed(2)}s`;
224
+ }
225
+ return `${Math.round(durationMs)}ms`;
226
+ }
227
+ function runScript(args, cwd, envs = {}) {
228
+ return (0, import_execa.default)("yarn", args, {
229
+ cwd,
230
+ stdio: "inherit",
231
+ env: {
232
+ ...process.env,
233
+ ...envs,
234
+ sourcemap: process.argv.includes("--sourcemap") ? "sourcemap" : void 0,
235
+ NODE_ENV: process.env.NODE_ENV || "production"
236
+ }
237
+ });
238
+ }
124
239
  // Annotate the CommonJS export names for ESM import in node:
125
240
  0 && (module.exports = {
241
+ createBuildProfileCollector,
126
242
  defineConfig,
243
+ formatDuration,
127
244
  getEnvDefine,
128
245
  getPackageJson,
129
246
  getPkgLog,
130
247
  getUserConfig,
248
+ nowMs,
249
+ printBuildProfile,
131
250
  readFromCache,
251
+ runProfiledStage,
252
+ runScript,
253
+ runWithConcurrency,
132
254
  toUnixPath,
133
255
  writeToCache
134
256
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nocobase/build",
3
- "version": "2.1.0-beta.15",
3
+ "version": "2.1.0-beta.16",
4
4
  "description": "Library build tool based on rollup.",
5
5
  "main": "lib/index.js",
6
6
  "types": "./lib/index.d.ts",
@@ -15,9 +15,13 @@
15
15
  "@babel/preset-env": "^7.26.0",
16
16
  "@hapi/topo": "^6.0.0",
17
17
  "@lerna/project": "4.0.0",
18
+ "@rsbuild/core": "1.7.3",
18
19
  "@rsbuild/plugin-babel": "^1.0.3",
20
+ "@rsbuild/plugin-less": "^1.6.2",
21
+ "@rsbuild/plugin-react": "1.4.6",
22
+ "@rsbuild/plugin-svgr": "^1.3.1",
19
23
  "@rsdoctor/rspack-plugin": "^0.4.8",
20
- "@rspack/core": "1.3.2",
24
+ "@rspack/core": "1.7.8",
21
25
  "@svgr/webpack": "^8.1.0",
22
26
  "@types/lerna__package": "5.1.0",
23
27
  "@types/lerna__project": "5.1.0",
@@ -42,8 +46,6 @@
42
46
  "tsup": "8.2.4",
43
47
  "typescript": "5.1.3",
44
48
  "update-notifier": "3.0.0",
45
- "vite-plugin-css-injected-by-js": "^3.2.1",
46
- "vite-plugin-lib-inject-css": "1.2.0",
47
49
  "yargs-parser": "13.1.2"
48
50
  },
49
51
  "license": "Apache-2.0",
@@ -51,5 +53,5 @@
51
53
  "build": "tsup",
52
54
  "build:watch": "tsup --watch"
53
55
  },
54
- "gitHead": "dc1aceea6357e6ab149976c2a236fc4b6bee1370"
56
+ "gitHead": "b9a191705a440a336c85d82fd877fdf152bec70f"
55
57
  }