robuild 0.0.13 → 0.0.14
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/README.md +1 -1
- package/dist/_chunks/build-Ck2ABQml.mjs +3 -0
- package/dist/_chunks/{build-C9gSlxzR.mjs → build-Dtx2Wt3D.mjs} +178 -580
- package/dist/_chunks/{config-BDpkh_pL.d.mts → config-BOcpEsqS.d.mts} +0 -26
- package/dist/_chunks/{package-UJXXVy4Q.mjs → package-Bz3LfrXJ.mjs} +4 -4
- package/dist/cli.mjs +2 -13
- package/dist/config.d.mts +1 -1
- package/dist/config.mjs +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +2 -2
- package/package.json +4 -4
- /package/dist/_chunks/{config-B_2eqpNJ.mjs → config-C1aXyI1S.mjs} +0 -0
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ English | <a href="./README-zh.md">简体中文</a>
|
|
|
21
21
|
🎯 **TypeScript**: First-class TypeScript support with `.d.ts` generation
|
|
22
22
|
🔄 **Dual mode**: Bundle or transform your source code
|
|
23
23
|
🚀 **Stub mode**: Lightning-fast development with file linking
|
|
24
|
-
|
|
24
|
+
📤 **Exports**: Automatic package.json exports generation
|
|
25
25
|
|
|
26
26
|
## Installation
|
|
27
27
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { builtinModules } from "node:module";
|
|
2
2
|
import { basename, dirname, extname, isAbsolute, join, relative, resolve } from "node:path";
|
|
3
3
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
4
|
-
import { consola } from "consola";
|
|
5
4
|
import { colors } from "consola/utils";
|
|
6
5
|
import prettyBytes from "pretty-bytes";
|
|
7
6
|
import { cp, mkdir, readFile, readdir, symlink, writeFile } from "node:fs/promises";
|
|
7
|
+
import { consola } from "consola";
|
|
8
8
|
import { defu } from "defu";
|
|
9
9
|
import { resolveModulePath } from "exsolve";
|
|
10
10
|
import { parseSync } from "oxc-parser";
|
|
11
|
-
import { rolldown } from "rolldown";
|
|
11
|
+
import { rolldown, watch } from "rolldown";
|
|
12
12
|
import { dts } from "rolldown-plugin-dts";
|
|
13
13
|
import { existsSync, promises, readdirSync, statSync } from "node:fs";
|
|
14
14
|
import { glob } from "glob";
|
|
@@ -20,8 +20,6 @@ import { transform } from "oxc-transform";
|
|
|
20
20
|
import { glob as glob$1 } from "tinyglobby";
|
|
21
21
|
import { exec } from "node:child_process";
|
|
22
22
|
import { promisify } from "node:util";
|
|
23
|
-
import { watch } from "chokidar";
|
|
24
|
-
import "minimatch";
|
|
25
23
|
|
|
26
24
|
//#region src/features/advanced-build.ts
|
|
27
25
|
/**
|
|
@@ -39,9 +37,10 @@ function createSkipNodeModulesPlugin(options) {
|
|
|
39
37
|
};
|
|
40
38
|
return {
|
|
41
39
|
name: "skip-node-modules",
|
|
42
|
-
resolveId: async (id) => {
|
|
40
|
+
resolveId: async (id, importer) => {
|
|
43
41
|
if (shouldInline(id)) return null;
|
|
44
|
-
if (
|
|
42
|
+
if (!importer) return null;
|
|
43
|
+
if (id.includes("node_modules") || !id.startsWith(".") && !id.startsWith("/") && !id.startsWith("\\")) return {
|
|
45
44
|
id,
|
|
46
45
|
external: true
|
|
47
46
|
};
|
|
@@ -53,7 +52,7 @@ function createSkipNodeModulesPlugin(options) {
|
|
|
53
52
|
* Unbundle mode: preserve file structure without bundling
|
|
54
53
|
*/
|
|
55
54
|
async function unbundleTransform(ctx, entry) {
|
|
56
|
-
const inputDir = join(ctx.pkgDir, entry.input);
|
|
55
|
+
const inputDir = isAbsolute(entry.input) ? entry.input : join(ctx.pkgDir, entry.input);
|
|
57
56
|
const outputDir = join(ctx.pkgDir, entry.outDir || "dist");
|
|
58
57
|
await processDirectoryUnbundled(inputDir, outputDir, entry);
|
|
59
58
|
}
|
|
@@ -101,7 +100,7 @@ async function processFileUnbundled(inputPath, outputPath, entry) {
|
|
|
101
100
|
/**
|
|
102
101
|
* Transform imports for unbundle mode
|
|
103
102
|
*/
|
|
104
|
-
function transformImportsForUnbundle(content,
|
|
103
|
+
function transformImportsForUnbundle(content, _filePath, entry) {
|
|
105
104
|
let transformedContent = content;
|
|
106
105
|
transformedContent = transformedContent.replace(/from\s+['"]([^'"]+)['"]/g, (match, importPath) => {
|
|
107
106
|
if (importPath.startsWith(".")) {
|
|
@@ -231,11 +230,11 @@ function createGlobImportPlugin(options = {}) {
|
|
|
231
230
|
let transformedCode = code;
|
|
232
231
|
while ((match = globImportRegex.exec(code)) !== null) {
|
|
233
232
|
hasGlobImports = true;
|
|
234
|
-
const [fullMatch,
|
|
233
|
+
const [fullMatch, , pattern, optionsStr] = match;
|
|
235
234
|
let globOptions = {};
|
|
236
235
|
if (optionsStr) try {
|
|
237
236
|
globOptions = parseGlobOptions(optionsStr);
|
|
238
|
-
} catch
|
|
237
|
+
} catch {
|
|
239
238
|
console.warn("Failed to parse glob options:", optionsStr);
|
|
240
239
|
}
|
|
241
240
|
const isEager = globOptions.eager ?? eager;
|
|
@@ -261,7 +260,7 @@ async function generateGlobImport(pattern, importer, eager, asUrls, allowedPatte
|
|
|
261
260
|
try {
|
|
262
261
|
const absolutePattern = resolve(importerDir, pattern);
|
|
263
262
|
files = await glob(absolutePattern, { ignore: ["**/node_modules/**", "**/.git/**"] });
|
|
264
|
-
} catch
|
|
263
|
+
} catch {
|
|
265
264
|
if (pattern.includes("*.js")) files = [resolve(importerDir, pattern.replace("*", "module1")), resolve(importerDir, pattern.replace("*", "module2"))];
|
|
266
265
|
}
|
|
267
266
|
if (eager) return generateEagerImport(files, importerDir, asUrls);
|
|
@@ -345,7 +344,7 @@ function addHashToFilename(filename, content, hashLength = 8) {
|
|
|
345
344
|
* Check if filename already has hash
|
|
346
345
|
*/
|
|
347
346
|
function hasHash(filename) {
|
|
348
|
-
return /-[a-f0-9]{8}(
|
|
347
|
+
return /-[a-f0-9]{8}(?:\.|$)/.test(filename);
|
|
349
348
|
}
|
|
350
349
|
|
|
351
350
|
//#endregion
|
|
@@ -411,7 +410,12 @@ async function transformWithLoader(filePath, content, loader, options) {
|
|
|
411
410
|
case "jsx":
|
|
412
411
|
case "ts":
|
|
413
412
|
case "tsx": return content;
|
|
414
|
-
case "json":
|
|
413
|
+
case "json": try {
|
|
414
|
+
const parsed = JSON.parse(content);
|
|
415
|
+
return `export default ${JSON.stringify(parsed)}`;
|
|
416
|
+
} catch {
|
|
417
|
+
return `export default ${JSON.stringify(content)}`;
|
|
418
|
+
}
|
|
415
419
|
case "css": return transformCssContent(content, options);
|
|
416
420
|
case "text": return `export default ${JSON.stringify(content)}`;
|
|
417
421
|
case "file": return transformFileContent(filePath, options);
|
|
@@ -447,7 +451,7 @@ function transformFileContent(filePath, options) {
|
|
|
447
451
|
/**
|
|
448
452
|
* Transform file content to data URL
|
|
449
453
|
*/
|
|
450
|
-
function transformDataUrlContent(filePath, content,
|
|
454
|
+
function transformDataUrlContent(filePath, content, _options) {
|
|
451
455
|
const ext = extname(filePath).toLowerCase();
|
|
452
456
|
const mimeType = getMimeType(ext);
|
|
453
457
|
const base64 = Buffer.from(content).toString("base64");
|
|
@@ -457,7 +461,7 @@ function transformDataUrlContent(filePath, content, options) {
|
|
|
457
461
|
/**
|
|
458
462
|
* Transform binary file content
|
|
459
463
|
*/
|
|
460
|
-
function transformBinaryContent(filePath,
|
|
464
|
+
function transformBinaryContent(filePath, _options) {
|
|
461
465
|
const fileName = filePath.split("/").pop() || "binary";
|
|
462
466
|
return `export default ${JSON.stringify(fileName)}`;
|
|
463
467
|
}
|
|
@@ -467,7 +471,7 @@ function transformBinaryContent(filePath, options) {
|
|
|
467
471
|
function extractCssClassNames(content) {
|
|
468
472
|
const classRegex = /\.([a-z_-][\w-]*)/gi;
|
|
469
473
|
const matches = content.match(classRegex) || [];
|
|
470
|
-
return
|
|
474
|
+
return Array.from(new Set(matches.map((match) => match.slice(1))));
|
|
471
475
|
}
|
|
472
476
|
/**
|
|
473
477
|
* Get MIME type for file extension
|
|
@@ -508,13 +512,15 @@ function createLoaderPlugin(loaders) {
|
|
|
508
512
|
return {
|
|
509
513
|
name: "loaders",
|
|
510
514
|
load: async (id) => {
|
|
515
|
+
const ext = extname(id);
|
|
511
516
|
const loader = getLoaderForFile(id, loaders);
|
|
512
517
|
if (loader === "js" || loader === "jsx" || loader === "ts" || loader === "tsx") return null;
|
|
518
|
+
if (loader === "json" && !loaders?.[ext]) return null;
|
|
513
519
|
try {
|
|
514
520
|
const content = await readFile(id, "utf-8");
|
|
515
|
-
const options = loaders?.[
|
|
521
|
+
const options = loaders?.[ext]?.options;
|
|
516
522
|
return await transformWithLoader(id, content, loader, options);
|
|
517
|
-
} catch
|
|
523
|
+
} catch {
|
|
518
524
|
return null;
|
|
519
525
|
}
|
|
520
526
|
}
|
|
@@ -742,7 +748,7 @@ function createShimsPlugin(config = true) {
|
|
|
742
748
|
return {
|
|
743
749
|
name: "shims",
|
|
744
750
|
transform: async (code, id) => {
|
|
745
|
-
if (!/\.(js|mjs|cjs|ts|mts|cts|jsx|tsx)$/.test(id)) return null;
|
|
751
|
+
if (!/\.(?:js|mjs|cjs|ts|mts|cts|jsx|tsx)$/.test(id)) return null;
|
|
746
752
|
const needs = detectShimNeeds(code);
|
|
747
753
|
if (!needs.needsDirname && !needs.needsRequire && !needs.needsExports && !needs.needsEnv) return null;
|
|
748
754
|
const transformedCode = transformWithShims(code, shimsConfig);
|
|
@@ -751,88 +757,6 @@ function createShimsPlugin(config = true) {
|
|
|
751
757
|
};
|
|
752
758
|
}
|
|
753
759
|
|
|
754
|
-
//#endregion
|
|
755
|
-
//#region src/utils.ts
|
|
756
|
-
function fmtPath(path) {
|
|
757
|
-
return resolve(path).replace(process.cwd(), ".");
|
|
758
|
-
}
|
|
759
|
-
function analyzeDir(dir) {
|
|
760
|
-
if (Array.isArray(dir)) {
|
|
761
|
-
let totalSize$1 = 0;
|
|
762
|
-
let totalFiles = 0;
|
|
763
|
-
for (const d of dir) {
|
|
764
|
-
const { size, files: files$1 } = analyzeDir(d);
|
|
765
|
-
totalSize$1 += size;
|
|
766
|
-
totalFiles += files$1;
|
|
767
|
-
}
|
|
768
|
-
return {
|
|
769
|
-
size: totalSize$1,
|
|
770
|
-
files: totalFiles
|
|
771
|
-
};
|
|
772
|
-
}
|
|
773
|
-
let totalSize = 0;
|
|
774
|
-
const files = readdirSync(dir, {
|
|
775
|
-
withFileTypes: true,
|
|
776
|
-
recursive: true
|
|
777
|
-
});
|
|
778
|
-
for (const file of files) {
|
|
779
|
-
const fullPath = join(file.parentPath, file.name);
|
|
780
|
-
if (file.isFile()) {
|
|
781
|
-
const { size } = statSync(fullPath);
|
|
782
|
-
totalSize += size;
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
|
-
return {
|
|
786
|
-
size: totalSize,
|
|
787
|
-
files: files.length
|
|
788
|
-
};
|
|
789
|
-
}
|
|
790
|
-
async function distSize(dir, entry) {
|
|
791
|
-
const build$1 = await rolldown({
|
|
792
|
-
input: join(dir, entry),
|
|
793
|
-
plugins: [],
|
|
794
|
-
platform: "neutral",
|
|
795
|
-
external: (id) => id[0] !== "." && !id.startsWith(dir)
|
|
796
|
-
});
|
|
797
|
-
const { output } = await build$1.generate({ inlineDynamicImports: true });
|
|
798
|
-
const code = output[0].code;
|
|
799
|
-
const { code: minified } = await minify(entry, code);
|
|
800
|
-
return {
|
|
801
|
-
size: Buffer.byteLength(code),
|
|
802
|
-
minSize: Buffer.byteLength(minified),
|
|
803
|
-
minGzipSize: gzipSync(minified).length
|
|
804
|
-
};
|
|
805
|
-
}
|
|
806
|
-
async function sideEffectSize(dir, entry) {
|
|
807
|
-
const virtualEntry = {
|
|
808
|
-
name: "virtual-entry",
|
|
809
|
-
async resolveId(id, importer, opts) {
|
|
810
|
-
if (id === "#entry") return { id };
|
|
811
|
-
const resolved = await this.resolve(id, importer, opts);
|
|
812
|
-
if (!resolved) return null;
|
|
813
|
-
resolved.moduleSideEffects = null;
|
|
814
|
-
return resolved;
|
|
815
|
-
},
|
|
816
|
-
load(id) {
|
|
817
|
-
if (id === "#entry") return `import * as _lib from "${join(dir, entry)}";`;
|
|
818
|
-
}
|
|
819
|
-
};
|
|
820
|
-
const build$1 = await rolldown({
|
|
821
|
-
input: "#entry",
|
|
822
|
-
platform: "neutral",
|
|
823
|
-
external: (id) => id[0] !== "." && !id.startsWith(dir),
|
|
824
|
-
plugins: [virtualEntry]
|
|
825
|
-
});
|
|
826
|
-
const { output } = await build$1.generate({ inlineDynamicImports: true });
|
|
827
|
-
if (process.env.INSPECT_BUILD) {
|
|
828
|
-
console.log("---------[side effects]---------");
|
|
829
|
-
console.log(entry);
|
|
830
|
-
console.log(output[0].code);
|
|
831
|
-
console.log("-------------------------------");
|
|
832
|
-
}
|
|
833
|
-
return Buffer.byteLength(output[0].code.trim());
|
|
834
|
-
}
|
|
835
|
-
|
|
836
760
|
//#endregion
|
|
837
761
|
//#region src/features/node-protocol.ts
|
|
838
762
|
/**
|
|
@@ -925,7 +849,7 @@ function transformNodeProtocol(code, nodeProtocol) {
|
|
|
925
849
|
}
|
|
926
850
|
|
|
927
851
|
//#endregion
|
|
928
|
-
//#region src/
|
|
852
|
+
//#region src/plugins/node-protocol.ts
|
|
929
853
|
/**
|
|
930
854
|
* Rolldown plugin for Node.js protocol handling
|
|
931
855
|
*/
|
|
@@ -943,7 +867,7 @@ function nodeProtocolPlugin(nodeProtocol) {
|
|
|
943
867
|
}
|
|
944
868
|
|
|
945
869
|
//#endregion
|
|
946
|
-
//#region src/
|
|
870
|
+
//#region src/plugins/shebang.ts
|
|
947
871
|
const SHEBANG_RE = /^#![^\n]*/;
|
|
948
872
|
function shebangPlugin() {
|
|
949
873
|
return {
|
|
@@ -966,6 +890,88 @@ async function makeExecutable(filePath) {
|
|
|
966
890
|
await promises.chmod(filePath, 493).catch(() => {});
|
|
967
891
|
}
|
|
968
892
|
|
|
893
|
+
//#endregion
|
|
894
|
+
//#region src/utils.ts
|
|
895
|
+
function fmtPath(path) {
|
|
896
|
+
return resolve(path).replace(process.cwd(), ".");
|
|
897
|
+
}
|
|
898
|
+
function analyzeDir(dir) {
|
|
899
|
+
if (Array.isArray(dir)) {
|
|
900
|
+
let totalSize$1 = 0;
|
|
901
|
+
let totalFiles = 0;
|
|
902
|
+
for (const d of dir) {
|
|
903
|
+
const { size, files: files$1 } = analyzeDir(d);
|
|
904
|
+
totalSize$1 += size;
|
|
905
|
+
totalFiles += files$1;
|
|
906
|
+
}
|
|
907
|
+
return {
|
|
908
|
+
size: totalSize$1,
|
|
909
|
+
files: totalFiles
|
|
910
|
+
};
|
|
911
|
+
}
|
|
912
|
+
let totalSize = 0;
|
|
913
|
+
const files = readdirSync(dir, {
|
|
914
|
+
withFileTypes: true,
|
|
915
|
+
recursive: true
|
|
916
|
+
});
|
|
917
|
+
for (const file of files) {
|
|
918
|
+
const fullPath = join(file.parentPath, file.name);
|
|
919
|
+
if (file.isFile()) {
|
|
920
|
+
const { size } = statSync(fullPath);
|
|
921
|
+
totalSize += size;
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
return {
|
|
925
|
+
size: totalSize,
|
|
926
|
+
files: files.length
|
|
927
|
+
};
|
|
928
|
+
}
|
|
929
|
+
async function distSize(dir, entry) {
|
|
930
|
+
const build$1 = await rolldown({
|
|
931
|
+
input: join(dir, entry),
|
|
932
|
+
plugins: [],
|
|
933
|
+
platform: "neutral",
|
|
934
|
+
external: (id) => id[0] !== "." && !id.startsWith(dir)
|
|
935
|
+
});
|
|
936
|
+
const { output } = await build$1.generate({ inlineDynamicImports: true });
|
|
937
|
+
const code = output[0].code;
|
|
938
|
+
const { code: minified } = minify(entry, code);
|
|
939
|
+
return {
|
|
940
|
+
size: Buffer.byteLength(code),
|
|
941
|
+
minSize: Buffer.byteLength(minified),
|
|
942
|
+
minGzipSize: gzipSync(minified).length
|
|
943
|
+
};
|
|
944
|
+
}
|
|
945
|
+
async function sideEffectSize(dir, entry) {
|
|
946
|
+
const virtualEntry = {
|
|
947
|
+
name: "virtual-entry",
|
|
948
|
+
async resolveId(id, importer, opts) {
|
|
949
|
+
if (id === "#entry") return { id };
|
|
950
|
+
const resolved = await this.resolve(id, importer, opts);
|
|
951
|
+
if (!resolved) return null;
|
|
952
|
+
resolved.moduleSideEffects = null;
|
|
953
|
+
return resolved;
|
|
954
|
+
},
|
|
955
|
+
load(id) {
|
|
956
|
+
if (id === "#entry") return `import * as _lib from "${join(dir, entry)}";`;
|
|
957
|
+
}
|
|
958
|
+
};
|
|
959
|
+
const build$1 = await rolldown({
|
|
960
|
+
input: "#entry",
|
|
961
|
+
platform: "neutral",
|
|
962
|
+
external: (id) => id[0] !== "." && !id.startsWith(dir),
|
|
963
|
+
plugins: [virtualEntry]
|
|
964
|
+
});
|
|
965
|
+
const { output } = await build$1.generate({ inlineDynamicImports: true });
|
|
966
|
+
if (process.env.INSPECT_BUILD) {
|
|
967
|
+
console.log("---------[side effects]---------");
|
|
968
|
+
console.log(entry);
|
|
969
|
+
console.log(output[0].code);
|
|
970
|
+
console.log("-------------------------------");
|
|
971
|
+
}
|
|
972
|
+
return Buffer.byteLength(output[0].code.trim());
|
|
973
|
+
}
|
|
974
|
+
|
|
969
975
|
//#endregion
|
|
970
976
|
//#region src/builders/bundle.ts
|
|
971
977
|
/**
|
|
@@ -1070,7 +1076,7 @@ async function rolldownBuild(ctx, entry, hooks, config) {
|
|
|
1070
1076
|
externalDeps = externalDeps.filter((dep) => {
|
|
1071
1077
|
if (typeof dep === "string") return !excludedNames.has(dep);
|
|
1072
1078
|
if (dep instanceof RegExp) {
|
|
1073
|
-
for (const name of excludedNames) if (dep.source.startsWith(`^${escapeRegExp(name)}/`)) return false;
|
|
1079
|
+
for (const name of Array.from(excludedNames)) if (dep.source.startsWith(`^${escapeRegExp(name)}/`)) return false;
|
|
1074
1080
|
return true;
|
|
1075
1081
|
}
|
|
1076
1082
|
return true;
|
|
@@ -1499,176 +1505,6 @@ async function transformModule(entryPath, entry) {
|
|
|
1499
1505
|
return transformed;
|
|
1500
1506
|
}
|
|
1501
1507
|
|
|
1502
|
-
//#endregion
|
|
1503
|
-
//#region src/features/exports.ts
|
|
1504
|
-
/**
|
|
1505
|
-
* Generate package.json exports field based on build configuration
|
|
1506
|
-
*/
|
|
1507
|
-
async function generatePackageExports(packageRoot, buildConfig, exportsConfig = { enabled: true }) {
|
|
1508
|
-
if (!exportsConfig.enabled) return {};
|
|
1509
|
-
const exports = {};
|
|
1510
|
-
const baseDir = exportsConfig.baseDir || "dist";
|
|
1511
|
-
if (exportsConfig.custom) Object.assign(exports, exportsConfig.custom);
|
|
1512
|
-
if (buildConfig.entries) for (const entry of buildConfig.entries) {
|
|
1513
|
-
const exportEntries = await generateExportFromEntry(packageRoot, entry, baseDir, exportsConfig.includeTypes);
|
|
1514
|
-
for (const exportEntry of exportEntries) exports[exportEntry.key] = createExportValue(exportEntry);
|
|
1515
|
-
}
|
|
1516
|
-
if (!exports["."] && !exports["./index"]) {
|
|
1517
|
-
const mainExport = await findMainExport(packageRoot, baseDir);
|
|
1518
|
-
if (mainExport) exports["."] = mainExport;
|
|
1519
|
-
}
|
|
1520
|
-
return exports;
|
|
1521
|
-
}
|
|
1522
|
-
/**
|
|
1523
|
-
* Generate export entries from a build entry
|
|
1524
|
-
*/
|
|
1525
|
-
async function generateExportFromEntry(packageRoot, entry, baseDir, includeTypes) {
|
|
1526
|
-
const exports = [];
|
|
1527
|
-
if (entry.type === "bundle") {
|
|
1528
|
-
const exportKey = getExportKey(entry.input);
|
|
1529
|
-
const exportEntry = { key: exportKey };
|
|
1530
|
-
if (Array.isArray(entry.format)) for (const format of entry.format) {
|
|
1531
|
-
const outputPath = getOutputPath(entry, format, baseDir);
|
|
1532
|
-
assignFormatToExport(exportEntry, format, outputPath);
|
|
1533
|
-
}
|
|
1534
|
-
else if (entry.format) {
|
|
1535
|
-
const outputPath = getOutputPath(entry, entry.format, baseDir);
|
|
1536
|
-
assignFormatToExport(exportEntry, entry.format, outputPath);
|
|
1537
|
-
}
|
|
1538
|
-
if (includeTypes && entry.dts) {
|
|
1539
|
-
const typesPath = getTypesPath(entry, baseDir);
|
|
1540
|
-
exportEntry.types = typesPath;
|
|
1541
|
-
}
|
|
1542
|
-
exports.push(exportEntry);
|
|
1543
|
-
} else if (entry.type === "transform") {
|
|
1544
|
-
const transformExports = await discoverTransformExports(packageRoot, entry, baseDir, includeTypes);
|
|
1545
|
-
exports.push(...transformExports);
|
|
1546
|
-
}
|
|
1547
|
-
return exports;
|
|
1548
|
-
}
|
|
1549
|
-
/**
|
|
1550
|
-
* Get export key from input path
|
|
1551
|
-
*/
|
|
1552
|
-
function getExportKey(input) {
|
|
1553
|
-
if (input === "index.ts" || input === "src/index.ts") return ".";
|
|
1554
|
-
let key = input.replace(/\.(ts|js|tsx|jsx)$/, "");
|
|
1555
|
-
key = key.replace(/^src\//, "");
|
|
1556
|
-
return key === "index" ? "." : `./${key}`;
|
|
1557
|
-
}
|
|
1558
|
-
/**
|
|
1559
|
-
* Get output path for a specific format
|
|
1560
|
-
*/
|
|
1561
|
-
function getOutputPath(entry, format, baseDir) {
|
|
1562
|
-
const extension = getExtensionForFormat(format);
|
|
1563
|
-
const basename$1 = getBasename(entry.input);
|
|
1564
|
-
if (format === "cjs") return `./${baseDir}/cjs/${basename$1}${extension}`;
|
|
1565
|
-
else if (format === "esm") return `./${baseDir}/${basename$1}${extension}`;
|
|
1566
|
-
else return `./${baseDir}/${format}/${basename$1}${extension}`;
|
|
1567
|
-
}
|
|
1568
|
-
/**
|
|
1569
|
-
* Get file extension for format
|
|
1570
|
-
*/
|
|
1571
|
-
function getExtensionForFormat(format) {
|
|
1572
|
-
switch (format) {
|
|
1573
|
-
case "esm": return ".mjs";
|
|
1574
|
-
case "cjs": return ".cjs";
|
|
1575
|
-
case "iife":
|
|
1576
|
-
case "umd": return ".js";
|
|
1577
|
-
default: return ".js";
|
|
1578
|
-
}
|
|
1579
|
-
}
|
|
1580
|
-
/**
|
|
1581
|
-
* Get basename from input path
|
|
1582
|
-
*/
|
|
1583
|
-
function getBasename(input) {
|
|
1584
|
-
return input.replace(/\.(ts|js|tsx|jsx)$/, "").replace(/^src\//, "");
|
|
1585
|
-
}
|
|
1586
|
-
/**
|
|
1587
|
-
* Get types path for entry
|
|
1588
|
-
*/
|
|
1589
|
-
function getTypesPath(entry, baseDir) {
|
|
1590
|
-
const basename$1 = getBasename(entry.input);
|
|
1591
|
-
return `./${baseDir}/${basename$1}.d.ts`;
|
|
1592
|
-
}
|
|
1593
|
-
/**
|
|
1594
|
-
* Assign format-specific path to export entry
|
|
1595
|
-
*/
|
|
1596
|
-
function assignFormatToExport(exportEntry, format, path) {
|
|
1597
|
-
switch (format) {
|
|
1598
|
-
case "esm":
|
|
1599
|
-
exportEntry.import = path;
|
|
1600
|
-
break;
|
|
1601
|
-
case "cjs":
|
|
1602
|
-
exportEntry.require = path;
|
|
1603
|
-
break;
|
|
1604
|
-
default:
|
|
1605
|
-
exportEntry.import = path;
|
|
1606
|
-
break;
|
|
1607
|
-
}
|
|
1608
|
-
}
|
|
1609
|
-
/**
|
|
1610
|
-
* Create export value from export entry
|
|
1611
|
-
*/
|
|
1612
|
-
function createExportValue(entry) {
|
|
1613
|
-
const value = {};
|
|
1614
|
-
if (entry.types) value.types = entry.types;
|
|
1615
|
-
if (entry.import) value.import = entry.import;
|
|
1616
|
-
if (entry.require) value.require = entry.require;
|
|
1617
|
-
const keys = Object.keys(value);
|
|
1618
|
-
if (keys.length === 1 && !entry.types) return value[keys[0]];
|
|
1619
|
-
return value;
|
|
1620
|
-
}
|
|
1621
|
-
/**
|
|
1622
|
-
* Discover exports from transform entries
|
|
1623
|
-
*/
|
|
1624
|
-
async function discoverTransformExports(packageRoot, entry, baseDir, includeTypes) {
|
|
1625
|
-
const exports = [];
|
|
1626
|
-
const exportKey = getExportKey(entry.input);
|
|
1627
|
-
const exportEntry = {
|
|
1628
|
-
key: exportKey,
|
|
1629
|
-
import: `./${baseDir}/${getBasename(entry.input)}.mjs`
|
|
1630
|
-
};
|
|
1631
|
-
if (includeTypes && entry.dts) exportEntry.types = getTypesPath(entry, baseDir);
|
|
1632
|
-
exports.push(exportEntry);
|
|
1633
|
-
return exports;
|
|
1634
|
-
}
|
|
1635
|
-
/**
|
|
1636
|
-
* Find main export file
|
|
1637
|
-
*/
|
|
1638
|
-
async function findMainExport(packageRoot, baseDir) {
|
|
1639
|
-
const possibleMains = [
|
|
1640
|
-
"index.mjs",
|
|
1641
|
-
"index.js",
|
|
1642
|
-
"index.cjs"
|
|
1643
|
-
];
|
|
1644
|
-
for (const main of possibleMains) try {
|
|
1645
|
-
join(packageRoot, baseDir, main);
|
|
1646
|
-
const value = {};
|
|
1647
|
-
if (main.endsWith(".mjs")) value.import = `./${baseDir}/${main}`;
|
|
1648
|
-
else if (main.endsWith(".cjs")) value.require = `./${baseDir}/${main}`;
|
|
1649
|
-
else value.import = `./${baseDir}/${main}`;
|
|
1650
|
-
return value;
|
|
1651
|
-
} catch {
|
|
1652
|
-
continue;
|
|
1653
|
-
}
|
|
1654
|
-
return null;
|
|
1655
|
-
}
|
|
1656
|
-
/**
|
|
1657
|
-
* Update package.json with generated exports
|
|
1658
|
-
*/
|
|
1659
|
-
async function updatePackageJsonExports(packageRoot, exports) {
|
|
1660
|
-
const packageJsonPath = join(packageRoot, "package.json");
|
|
1661
|
-
try {
|
|
1662
|
-
const content = await readFile(packageJsonPath, "utf-8");
|
|
1663
|
-
const packageJson = JSON.parse(content);
|
|
1664
|
-
packageJson.exports = exports;
|
|
1665
|
-
const updatedContent = `${JSON.stringify(packageJson, null, 2)}\n`;
|
|
1666
|
-
await writeFile(packageJsonPath, updatedContent, "utf-8");
|
|
1667
|
-
} catch (error) {
|
|
1668
|
-
throw new Error(`Failed to update package.json: ${error}`);
|
|
1669
|
-
}
|
|
1670
|
-
}
|
|
1671
|
-
|
|
1672
1508
|
//#endregion
|
|
1673
1509
|
//#region src/features/logger.ts
|
|
1674
1510
|
/**
|
|
@@ -1904,263 +1740,80 @@ function convertExternal(external) {
|
|
|
1904
1740
|
}
|
|
1905
1741
|
|
|
1906
1742
|
//#endregion
|
|
1907
|
-
//#region src/
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
*/
|
|
1911
|
-
async function discoverWorkspacePackages(workspaceRoot, patterns = ["packages/*", "apps/*"]) {
|
|
1912
|
-
const packages = [];
|
|
1913
|
-
for (const pattern of patterns) {
|
|
1914
|
-
const packagePaths = await glob(pattern, {
|
|
1915
|
-
cwd: workspaceRoot,
|
|
1916
|
-
onlyDirectories: true
|
|
1917
|
-
});
|
|
1918
|
-
for (const packagePath of packagePaths) {
|
|
1919
|
-
const fullPath = resolve(workspaceRoot, packagePath);
|
|
1920
|
-
const packageJsonPath = join(fullPath, "package.json");
|
|
1921
|
-
try {
|
|
1922
|
-
const packageJsonContent = await readFile(packageJsonPath, "utf-8");
|
|
1923
|
-
const packageJson = JSON.parse(packageJsonContent);
|
|
1924
|
-
packages.push({
|
|
1925
|
-
name: packageJson.name || packagePath,
|
|
1926
|
-
path: fullPath,
|
|
1927
|
-
packageJson
|
|
1928
|
-
});
|
|
1929
|
-
} catch {
|
|
1930
|
-
continue;
|
|
1931
|
-
}
|
|
1932
|
-
}
|
|
1933
|
-
}
|
|
1934
|
-
return packages;
|
|
1935
|
-
}
|
|
1936
|
-
/**
|
|
1937
|
-
* Filter workspace packages based on filter patterns
|
|
1938
|
-
*/
|
|
1939
|
-
function filterWorkspacePackages(packages, filter, exclude) {
|
|
1940
|
-
let filtered = packages;
|
|
1941
|
-
if (filter) {
|
|
1942
|
-
const filters = Array.isArray(filter) ? filter : [filter];
|
|
1943
|
-
filtered = filtered.filter((pkg) => filters.some((f) => matchesPattern(pkg.name, f) || matchesPattern(pkg.path, f)));
|
|
1944
|
-
}
|
|
1945
|
-
if (exclude) {
|
|
1946
|
-
const excludes = Array.isArray(exclude) ? exclude : [exclude];
|
|
1947
|
-
filtered = filtered.filter((pkg) => !excludes.some((e) => matchesPattern(pkg.name, e) || matchesPattern(pkg.path, e)));
|
|
1948
|
-
}
|
|
1949
|
-
return filtered;
|
|
1950
|
-
}
|
|
1951
|
-
/**
|
|
1952
|
-
* Check if a string matches a pattern (supports wildcards)
|
|
1953
|
-
*/
|
|
1954
|
-
function matchesPattern(str, pattern) {
|
|
1955
|
-
const regexPattern = pattern.replace(/\*/g, ".*").replace(/\?/g, ".").replace(/\[([^\]]+)\]/g, "[$1]");
|
|
1956
|
-
const regex = /* @__PURE__ */ new RegExp(`^${regexPattern}$`);
|
|
1957
|
-
return regex.test(str);
|
|
1958
|
-
}
|
|
1959
|
-
/**
|
|
1960
|
-
* Load workspace configuration from package.json or workspace config file
|
|
1961
|
-
*/
|
|
1962
|
-
async function loadWorkspaceConfig(workspaceRoot) {
|
|
1963
|
-
try {
|
|
1964
|
-
const packageJsonPath = join(workspaceRoot, "package.json");
|
|
1965
|
-
const packageJsonContent = await readFile(packageJsonPath, "utf-8");
|
|
1966
|
-
const packageJson = JSON.parse(packageJsonContent);
|
|
1967
|
-
if (packageJson.workspaces) {
|
|
1968
|
-
const workspaces = Array.isArray(packageJson.workspaces) ? packageJson.workspaces : packageJson.workspaces.packages || [];
|
|
1969
|
-
return { packages: workspaces };
|
|
1970
|
-
}
|
|
1971
|
-
try {
|
|
1972
|
-
const { load } = await import("js-yaml");
|
|
1973
|
-
const pnpmWorkspacePath = join(workspaceRoot, "pnpm-workspace.yaml");
|
|
1974
|
-
const pnpmWorkspaceContent = await readFile(pnpmWorkspacePath, "utf-8");
|
|
1975
|
-
const pnpmWorkspace = load(pnpmWorkspaceContent);
|
|
1976
|
-
if (pnpmWorkspace?.packages) return { packages: pnpmWorkspace.packages };
|
|
1977
|
-
} catch {}
|
|
1978
|
-
try {
|
|
1979
|
-
const lernaJsonPath = join(workspaceRoot, "lerna.json");
|
|
1980
|
-
const lernaJsonContent = await readFile(lernaJsonPath, "utf-8");
|
|
1981
|
-
const lernaJson = JSON.parse(lernaJsonContent);
|
|
1982
|
-
if (lernaJson.packages) return { packages: lernaJson.packages };
|
|
1983
|
-
} catch {}
|
|
1984
|
-
return null;
|
|
1985
|
-
} catch {
|
|
1986
|
-
return null;
|
|
1987
|
-
}
|
|
1743
|
+
//#region src/watch.ts
|
|
1744
|
+
function normalizePath$1(path, resolveFrom) {
|
|
1745
|
+
return typeof path === "string" && isAbsolute(path) ? path : path instanceof URL ? fileURLToPath(path) : resolve(resolveFrom || ".", path || ".");
|
|
1988
1746
|
}
|
|
1989
1747
|
/**
|
|
1990
|
-
*
|
|
1748
|
+
* Perform watch build using rolldown's built-in watch mode
|
|
1991
1749
|
*/
|
|
1992
|
-
async function
|
|
1993
|
-
await
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
/**
|
|
1999
|
-
* Normalize ignore patterns
|
|
2000
|
-
*/
|
|
2001
|
-
function normalizeIgnorePatterns(patterns) {
|
|
2002
|
-
return patterns.map((pattern) => {
|
|
2003
|
-
if (pattern.startsWith("./")) return pattern.slice(2);
|
|
2004
|
-
if (pattern.startsWith("/")) return pattern.slice(1);
|
|
2005
|
-
return pattern;
|
|
2006
|
-
});
|
|
2007
|
-
}
|
|
2008
|
-
|
|
2009
|
-
//#endregion
|
|
2010
|
-
//#region src/watch.ts
|
|
2011
|
-
/**
|
|
2012
|
-
* Start watching files and rebuild on changes
|
|
2013
|
-
*/
|
|
2014
|
-
async function startWatch(config, ctx, buildFn) {
|
|
2015
|
-
const watchOptions = config.watch || {};
|
|
2016
|
-
if (!watchOptions.enabled) throw new Error("Watch mode is not enabled");
|
|
2017
|
-
const watchCtx = {
|
|
2018
|
-
config,
|
|
2019
|
-
ctx,
|
|
2020
|
-
buildFn,
|
|
2021
|
-
isBuilding: false,
|
|
2022
|
-
pendingRebuild: false
|
|
2023
|
-
};
|
|
2024
|
-
const watchPatterns = await getWatchPatterns(config, ctx, watchOptions);
|
|
2025
|
-
const ignorePatterns = getIgnorePatterns(config, watchOptions);
|
|
2026
|
-
consola.info(`👀 Starting watch mode...`);
|
|
2027
|
-
consola.info(`📁 Watching: ${colors.dim(watchPatterns.join(", "))}`);
|
|
2028
|
-
if (ignorePatterns.length > 0) consola.info(`🚫 Ignoring: ${colors.dim(ignorePatterns.join(", "))}`);
|
|
2029
|
-
const delay = watchOptions.delay ?? 100;
|
|
2030
|
-
if (delay > 0) consola.info(`⏱️ Rebuild delay: ${colors.dim(`${delay}ms`)}`);
|
|
2031
|
-
const watcher = watch(watchPatterns, {
|
|
2032
|
-
ignored: ignorePatterns,
|
|
2033
|
-
ignoreInitial: watchOptions.ignoreInitial ?? false,
|
|
2034
|
-
persistent: true,
|
|
2035
|
-
followSymlinks: false,
|
|
2036
|
-
cwd: ctx.pkgDir
|
|
2037
|
-
});
|
|
2038
|
-
watcher.on("change", (path) => handleFileChange(watchCtx, path, "changed"));
|
|
2039
|
-
watcher.on("add", (path) => {
|
|
2040
|
-
if (watchOptions.watchNewFiles !== false) handleFileChange(watchCtx, path, "added");
|
|
2041
|
-
});
|
|
2042
|
-
watcher.on("unlink", (path) => handleFileChange(watchCtx, path, "removed"));
|
|
2043
|
-
watcher.on("error", (error) => {
|
|
2044
|
-
consola.error("❌ Watch error:", error);
|
|
1750
|
+
async function performWatchBuild(config, ctx, startTime) {
|
|
1751
|
+
const { performBuild: performBuild$1 } = await import("./build-Ck2ABQml.mjs");
|
|
1752
|
+
await performBuild$1(config, ctx, startTime);
|
|
1753
|
+
const bundleEntries = (config.entries || []).filter((entry) => {
|
|
1754
|
+
if (typeof entry === "string") return !entry.endsWith("/");
|
|
1755
|
+
return entry.type === "bundle";
|
|
2045
1756
|
});
|
|
2046
|
-
if (
|
|
2047
|
-
|
|
2048
|
-
|
|
1757
|
+
if (bundleEntries.length > 0) await startRolldownWatch(ctx, bundleEntries);
|
|
1758
|
+
else {
|
|
1759
|
+
logger.warn("Transform-only watch mode not yet implemented with rolldown");
|
|
1760
|
+
return new Promise(() => {});
|
|
2049
1761
|
}
|
|
2050
|
-
await new Promise((resolve$1) => {
|
|
2051
|
-
watcher.on("ready", () => {
|
|
2052
|
-
const watchedPaths = watcher.getWatched();
|
|
2053
|
-
const totalFiles = Object.values(watchedPaths).reduce((sum, files) => sum + files.length, 0);
|
|
2054
|
-
consola.success(`🚀 Watch mode ready - watching ${totalFiles} files`);
|
|
2055
|
-
consola.info(`💡 Press ${colors.cyan("Ctrl+C")} to stop watching`);
|
|
2056
|
-
resolve$1();
|
|
2057
|
-
});
|
|
2058
|
-
});
|
|
2059
|
-
return () => {
|
|
2060
|
-
if (watchCtx.rebuildTimer) clearTimeout(watchCtx.rebuildTimer);
|
|
2061
|
-
return watcher.close();
|
|
2062
|
-
};
|
|
2063
1762
|
}
|
|
2064
1763
|
/**
|
|
2065
|
-
*
|
|
1764
|
+
* Start rolldown watch mode for bundle entries
|
|
2066
1765
|
*/
|
|
2067
|
-
function
|
|
2068
|
-
|
|
2069
|
-
const
|
|
2070
|
-
const
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
if (watchCtx.isBuilding) return;
|
|
2087
|
-
if (!watchCtx.pendingRebuild) return;
|
|
2088
|
-
watchCtx.isBuilding = true;
|
|
2089
|
-
watchCtx.pendingRebuild = false;
|
|
2090
|
-
try {
|
|
2091
|
-
consola.info(`🔄 Rebuilding...`);
|
|
2092
|
-
const start = Date.now();
|
|
2093
|
-
const buildConfig = {
|
|
2094
|
-
...config,
|
|
2095
|
-
watch: {
|
|
2096
|
-
...config.watch,
|
|
2097
|
-
enabled: false
|
|
1766
|
+
async function startRolldownWatch(ctx, bundleEntries) {
|
|
1767
|
+
logger.info("🚧 Using rolldown built-in watch mode...");
|
|
1768
|
+
const watchConfigs = [];
|
|
1769
|
+
for (const rawEntry of bundleEntries) {
|
|
1770
|
+
let entry;
|
|
1771
|
+
if (typeof rawEntry === "string") {
|
|
1772
|
+
const [input, outDir] = rawEntry.split(":");
|
|
1773
|
+
entry = {
|
|
1774
|
+
type: "bundle",
|
|
1775
|
+
input,
|
|
1776
|
+
outDir: outDir || "dist"
|
|
1777
|
+
};
|
|
1778
|
+
} else entry = rawEntry;
|
|
1779
|
+
entry.input = Array.isArray(entry.input) ? entry.input.map((i) => normalizePath$1(i, ctx.pkgDir)) : normalizePath$1(entry.input, ctx.pkgDir);
|
|
1780
|
+
const watchConfig = {
|
|
1781
|
+
input: Array.isArray(entry.input) ? entry.input[0] : entry.input,
|
|
1782
|
+
output: {
|
|
1783
|
+
dir: entry.outDir,
|
|
1784
|
+
format: "esm"
|
|
2098
1785
|
}
|
|
2099
1786
|
};
|
|
2100
|
-
|
|
2101
|
-
const duration = Date.now() - start;
|
|
2102
|
-
consola.success(`✅ Rebuild completed in ${duration}ms`);
|
|
2103
|
-
} catch (error) {
|
|
2104
|
-
consola.error("❌ Rebuild failed:");
|
|
2105
|
-
if (error instanceof Error) {
|
|
2106
|
-
consola.error(` ${error.message}`);
|
|
2107
|
-
if (process.env.DEBUG && error.stack) consola.debug(error.stack);
|
|
2108
|
-
} else consola.error(` ${String(error)}`);
|
|
2109
|
-
consola.info("👀 Still watching for changes...");
|
|
2110
|
-
} finally {
|
|
2111
|
-
watchCtx.isBuilding = false;
|
|
2112
|
-
if (watchCtx.pendingRebuild) setTimeout(() => triggerRebuild(watchCtx), watchCtx.config.watch?.delay ?? 100);
|
|
1787
|
+
watchConfigs.push(watchConfig);
|
|
2113
1788
|
}
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
} else if (entry.type === "transform") patterns.push(`${entry.input}/**/*`);
|
|
2133
|
-
else {
|
|
2134
|
-
const inputs = Array.isArray(entry.input) ? entry.input : [entry.input];
|
|
2135
|
-
for (const inputFile of inputs) {
|
|
2136
|
-
patterns.push(inputFile);
|
|
2137
|
-
const dir = inputFile.substring(0, inputFile.lastIndexOf("/"));
|
|
2138
|
-
if (dir) patterns.push(`${dir}/**/*`);
|
|
1789
|
+
const watcher = watch(watchConfigs);
|
|
1790
|
+
watcher.on("event", (event) => {
|
|
1791
|
+
switch (event.code) {
|
|
1792
|
+
case "START":
|
|
1793
|
+
logger.info("🔄 Rebuilding...");
|
|
1794
|
+
break;
|
|
1795
|
+
case "BUNDLE_START":
|
|
1796
|
+
logger.info("📦 Bundling...");
|
|
1797
|
+
break;
|
|
1798
|
+
case "BUNDLE_END":
|
|
1799
|
+
logger.success("✅ Bundle complete");
|
|
1800
|
+
break;
|
|
1801
|
+
case "END":
|
|
1802
|
+
logger.success("🎉 Watch rebuild complete");
|
|
1803
|
+
break;
|
|
1804
|
+
case "ERROR":
|
|
1805
|
+
logger.error("❌ Build error:", event.error);
|
|
1806
|
+
break;
|
|
2139
1807
|
}
|
|
2140
|
-
}
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
"**/node_modules/**",
|
|
2150
|
-
"**/dist/**",
|
|
2151
|
-
"**/build/**",
|
|
2152
|
-
"**/coverage/**",
|
|
2153
|
-
"**/.git/**",
|
|
2154
|
-
"**/.DS_Store",
|
|
2155
|
-
"**/Thumbs.db",
|
|
2156
|
-
"**/*.log",
|
|
2157
|
-
"**/tmp/**",
|
|
2158
|
-
"**/temp/**"
|
|
2159
|
-
];
|
|
2160
|
-
const allIgnores = [...defaultIgnores];
|
|
2161
|
-
if (watchOptions.exclude && watchOptions.exclude.length > 0) allIgnores.push(...watchOptions.exclude);
|
|
2162
|
-
if (config.ignoreWatch && config.ignoreWatch.length > 0) allIgnores.push(...normalizeIgnorePatterns(config.ignoreWatch));
|
|
2163
|
-
return allIgnores;
|
|
1808
|
+
});
|
|
1809
|
+
const cleanup = async () => {
|
|
1810
|
+
consola.info("🛑 Stopping watch mode...");
|
|
1811
|
+
await watcher.close();
|
|
1812
|
+
process.exit(0);
|
|
1813
|
+
};
|
|
1814
|
+
process.on("SIGINT", cleanup);
|
|
1815
|
+
process.on("SIGTERM", cleanup);
|
|
1816
|
+
return new Promise(() => {});
|
|
2164
1817
|
}
|
|
2165
1818
|
|
|
2166
1819
|
//#endregion
|
|
@@ -2178,7 +1831,6 @@ async function build(config) {
|
|
|
2178
1831
|
pkg,
|
|
2179
1832
|
pkgDir
|
|
2180
1833
|
};
|
|
2181
|
-
if (config.workspace) return buildWorkspace(config, pkgDir);
|
|
2182
1834
|
let finalConfig = config;
|
|
2183
1835
|
if (config.fromVite) {
|
|
2184
1836
|
logger.verbose("Loading configuration from Vite config file");
|
|
@@ -2190,16 +1842,8 @@ async function build(config) {
|
|
|
2190
1842
|
}
|
|
2191
1843
|
if (finalConfig.watch?.enabled) {
|
|
2192
1844
|
logger.info(`👀 Starting watch mode for \`${ctx.pkg.name || "<no name>"}\` (\`${ctx.pkgDir}\`)`);
|
|
2193
|
-
await
|
|
2194
|
-
|
|
2195
|
-
const cleanup = () => {
|
|
2196
|
-
consola.info("🛑 Stopping watch mode...");
|
|
2197
|
-
stopWatch();
|
|
2198
|
-
process.exit(0);
|
|
2199
|
-
};
|
|
2200
|
-
process.on("SIGINT", cleanup);
|
|
2201
|
-
process.on("SIGTERM", cleanup);
|
|
2202
|
-
return new Promise(() => {});
|
|
1845
|
+
await performWatchBuild(finalConfig, ctx, startTime);
|
|
1846
|
+
return;
|
|
2203
1847
|
}
|
|
2204
1848
|
logger.info(`📦 Building \`${ctx.pkg.name || "<no name>"}\` (\`${ctx.pkgDir}\`)`);
|
|
2205
1849
|
await performBuild(finalConfig, ctx, startTime);
|
|
@@ -2249,56 +1893,10 @@ async function performBuild(config, ctx, startTime) {
|
|
|
2249
1893
|
function normalizePath(path, resolveFrom) {
|
|
2250
1894
|
return typeof path === "string" && isAbsolute(path) ? path : path instanceof URL ? fileURLToPath(path) : resolve(resolveFrom || ".", path || ".");
|
|
2251
1895
|
}
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
async function buildWorkspace(config, workspaceRoot) {
|
|
2256
|
-
logger.info("🏢 Building workspace packages...");
|
|
2257
|
-
const workspaceConfig = await loadWorkspaceConfig(workspaceRoot);
|
|
2258
|
-
if (!workspaceConfig) throw new Error("No workspace configuration found");
|
|
2259
|
-
const allPackages = await discoverWorkspacePackages(workspaceRoot, workspaceConfig.packages);
|
|
2260
|
-
if (allPackages.length === 0) {
|
|
2261
|
-
logger.warn("No packages found in workspace");
|
|
2262
|
-
return;
|
|
2263
|
-
}
|
|
2264
|
-
const filteredPackages = filterWorkspacePackages(allPackages, config.filter || config.workspace?.filter, config.workspace?.exclude);
|
|
2265
|
-
if (filteredPackages.length === 0) {
|
|
2266
|
-
logger.warn("No packages match the filter criteria");
|
|
2267
|
-
return;
|
|
2268
|
-
}
|
|
2269
|
-
logger.info(`Building ${filteredPackages.length} packages`);
|
|
2270
|
-
const buildPackage = async (pkg) => {
|
|
2271
|
-
logger.info(`📦 Building ${pkg.name}...`);
|
|
2272
|
-
try {
|
|
2273
|
-
const packageConfig = {
|
|
2274
|
-
...config,
|
|
2275
|
-
cwd: pkg.path,
|
|
2276
|
-
workspace: void 0
|
|
2277
|
-
};
|
|
2278
|
-
await build(packageConfig);
|
|
2279
|
-
if (config.exports?.enabled) {
|
|
2280
|
-
const exportsConfig = {
|
|
2281
|
-
enabled: true,
|
|
2282
|
-
...config.exports
|
|
2283
|
-
};
|
|
2284
|
-
const exports = await generatePackageExports(pkg.path, packageConfig, exportsConfig);
|
|
2285
|
-
if (config.exports.autoUpdate) {
|
|
2286
|
-
await updatePackageJsonExports(pkg.path, exports);
|
|
2287
|
-
logger.info(`Updated exports for ${pkg.name}`);
|
|
2288
|
-
}
|
|
2289
|
-
}
|
|
2290
|
-
logger.success(`Built ${pkg.name}`);
|
|
2291
|
-
} catch (error) {
|
|
2292
|
-
logger.error(`Failed to build ${pkg.name}:`, error);
|
|
2293
|
-
throw error;
|
|
2294
|
-
}
|
|
2295
|
-
};
|
|
2296
|
-
await buildWorkspacePackages(filteredPackages, buildPackage);
|
|
2297
|
-
logger.success(`Successfully built ${filteredPackages.length} packages`);
|
|
2298
|
-
}
|
|
2299
|
-
function readJSON(specifier) {
|
|
2300
|
-
return import(specifier, { with: { type: "json" } }).then((r) => r.default);
|
|
1896
|
+
async function readJSON(specifier) {
|
|
1897
|
+
const module = await import(specifier, { with: { type: "json" } });
|
|
1898
|
+
return module.default;
|
|
2301
1899
|
}
|
|
2302
1900
|
|
|
2303
1901
|
//#endregion
|
|
2304
|
-
export { build };
|
|
1902
|
+
export { build, performBuild };
|
|
@@ -445,35 +445,9 @@ interface BuildConfig {
|
|
|
445
445
|
*/
|
|
446
446
|
fromVite?: boolean;
|
|
447
447
|
/**
|
|
448
|
-
* Workspace configuration for monorepo support.
|
|
449
|
-
*/
|
|
450
|
-
workspace?: WorkspaceConfig;
|
|
451
|
-
/**
|
|
452
448
|
* Package exports generation configuration.
|
|
453
449
|
*/
|
|
454
450
|
exports?: ExportsConfig;
|
|
455
|
-
/**
|
|
456
|
-
* Package filter for workspace builds.
|
|
457
|
-
*/
|
|
458
|
-
filter?: string | string[];
|
|
459
|
-
}
|
|
460
|
-
interface WorkspaceConfig {
|
|
461
|
-
/**
|
|
462
|
-
* Workspace package patterns.
|
|
463
|
-
*/
|
|
464
|
-
packages?: string[];
|
|
465
|
-
/**
|
|
466
|
-
* Package filter patterns.
|
|
467
|
-
*/
|
|
468
|
-
filter?: string | string[];
|
|
469
|
-
/**
|
|
470
|
-
* Package exclude patterns.
|
|
471
|
-
*/
|
|
472
|
-
exclude?: string | string[];
|
|
473
|
-
/**
|
|
474
|
-
* Build packages in dependency order.
|
|
475
|
-
*/
|
|
476
|
-
dependencyOrder?: boolean;
|
|
477
451
|
}
|
|
478
452
|
interface ExportsConfig {
|
|
479
453
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
//#region package.json
|
|
2
2
|
var name = "robuild";
|
|
3
3
|
var type = "module";
|
|
4
|
-
var version = "0.0.
|
|
4
|
+
var version = "0.0.14";
|
|
5
5
|
var packageManager = "pnpm@10.11.1";
|
|
6
6
|
var description = "Zero-config ESM/TS package builder. Powered by Rolldown and Oxc";
|
|
7
7
|
var license = "MIT";
|
|
@@ -15,8 +15,8 @@ var types = "./dist/index.d.mts";
|
|
|
15
15
|
var bin = "./dist/cli.mjs";
|
|
16
16
|
var files = ["dist"];
|
|
17
17
|
var scripts = {
|
|
18
|
-
"build": "pnpm robuild",
|
|
19
|
-
"dev": "pnpm
|
|
18
|
+
"build": "pnpm test:types && pnpm robuild",
|
|
19
|
+
"dev": "pnpm test",
|
|
20
20
|
"lint": "eslint .",
|
|
21
21
|
"lint:fix": "automd && eslint . --fix",
|
|
22
22
|
"robuild": "esno src/cli.ts",
|
|
@@ -24,7 +24,7 @@ var scripts = {
|
|
|
24
24
|
"release": "pnpm test && changelogen --release && npm publish && git push --follow-tags",
|
|
25
25
|
"test": "vitest run",
|
|
26
26
|
"test:watch": "vitest",
|
|
27
|
-
"test:types": "tsc --noEmit --skipLibCheck",
|
|
27
|
+
"test:types": "tsc --noEmit --skipLibCheck src/**/*.ts",
|
|
28
28
|
"docs:dev": "vitepress dev docs",
|
|
29
29
|
"docs:build": "vitepress build docs",
|
|
30
30
|
"docs:preview": "vitepress preview docs",
|
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { build } from "./_chunks/build-
|
|
2
|
+
import { build } from "./_chunks/build-Dtx2Wt3D.mjs";
|
|
3
3
|
import { consola } from "consola";
|
|
4
4
|
import { parseArgs } from "node:util";
|
|
5
5
|
import { loadConfig } from "c12";
|
|
@@ -50,11 +50,6 @@ const args = parseArgs({
|
|
|
50
50
|
multiple: true
|
|
51
51
|
},
|
|
52
52
|
"from-vite": { type: "boolean" },
|
|
53
|
-
"workspace": { type: "boolean" },
|
|
54
|
-
"filter": {
|
|
55
|
-
type: "string",
|
|
56
|
-
multiple: true
|
|
57
|
-
},
|
|
58
53
|
"generate-exports": { type: "boolean" },
|
|
59
54
|
"cjs-default": { type: "string" },
|
|
60
55
|
"shims": { type: "boolean" },
|
|
@@ -85,8 +80,7 @@ Options:
|
|
|
85
80
|
--fail-on-warn Fail build on warnings
|
|
86
81
|
--ignore-watch <pattern> Ignore patterns in watch mode (can be used multiple times)
|
|
87
82
|
--from-vite Load configuration from Vite config file
|
|
88
|
-
|
|
89
|
-
--filter <pattern> Filter workspace packages by name or path pattern (can be used multiple times)
|
|
83
|
+
|
|
90
84
|
--generate-exports Generate package.json exports field
|
|
91
85
|
--cjs-default <mode> CommonJS default export handling: true, false, auto (default: auto)
|
|
92
86
|
--shims Enable CJS/ESM compatibility shims
|
|
@@ -168,11 +162,6 @@ if (args.values["on-success"]) buildConfig.onSuccess = args.values["on-success"]
|
|
|
168
162
|
if (args.values["fail-on-warn"]) buildConfig.failOnWarn = true;
|
|
169
163
|
if (args.values["ignore-watch"]) buildConfig.ignoreWatch = args.values["ignore-watch"];
|
|
170
164
|
if (args.values["from-vite"]) buildConfig.fromVite = true;
|
|
171
|
-
if (args.values.workspace) buildConfig.workspace = {
|
|
172
|
-
packages: ["packages/*", "apps/*"],
|
|
173
|
-
...config.workspace
|
|
174
|
-
};
|
|
175
|
-
if (args.values.filter) buildConfig.filter = args.values.filter;
|
|
176
165
|
if (args.values["generate-exports"]) buildConfig.exports = {
|
|
177
166
|
enabled: true,
|
|
178
167
|
includeTypes: true,
|
package/dist/config.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { defineConfig } from "./_chunks/config-
|
|
1
|
+
import { defineConfig } from "./_chunks/config-BOcpEsqS.mjs";
|
|
2
2
|
export { defineConfig };
|
package/dist/config.mjs
CHANGED
package/dist/index.d.mts
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { build } from "./_chunks/build-
|
|
2
|
-
import { defineConfig } from "./_chunks/config-
|
|
1
|
+
import { build } from "./_chunks/build-Dtx2Wt3D.mjs";
|
|
2
|
+
import { defineConfig } from "./_chunks/config-C1aXyI1S.mjs";
|
|
3
3
|
|
|
4
4
|
export { build, defineConfig };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "robuild",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.14",
|
|
5
5
|
"packageManager": "pnpm@10.11.1",
|
|
6
6
|
"description": "Zero-config ESM/TS package builder. Powered by Rolldown and Oxc",
|
|
7
7
|
"license": "MIT",
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
"dist"
|
|
18
18
|
],
|
|
19
19
|
"scripts": {
|
|
20
|
-
"build": "pnpm robuild",
|
|
21
|
-
"dev": "pnpm
|
|
20
|
+
"build": "pnpm test:types && pnpm robuild",
|
|
21
|
+
"dev": "pnpm test",
|
|
22
22
|
"lint": "eslint .",
|
|
23
23
|
"lint:fix": "automd && eslint . --fix",
|
|
24
24
|
"robuild": "esno src/cli.ts",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"release": "pnpm test && changelogen --release && npm publish && git push --follow-tags",
|
|
27
27
|
"test": "vitest run",
|
|
28
28
|
"test:watch": "vitest",
|
|
29
|
-
"test:types": "tsc --noEmit --skipLibCheck",
|
|
29
|
+
"test:types": "tsc --noEmit --skipLibCheck src/**/*.ts",
|
|
30
30
|
"docs:dev": "vitepress dev docs",
|
|
31
31
|
"docs:build": "vitepress build docs",
|
|
32
32
|
"docs:preview": "vitepress preview docs",
|
|
File without changes
|