robuild 0.0.13 → 0.0.15
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-C9gSlxzR.mjs → build-BzBhuQnI.mjs} +397 -684
- package/dist/_chunks/build-yfn0_Gzc.mjs +3 -0
- package/dist/_chunks/config-_iCJoeRz.d.mts +679 -0
- package/dist/_chunks/{package-UJXXVy4Q.mjs → package-ryheU-UV.mjs} +4 -4
- package/dist/cli.mjs +123 -168
- package/dist/config.d.mts +1 -1
- package/dist/config.mjs +1 -1
- package/dist/index.d.mts +54 -5
- package/dist/index.mjs +219 -3
- package/package.json +4 -4
- package/dist/_chunks/config-BDpkh_pL.d.mts +0 -508
- /package/dist/_chunks/{config-B_2eqpNJ.mjs → config-C1aXyI1S.mjs} +0 -0
|
@@ -1,14 +1,13 @@
|
|
|
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";
|
|
8
|
-
import {
|
|
7
|
+
import { consola } from "consola";
|
|
9
8
|
import { resolveModulePath } from "exsolve";
|
|
10
9
|
import { parseSync } from "oxc-parser";
|
|
11
|
-
import { rolldown } from "rolldown";
|
|
10
|
+
import { rolldown, watch } from "rolldown";
|
|
12
11
|
import { dts } from "rolldown-plugin-dts";
|
|
13
12
|
import { existsSync, promises, readdirSync, statSync } from "node:fs";
|
|
14
13
|
import { glob } from "glob";
|
|
@@ -20,8 +19,6 @@ import { transform } from "oxc-transform";
|
|
|
20
19
|
import { glob as glob$1 } from "tinyglobby";
|
|
21
20
|
import { exec } from "node:child_process";
|
|
22
21
|
import { promisify } from "node:util";
|
|
23
|
-
import { watch } from "chokidar";
|
|
24
|
-
import "minimatch";
|
|
25
22
|
|
|
26
23
|
//#region src/features/advanced-build.ts
|
|
27
24
|
/**
|
|
@@ -39,9 +36,10 @@ function createSkipNodeModulesPlugin(options) {
|
|
|
39
36
|
};
|
|
40
37
|
return {
|
|
41
38
|
name: "skip-node-modules",
|
|
42
|
-
resolveId: async (id) => {
|
|
39
|
+
resolveId: async (id, importer) => {
|
|
43
40
|
if (shouldInline(id)) return null;
|
|
44
|
-
if (
|
|
41
|
+
if (!importer) return null;
|
|
42
|
+
if (id.includes("node_modules") || !id.startsWith(".") && !id.startsWith("/") && !id.startsWith("\\")) return {
|
|
45
43
|
id,
|
|
46
44
|
external: true
|
|
47
45
|
};
|
|
@@ -53,7 +51,7 @@ function createSkipNodeModulesPlugin(options) {
|
|
|
53
51
|
* Unbundle mode: preserve file structure without bundling
|
|
54
52
|
*/
|
|
55
53
|
async function unbundleTransform(ctx, entry) {
|
|
56
|
-
const inputDir = join(ctx.pkgDir, entry.input);
|
|
54
|
+
const inputDir = isAbsolute(entry.input) ? entry.input : join(ctx.pkgDir, entry.input);
|
|
57
55
|
const outputDir = join(ctx.pkgDir, entry.outDir || "dist");
|
|
58
56
|
await processDirectoryUnbundled(inputDir, outputDir, entry);
|
|
59
57
|
}
|
|
@@ -101,7 +99,7 @@ async function processFileUnbundled(inputPath, outputPath, entry) {
|
|
|
101
99
|
/**
|
|
102
100
|
* Transform imports for unbundle mode
|
|
103
101
|
*/
|
|
104
|
-
function transformImportsForUnbundle(content,
|
|
102
|
+
function transformImportsForUnbundle(content, _filePath, entry) {
|
|
105
103
|
let transformedContent = content;
|
|
106
104
|
transformedContent = transformedContent.replace(/from\s+['"]([^'"]+)['"]/g, (match, importPath) => {
|
|
107
105
|
if (importPath.startsWith(".")) {
|
|
@@ -231,11 +229,11 @@ function createGlobImportPlugin(options = {}) {
|
|
|
231
229
|
let transformedCode = code;
|
|
232
230
|
while ((match = globImportRegex.exec(code)) !== null) {
|
|
233
231
|
hasGlobImports = true;
|
|
234
|
-
const [fullMatch,
|
|
232
|
+
const [fullMatch, , pattern, optionsStr] = match;
|
|
235
233
|
let globOptions = {};
|
|
236
234
|
if (optionsStr) try {
|
|
237
235
|
globOptions = parseGlobOptions(optionsStr);
|
|
238
|
-
} catch
|
|
236
|
+
} catch {
|
|
239
237
|
console.warn("Failed to parse glob options:", optionsStr);
|
|
240
238
|
}
|
|
241
239
|
const isEager = globOptions.eager ?? eager;
|
|
@@ -261,7 +259,7 @@ async function generateGlobImport(pattern, importer, eager, asUrls, allowedPatte
|
|
|
261
259
|
try {
|
|
262
260
|
const absolutePattern = resolve(importerDir, pattern);
|
|
263
261
|
files = await glob(absolutePattern, { ignore: ["**/node_modules/**", "**/.git/**"] });
|
|
264
|
-
} catch
|
|
262
|
+
} catch {
|
|
265
263
|
if (pattern.includes("*.js")) files = [resolve(importerDir, pattern.replace("*", "module1")), resolve(importerDir, pattern.replace("*", "module2"))];
|
|
266
264
|
}
|
|
267
265
|
if (eager) return generateEagerImport(files, importerDir, asUrls);
|
|
@@ -345,7 +343,7 @@ function addHashToFilename(filename, content, hashLength = 8) {
|
|
|
345
343
|
* Check if filename already has hash
|
|
346
344
|
*/
|
|
347
345
|
function hasHash(filename) {
|
|
348
|
-
return /-[a-f0-9]{8}(
|
|
346
|
+
return /-[a-f0-9]{8}(?:\.|$)/.test(filename);
|
|
349
347
|
}
|
|
350
348
|
|
|
351
349
|
//#endregion
|
|
@@ -411,7 +409,12 @@ async function transformWithLoader(filePath, content, loader, options) {
|
|
|
411
409
|
case "jsx":
|
|
412
410
|
case "ts":
|
|
413
411
|
case "tsx": return content;
|
|
414
|
-
case "json":
|
|
412
|
+
case "json": try {
|
|
413
|
+
const parsed = JSON.parse(content);
|
|
414
|
+
return `export default ${JSON.stringify(parsed)}`;
|
|
415
|
+
} catch {
|
|
416
|
+
return `export default ${JSON.stringify(content)}`;
|
|
417
|
+
}
|
|
415
418
|
case "css": return transformCssContent(content, options);
|
|
416
419
|
case "text": return `export default ${JSON.stringify(content)}`;
|
|
417
420
|
case "file": return transformFileContent(filePath, options);
|
|
@@ -447,7 +450,7 @@ function transformFileContent(filePath, options) {
|
|
|
447
450
|
/**
|
|
448
451
|
* Transform file content to data URL
|
|
449
452
|
*/
|
|
450
|
-
function transformDataUrlContent(filePath, content,
|
|
453
|
+
function transformDataUrlContent(filePath, content, _options) {
|
|
451
454
|
const ext = extname(filePath).toLowerCase();
|
|
452
455
|
const mimeType = getMimeType(ext);
|
|
453
456
|
const base64 = Buffer.from(content).toString("base64");
|
|
@@ -457,7 +460,7 @@ function transformDataUrlContent(filePath, content, options) {
|
|
|
457
460
|
/**
|
|
458
461
|
* Transform binary file content
|
|
459
462
|
*/
|
|
460
|
-
function transformBinaryContent(filePath,
|
|
463
|
+
function transformBinaryContent(filePath, _options) {
|
|
461
464
|
const fileName = filePath.split("/").pop() || "binary";
|
|
462
465
|
return `export default ${JSON.stringify(fileName)}`;
|
|
463
466
|
}
|
|
@@ -467,7 +470,7 @@ function transformBinaryContent(filePath, options) {
|
|
|
467
470
|
function extractCssClassNames(content) {
|
|
468
471
|
const classRegex = /\.([a-z_-][\w-]*)/gi;
|
|
469
472
|
const matches = content.match(classRegex) || [];
|
|
470
|
-
return
|
|
473
|
+
return Array.from(new Set(matches.map((match) => match.slice(1))));
|
|
471
474
|
}
|
|
472
475
|
/**
|
|
473
476
|
* Get MIME type for file extension
|
|
@@ -508,13 +511,15 @@ function createLoaderPlugin(loaders) {
|
|
|
508
511
|
return {
|
|
509
512
|
name: "loaders",
|
|
510
513
|
load: async (id) => {
|
|
514
|
+
const ext = extname(id);
|
|
511
515
|
const loader = getLoaderForFile(id, loaders);
|
|
512
516
|
if (loader === "js" || loader === "jsx" || loader === "ts" || loader === "tsx") return null;
|
|
517
|
+
if (loader === "json" && !loaders?.[ext]) return null;
|
|
513
518
|
try {
|
|
514
519
|
const content = await readFile(id, "utf-8");
|
|
515
|
-
const options = loaders?.[
|
|
520
|
+
const options = loaders?.[ext]?.options;
|
|
516
521
|
return await transformWithLoader(id, content, loader, options);
|
|
517
|
-
} catch
|
|
522
|
+
} catch {
|
|
518
523
|
return null;
|
|
519
524
|
}
|
|
520
525
|
}
|
|
@@ -522,111 +527,156 @@ function createLoaderPlugin(loaders) {
|
|
|
522
527
|
}
|
|
523
528
|
|
|
524
529
|
//#endregion
|
|
525
|
-
//#region src/features/
|
|
530
|
+
//#region src/features/plugin-manager.ts
|
|
526
531
|
/**
|
|
527
|
-
*
|
|
532
|
+
* Simplified plugin manager that leverages rolldown's plugin system
|
|
528
533
|
*/
|
|
529
|
-
var
|
|
534
|
+
var RobuildPluginManager = class {
|
|
530
535
|
plugins = [];
|
|
531
536
|
context;
|
|
532
|
-
constructor(config, entry) {
|
|
537
|
+
constructor(config, entry, pkgDir) {
|
|
533
538
|
this.context = {
|
|
534
539
|
config,
|
|
535
540
|
entry,
|
|
536
|
-
|
|
537
|
-
|
|
541
|
+
pkgDir,
|
|
542
|
+
outDir: entry.outDir || "dist",
|
|
543
|
+
format: entry.format || "esm",
|
|
544
|
+
platform: entry.platform || "node",
|
|
545
|
+
target: entry.target || "es2022"
|
|
538
546
|
};
|
|
539
|
-
this.plugins = config.plugins || [];
|
|
547
|
+
this.plugins = this.normalizePlugins(config.plugins || []);
|
|
540
548
|
}
|
|
541
549
|
/**
|
|
542
|
-
*
|
|
550
|
+
* Normalize plugin options to RobuildPlugin instances
|
|
543
551
|
*/
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
552
|
+
normalizePlugins(pluginOptions) {
|
|
553
|
+
return pluginOptions.map((pluginOption) => this.normalizePlugin(pluginOption));
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* Normalize a single plugin option
|
|
557
|
+
*/
|
|
558
|
+
normalizePlugin(pluginOption) {
|
|
559
|
+
if (typeof pluginOption === "function") return this.normalizePlugin(pluginOption());
|
|
560
|
+
if (typeof pluginOption === "object" && pluginOption !== null) {
|
|
561
|
+
if (this.isRobuildPlugin(pluginOption)) return pluginOption;
|
|
562
|
+
if (this.isRolldownPlugin(pluginOption)) return this.adaptRolldownPlugin(pluginOption);
|
|
563
|
+
if (this.isVitePlugin(pluginOption)) return this.adaptVitePlugin(pluginOption);
|
|
564
|
+
if (this.isUnplugin(pluginOption)) return this.adaptUnplugin(pluginOption);
|
|
565
|
+
return this.adaptRolldownPlugin(pluginOption);
|
|
548
566
|
}
|
|
567
|
+
throw new Error(`Invalid plugin option: ${typeof pluginOption}`);
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Check if plugin is already a RobuildPlugin
|
|
571
|
+
*/
|
|
572
|
+
isRobuildPlugin(plugin) {
|
|
573
|
+
return plugin.meta?.robuild === true || plugin.robuildSetup || plugin.robuildBuildStart || plugin.robuildBuildEnd;
|
|
549
574
|
}
|
|
550
575
|
/**
|
|
551
|
-
*
|
|
576
|
+
* Check if plugin is a rolldown/rollup plugin
|
|
552
577
|
*/
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
578
|
+
isRolldownPlugin(plugin) {
|
|
579
|
+
return plugin.name && (plugin.buildStart || plugin.buildEnd || plugin.resolveId || plugin.load || plugin.transform || plugin.generateBundle || plugin.writeBundle);
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* Check if plugin is a Vite plugin
|
|
583
|
+
*/
|
|
584
|
+
isVitePlugin(plugin) {
|
|
585
|
+
return plugin.config || plugin.configResolved || plugin.configureServer || plugin.meta?.vite === true;
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* Check if plugin is an Unplugin
|
|
589
|
+
*/
|
|
590
|
+
isUnplugin(plugin) {
|
|
591
|
+
return plugin.unplugin === true || plugin.meta?.unplugin === true;
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* Adapt rolldown plugin to RobuildPlugin
|
|
595
|
+
*/
|
|
596
|
+
adaptRolldownPlugin(plugin) {
|
|
597
|
+
return {
|
|
598
|
+
...plugin,
|
|
599
|
+
meta: {
|
|
600
|
+
...plugin.meta,
|
|
601
|
+
framework: "rolldown",
|
|
602
|
+
robuild: true,
|
|
603
|
+
rollup: true
|
|
563
604
|
}
|
|
564
|
-
}
|
|
565
|
-
return results;
|
|
605
|
+
};
|
|
566
606
|
}
|
|
567
607
|
/**
|
|
568
|
-
*
|
|
608
|
+
* Adapt Vite plugin to RobuildPlugin
|
|
569
609
|
*/
|
|
570
|
-
|
|
571
|
-
const resolveCallbacks = [];
|
|
572
|
-
const loadCallbacks = [];
|
|
573
|
-
const transformCallbacks = [];
|
|
610
|
+
adaptVitePlugin(plugin) {
|
|
574
611
|
return {
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
loadCallbacks.push({
|
|
583
|
-
...options,
|
|
584
|
-
callback
|
|
585
|
-
});
|
|
586
|
-
},
|
|
587
|
-
onTransform: (options, callback) => {
|
|
588
|
-
transformCallbacks.push({
|
|
589
|
-
...options,
|
|
590
|
-
callback
|
|
591
|
-
});
|
|
592
|
-
},
|
|
593
|
-
resolve: async (path, options) => {
|
|
594
|
-
for (const { filter, callback } of resolveCallbacks) if (filter.test(path)) {
|
|
595
|
-
const result = await callback({
|
|
596
|
-
path,
|
|
597
|
-
...options
|
|
598
|
-
});
|
|
599
|
-
if (result) return result;
|
|
600
|
-
}
|
|
601
|
-
return null;
|
|
602
|
-
},
|
|
603
|
-
getConfig: () => this.context.config
|
|
612
|
+
...plugin,
|
|
613
|
+
meta: {
|
|
614
|
+
...plugin.meta,
|
|
615
|
+
framework: "vite",
|
|
616
|
+
robuild: true,
|
|
617
|
+
vite: true
|
|
618
|
+
}
|
|
604
619
|
};
|
|
605
620
|
}
|
|
606
621
|
/**
|
|
607
|
-
*
|
|
622
|
+
* Adapt Unplugin to RobuildPlugin
|
|
608
623
|
*/
|
|
609
|
-
|
|
610
|
-
return
|
|
624
|
+
adaptUnplugin(plugin) {
|
|
625
|
+
return {
|
|
626
|
+
...plugin,
|
|
627
|
+
meta: {
|
|
628
|
+
...plugin.meta,
|
|
629
|
+
framework: "unplugin",
|
|
630
|
+
robuild: true,
|
|
631
|
+
unplugin: true,
|
|
632
|
+
rollup: true,
|
|
633
|
+
vite: true,
|
|
634
|
+
webpack: true,
|
|
635
|
+
esbuild: true
|
|
636
|
+
}
|
|
637
|
+
};
|
|
611
638
|
}
|
|
612
639
|
/**
|
|
613
|
-
*
|
|
640
|
+
* Initialize robuild-specific plugin hooks
|
|
614
641
|
*/
|
|
615
|
-
|
|
616
|
-
this.plugins
|
|
617
|
-
this.context.plugins = this.plugins;
|
|
642
|
+
async initializeRobuildHooks() {
|
|
643
|
+
for (const plugin of this.plugins) if (plugin.robuildSetup) await plugin.robuildSetup(this.context);
|
|
618
644
|
}
|
|
619
645
|
/**
|
|
620
|
-
*
|
|
646
|
+
* Execute robuild buildStart hooks
|
|
621
647
|
*/
|
|
622
|
-
|
|
623
|
-
const
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
648
|
+
async executeRobuildBuildStart() {
|
|
649
|
+
for (const plugin of this.plugins) if (plugin.robuildBuildStart) await plugin.robuildBuildStart(this.context);
|
|
650
|
+
}
|
|
651
|
+
/**
|
|
652
|
+
* Execute robuild buildEnd hooks
|
|
653
|
+
*/
|
|
654
|
+
async executeRobuildBuildEnd(result) {
|
|
655
|
+
for (const plugin of this.plugins) if (plugin.robuildBuildEnd) await plugin.robuildBuildEnd(this.context, result);
|
|
656
|
+
}
|
|
657
|
+
/**
|
|
658
|
+
* Get rolldown-compatible plugins for direct use
|
|
659
|
+
*/
|
|
660
|
+
getRolldownPlugins() {
|
|
661
|
+
return this.plugins.map((plugin) => {
|
|
662
|
+
const { robuildSetup, robuildBuildStart, robuildBuildEnd,...rolldownPlugin } = plugin;
|
|
663
|
+
return rolldownPlugin;
|
|
664
|
+
});
|
|
665
|
+
}
|
|
666
|
+
/**
|
|
667
|
+
* Get all plugins
|
|
668
|
+
*/
|
|
669
|
+
getPlugins() {
|
|
670
|
+
return this.plugins;
|
|
671
|
+
}
|
|
672
|
+
/**
|
|
673
|
+
* Update context (useful when build parameters change)
|
|
674
|
+
*/
|
|
675
|
+
updateContext(updates) {
|
|
676
|
+
this.context = {
|
|
677
|
+
...this.context,
|
|
678
|
+
...updates
|
|
679
|
+
};
|
|
630
680
|
}
|
|
631
681
|
};
|
|
632
682
|
|
|
@@ -742,7 +792,7 @@ function createShimsPlugin(config = true) {
|
|
|
742
792
|
return {
|
|
743
793
|
name: "shims",
|
|
744
794
|
transform: async (code, id) => {
|
|
745
|
-
if (!/\.(js|mjs|cjs|ts|mts|cts|jsx|tsx)$/.test(id)) return null;
|
|
795
|
+
if (!/\.(?:js|mjs|cjs|ts|mts|cts|jsx|tsx)$/.test(id)) return null;
|
|
746
796
|
const needs = detectShimNeeds(code);
|
|
747
797
|
if (!needs.needsDirname && !needs.needsRequire && !needs.needsExports && !needs.needsEnv) return null;
|
|
748
798
|
const transformedCode = transformWithShims(code, shimsConfig);
|
|
@@ -751,88 +801,6 @@ function createShimsPlugin(config = true) {
|
|
|
751
801
|
};
|
|
752
802
|
}
|
|
753
803
|
|
|
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
804
|
//#endregion
|
|
837
805
|
//#region src/features/node-protocol.ts
|
|
838
806
|
/**
|
|
@@ -925,7 +893,7 @@ function transformNodeProtocol(code, nodeProtocol) {
|
|
|
925
893
|
}
|
|
926
894
|
|
|
927
895
|
//#endregion
|
|
928
|
-
//#region src/
|
|
896
|
+
//#region src/plugins/node-protocol.ts
|
|
929
897
|
/**
|
|
930
898
|
* Rolldown plugin for Node.js protocol handling
|
|
931
899
|
*/
|
|
@@ -943,7 +911,7 @@ function nodeProtocolPlugin(nodeProtocol) {
|
|
|
943
911
|
}
|
|
944
912
|
|
|
945
913
|
//#endregion
|
|
946
|
-
//#region src/
|
|
914
|
+
//#region src/plugins/shebang.ts
|
|
947
915
|
const SHEBANG_RE = /^#![^\n]*/;
|
|
948
916
|
function shebangPlugin() {
|
|
949
917
|
return {
|
|
@@ -966,6 +934,88 @@ async function makeExecutable(filePath) {
|
|
|
966
934
|
await promises.chmod(filePath, 493).catch(() => {});
|
|
967
935
|
}
|
|
968
936
|
|
|
937
|
+
//#endregion
|
|
938
|
+
//#region src/utils.ts
|
|
939
|
+
function fmtPath(path) {
|
|
940
|
+
return resolve(path).replace(process.cwd(), ".");
|
|
941
|
+
}
|
|
942
|
+
function analyzeDir(dir) {
|
|
943
|
+
if (Array.isArray(dir)) {
|
|
944
|
+
let totalSize$1 = 0;
|
|
945
|
+
let totalFiles = 0;
|
|
946
|
+
for (const d of dir) {
|
|
947
|
+
const { size, files: files$1 } = analyzeDir(d);
|
|
948
|
+
totalSize$1 += size;
|
|
949
|
+
totalFiles += files$1;
|
|
950
|
+
}
|
|
951
|
+
return {
|
|
952
|
+
size: totalSize$1,
|
|
953
|
+
files: totalFiles
|
|
954
|
+
};
|
|
955
|
+
}
|
|
956
|
+
let totalSize = 0;
|
|
957
|
+
const files = readdirSync(dir, {
|
|
958
|
+
withFileTypes: true,
|
|
959
|
+
recursive: true
|
|
960
|
+
});
|
|
961
|
+
for (const file of files) {
|
|
962
|
+
const fullPath = join(file.parentPath, file.name);
|
|
963
|
+
if (file.isFile()) {
|
|
964
|
+
const { size } = statSync(fullPath);
|
|
965
|
+
totalSize += size;
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
return {
|
|
969
|
+
size: totalSize,
|
|
970
|
+
files: files.length
|
|
971
|
+
};
|
|
972
|
+
}
|
|
973
|
+
async function distSize(dir, entry) {
|
|
974
|
+
const build$1 = await rolldown({
|
|
975
|
+
input: join(dir, entry),
|
|
976
|
+
plugins: [],
|
|
977
|
+
platform: "neutral",
|
|
978
|
+
external: (id) => id[0] !== "." && !id.startsWith(dir)
|
|
979
|
+
});
|
|
980
|
+
const { output } = await build$1.generate({ inlineDynamicImports: true });
|
|
981
|
+
const code = output[0].code;
|
|
982
|
+
const { code: minified } = minify(entry, code);
|
|
983
|
+
return {
|
|
984
|
+
size: Buffer.byteLength(code),
|
|
985
|
+
minSize: Buffer.byteLength(minified),
|
|
986
|
+
minGzipSize: gzipSync(minified).length
|
|
987
|
+
};
|
|
988
|
+
}
|
|
989
|
+
async function sideEffectSize(dir, entry) {
|
|
990
|
+
const virtualEntry = {
|
|
991
|
+
name: "virtual-entry",
|
|
992
|
+
async resolveId(id, importer, opts) {
|
|
993
|
+
if (id === "#entry") return { id };
|
|
994
|
+
const resolved = await this.resolve(id, importer, opts);
|
|
995
|
+
if (!resolved) return null;
|
|
996
|
+
resolved.moduleSideEffects = null;
|
|
997
|
+
return resolved;
|
|
998
|
+
},
|
|
999
|
+
load(id) {
|
|
1000
|
+
if (id === "#entry") return `import * as _lib from "${join(dir, entry)}";`;
|
|
1001
|
+
}
|
|
1002
|
+
};
|
|
1003
|
+
const build$1 = await rolldown({
|
|
1004
|
+
input: "#entry",
|
|
1005
|
+
platform: "neutral",
|
|
1006
|
+
external: (id) => id[0] !== "." && !id.startsWith(dir),
|
|
1007
|
+
plugins: [virtualEntry]
|
|
1008
|
+
});
|
|
1009
|
+
const { output } = await build$1.generate({ inlineDynamicImports: true });
|
|
1010
|
+
if (process.env.INSPECT_BUILD) {
|
|
1011
|
+
console.log("---------[side effects]---------");
|
|
1012
|
+
console.log(entry);
|
|
1013
|
+
console.log(output[0].code);
|
|
1014
|
+
console.log("-------------------------------");
|
|
1015
|
+
}
|
|
1016
|
+
return Buffer.byteLength(output[0].code.trim());
|
|
1017
|
+
}
|
|
1018
|
+
|
|
969
1019
|
//#endregion
|
|
970
1020
|
//#region src/builders/bundle.ts
|
|
971
1021
|
/**
|
|
@@ -1020,22 +1070,29 @@ async function cleanOutputDir$1(projectRoot, outDir, cleanPaths) {
|
|
|
1020
1070
|
}
|
|
1021
1071
|
}
|
|
1022
1072
|
async function rolldownBuild(ctx, entry, hooks, config) {
|
|
1023
|
-
const
|
|
1024
|
-
|
|
1025
|
-
|
|
1073
|
+
const entryInput = entry.input || entry.entry;
|
|
1074
|
+
if (!entryInput) throw new Error("Entry input is required");
|
|
1075
|
+
const inputs = normalizeBundleInputs(entryInput, ctx);
|
|
1076
|
+
const pluginManager = new RobuildPluginManager(config || {}, entry, ctx.pkgDir);
|
|
1077
|
+
await pluginManager.initializeRobuildHooks();
|
|
1026
1078
|
const formats = Array.isArray(entry.format) ? entry.format : [entry.format || "esm"];
|
|
1027
1079
|
const platform = entry.platform || "node";
|
|
1028
1080
|
const target = entry.target || "es2022";
|
|
1029
1081
|
const outDir = entry.outDir || "dist";
|
|
1030
1082
|
const fullOutDir = resolve(ctx.pkgDir, outDir);
|
|
1031
1083
|
const isMultiFormat = formats.length > 1;
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
formats,
|
|
1084
|
+
pluginManager.updateContext({
|
|
1085
|
+
format: formats,
|
|
1035
1086
|
platform,
|
|
1036
|
-
target
|
|
1087
|
+
target,
|
|
1088
|
+
outDir: fullOutDir
|
|
1037
1089
|
});
|
|
1090
|
+
await pluginManager.executeRobuildBuildStart();
|
|
1038
1091
|
await cleanOutputDir$1(ctx.pkgDir, fullOutDir, entry.clean ?? true);
|
|
1092
|
+
if (entry.dtsOnly) {
|
|
1093
|
+
consola.info("Running in dtsOnly mode - only generating declaration files");
|
|
1094
|
+
entry.dts = entry.dts === false ? true : entry.dts || true;
|
|
1095
|
+
}
|
|
1039
1096
|
if (entry.stub) {
|
|
1040
1097
|
for (const [distName, srcPath] of Object.entries(inputs)) {
|
|
1041
1098
|
const distPath = join(ctx.pkgDir, "dist", `${distName}.mjs`);
|
|
@@ -1070,7 +1127,7 @@ async function rolldownBuild(ctx, entry, hooks, config) {
|
|
|
1070
1127
|
externalDeps = externalDeps.filter((dep) => {
|
|
1071
1128
|
if (typeof dep === "string") return !excludedNames.has(dep);
|
|
1072
1129
|
if (dep instanceof RegExp) {
|
|
1073
|
-
for (const name of excludedNames) if (dep.source.startsWith(`^${escapeRegExp(name)}/`)) return false;
|
|
1130
|
+
for (const name of Array.from(excludedNames)) if (dep.source.startsWith(`^${escapeRegExp(name)}/`)) return false;
|
|
1074
1131
|
return true;
|
|
1075
1132
|
}
|
|
1076
1133
|
return true;
|
|
@@ -1099,13 +1156,12 @@ async function rolldownBuild(ctx, entry, hooks, config) {
|
|
|
1099
1156
|
const defineOptions = {};
|
|
1100
1157
|
if (entry.env) for (const [key, value] of Object.entries(entry.env)) defineOptions[`process.env.${key}`] = JSON.stringify(value);
|
|
1101
1158
|
if (entry.define) for (const [key, value] of Object.entries(entry.define)) defineOptions[key] = value;
|
|
1102
|
-
const rolldownPlugins = [];
|
|
1103
|
-
rolldownPlugins.push(shebangPlugin(), nodeProtocolPlugin(entry.nodeProtocol || false));
|
|
1159
|
+
const rolldownPlugins = [shebangPlugin(), nodeProtocolPlugin(entry.nodeProtocol || false)];
|
|
1104
1160
|
if (config?.globImport?.enabled) {
|
|
1105
1161
|
const globPlugin = createGlobImportPlugin(config.globImport);
|
|
1106
1162
|
if (globPlugin.transform) rolldownPlugins.push({
|
|
1107
1163
|
name: "glob-import",
|
|
1108
|
-
transform: async (code, id) => {
|
|
1164
|
+
transform: async (code, id, _meta) => {
|
|
1109
1165
|
const result = await globPlugin.transform(code, id);
|
|
1110
1166
|
return result ? { code: result } : null;
|
|
1111
1167
|
}
|
|
@@ -1122,7 +1178,7 @@ async function rolldownBuild(ctx, entry, hooks, config) {
|
|
|
1122
1178
|
const shimsPlugin = createShimsPlugin(entry.shims);
|
|
1123
1179
|
if (shimsPlugin.transform) rolldownPlugins.push({
|
|
1124
1180
|
name: "shims",
|
|
1125
|
-
transform: async (code, id) => {
|
|
1181
|
+
transform: async (code, id, _meta) => {
|
|
1126
1182
|
const result = await shimsPlugin.transform(code, id);
|
|
1127
1183
|
return result ? { code: result } : null;
|
|
1128
1184
|
}
|
|
@@ -1135,18 +1191,8 @@ async function rolldownBuild(ctx, entry, hooks, config) {
|
|
|
1135
1191
|
resolveId: skipPlugin.resolveId
|
|
1136
1192
|
});
|
|
1137
1193
|
}
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
name: plugin.name,
|
|
1141
|
-
resolveId: plugin.resolveId,
|
|
1142
|
-
load: plugin.load,
|
|
1143
|
-
transform: plugin.transform ? async (code, id) => {
|
|
1144
|
-
const result = await plugin.transform(code, id);
|
|
1145
|
-
return result ? typeof result === "string" ? { code: result } : result : null;
|
|
1146
|
-
} : void 0
|
|
1147
|
-
});
|
|
1148
|
-
}
|
|
1149
|
-
const baseRolldownConfig = defu(entry.rolldown, {
|
|
1194
|
+
rolldownPlugins.push(...pluginManager.getRolldownPlugins());
|
|
1195
|
+
const robuildGeneratedConfig = {
|
|
1150
1196
|
cwd: ctx.pkgDir,
|
|
1151
1197
|
input: inputs,
|
|
1152
1198
|
plugins: rolldownPlugins,
|
|
@@ -1155,7 +1201,15 @@ async function rolldownBuild(ctx, entry, hooks, config) {
|
|
|
1155
1201
|
define: defineOptions,
|
|
1156
1202
|
resolve: { alias: entry.alias || {} },
|
|
1157
1203
|
transform: { target }
|
|
1158
|
-
}
|
|
1204
|
+
};
|
|
1205
|
+
if (entry.treeshake !== void 0) if (typeof entry.treeshake === "boolean") robuildGeneratedConfig.treeshake = entry.treeshake;
|
|
1206
|
+
else robuildGeneratedConfig.treeshake = entry.treeshake;
|
|
1207
|
+
const { output: userOutputConfig, plugins: userPlugins,...userRolldownConfig } = entry.rolldown || {};
|
|
1208
|
+
const baseRolldownConfig = {
|
|
1209
|
+
...robuildGeneratedConfig,
|
|
1210
|
+
...userRolldownConfig,
|
|
1211
|
+
plugins: [...rolldownPlugins, ...Array.isArray(userPlugins) ? userPlugins : userPlugins ? [userPlugins] : []]
|
|
1212
|
+
};
|
|
1159
1213
|
await hooks.rolldownConfig?.(baseRolldownConfig, ctx);
|
|
1160
1214
|
const allOutputEntries = [];
|
|
1161
1215
|
const filePathMap = /* @__PURE__ */ new Map();
|
|
@@ -1163,7 +1217,10 @@ async function rolldownBuild(ctx, entry, hooks, config) {
|
|
|
1163
1217
|
const rolldownFormat = formatToRolldownFormat(format);
|
|
1164
1218
|
const extension = getFormatExtension(format, platform, entry.fixedExtension);
|
|
1165
1219
|
const formatConfig = { ...baseRolldownConfig };
|
|
1166
|
-
if (entry.dts !== false && format === "esm")
|
|
1220
|
+
if (entry.dts !== false && format === "esm") {
|
|
1221
|
+
const dtsPlugins = dts({ ...entry.dts });
|
|
1222
|
+
formatConfig.plugins = [...Array.isArray(formatConfig.plugins) ? formatConfig.plugins : [formatConfig.plugins], ...Array.isArray(dtsPlugins) ? dtsPlugins : [dtsPlugins]];
|
|
1223
|
+
}
|
|
1167
1224
|
const res = await rolldown(formatConfig);
|
|
1168
1225
|
let formatOutDir = fullOutDir;
|
|
1169
1226
|
let entryFileName = `[name]${extension}`;
|
|
@@ -1179,7 +1236,7 @@ async function rolldownBuild(ctx, entry, hooks, config) {
|
|
|
1179
1236
|
formatOutDir = join(fullOutDir, "browser");
|
|
1180
1237
|
entryFileName = `[name].js`;
|
|
1181
1238
|
}
|
|
1182
|
-
const
|
|
1239
|
+
const robuildOutputConfig = {
|
|
1183
1240
|
dir: formatOutDir,
|
|
1184
1241
|
format: rolldownFormat,
|
|
1185
1242
|
entryFileNames: entryFileName,
|
|
@@ -1189,7 +1246,11 @@ async function rolldownBuild(ctx, entry, hooks, config) {
|
|
|
1189
1246
|
banner: resolveChunkAddon(entry.banner, format),
|
|
1190
1247
|
footer: resolveChunkAddon(entry.footer, format)
|
|
1191
1248
|
};
|
|
1192
|
-
if (entry.sourcemap !== void 0)
|
|
1249
|
+
if (entry.sourcemap !== void 0) robuildOutputConfig.sourcemap = entry.sourcemap;
|
|
1250
|
+
const outConfig = {
|
|
1251
|
+
...robuildOutputConfig,
|
|
1252
|
+
...userOutputConfig || {}
|
|
1253
|
+
};
|
|
1193
1254
|
await hooks.rolldownOutput?.(outConfig, res, ctx);
|
|
1194
1255
|
const { output } = await res.write(outConfig);
|
|
1195
1256
|
await res.close();
|
|
@@ -1242,7 +1303,7 @@ async function rolldownBuild(ctx, entry, hooks, config) {
|
|
|
1242
1303
|
}
|
|
1243
1304
|
}
|
|
1244
1305
|
if (entry.copy) await copyFiles(ctx.pkgDir, fullOutDir, entry.copy);
|
|
1245
|
-
await pluginManager.
|
|
1306
|
+
await pluginManager.executeRobuildBuildEnd({ allOutputEntries });
|
|
1246
1307
|
consola.log(`\n${allOutputEntries.map((o) => [
|
|
1247
1308
|
`${colors.magenta(`[bundle] `)}${colors.underline(fmtPath(filePathMap.get(o.name) || join(fullOutDir, o.name)))}`,
|
|
1248
1309
|
colors.dim(`${colors.bold("Size:")} ${prettyBytes(o.size)}, ${colors.bold(prettyBytes(o.minSize))} minified, ${prettyBytes(o.minGzipSize)} min+gzipped (Side effects: ${prettyBytes(o.sideEffectSize)})`),
|
|
@@ -1252,6 +1313,22 @@ async function rolldownBuild(ctx, entry, hooks, config) {
|
|
|
1252
1313
|
}
|
|
1253
1314
|
function normalizeBundleInputs(input, ctx) {
|
|
1254
1315
|
const inputs = {};
|
|
1316
|
+
if (typeof input === "object" && !Array.isArray(input)) {
|
|
1317
|
+
for (const [name, src] of Object.entries(input)) {
|
|
1318
|
+
const resolvedSrc = resolveModulePath(src, {
|
|
1319
|
+
from: ctx.pkgDir,
|
|
1320
|
+
extensions: [
|
|
1321
|
+
".ts",
|
|
1322
|
+
".js",
|
|
1323
|
+
".mjs",
|
|
1324
|
+
".cjs",
|
|
1325
|
+
".json"
|
|
1326
|
+
]
|
|
1327
|
+
});
|
|
1328
|
+
inputs[name] = resolvedSrc;
|
|
1329
|
+
}
|
|
1330
|
+
return inputs;
|
|
1331
|
+
}
|
|
1255
1332
|
for (let src of Array.isArray(input) ? input : [input]) {
|
|
1256
1333
|
src = resolveModulePath(src, {
|
|
1257
1334
|
from: ctx.pkgDir,
|
|
@@ -1499,176 +1576,6 @@ async function transformModule(entryPath, entry) {
|
|
|
1499
1576
|
return transformed;
|
|
1500
1577
|
}
|
|
1501
1578
|
|
|
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
1579
|
//#endregion
|
|
1673
1580
|
//#region src/features/logger.ts
|
|
1674
1581
|
/**
|
|
@@ -1904,267 +1811,120 @@ function convertExternal(external) {
|
|
|
1904
1811
|
}
|
|
1905
1812
|
|
|
1906
1813
|
//#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;
|
|
1814
|
+
//#region src/watch.ts
|
|
1815
|
+
function normalizePath$1(path, resolveFrom) {
|
|
1816
|
+
return typeof path === "string" && isAbsolute(path) ? path : path instanceof URL ? fileURLToPath(path) : resolve(resolveFrom || ".", path || ".");
|
|
1935
1817
|
}
|
|
1936
1818
|
/**
|
|
1937
|
-
*
|
|
1819
|
+
* Perform watch build using rolldown's built-in watch mode
|
|
1938
1820
|
*/
|
|
1939
|
-
function
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1821
|
+
async function performWatchBuild(config, ctx, startTime) {
|
|
1822
|
+
const { performBuild: performBuild$1 } = await import("./build-yfn0_Gzc.mjs");
|
|
1823
|
+
await performBuild$1(config, ctx, startTime);
|
|
1824
|
+
const bundleEntries = (config.entries || []).filter((entry) => {
|
|
1825
|
+
if (typeof entry === "string") return !entry.endsWith("/");
|
|
1826
|
+
return entry.type === "bundle";
|
|
1827
|
+
});
|
|
1828
|
+
if (bundleEntries.length > 0) await startRolldownWatch(ctx, bundleEntries);
|
|
1829
|
+
else {
|
|
1830
|
+
logger.warn("Transform-only watch mode not yet implemented with rolldown");
|
|
1831
|
+
return new Promise(() => {});
|
|
1948
1832
|
}
|
|
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
1833
|
}
|
|
1959
1834
|
/**
|
|
1960
|
-
*
|
|
1835
|
+
* Start rolldown watch mode for bundle entries
|
|
1961
1836
|
*/
|
|
1962
|
-
async function
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
if (
|
|
1968
|
-
const
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
return null;
|
|
1985
|
-
} catch {
|
|
1986
|
-
return null;
|
|
1837
|
+
async function startRolldownWatch(ctx, bundleEntries) {
|
|
1838
|
+
logger.info("🚧 Using rolldown built-in watch mode...");
|
|
1839
|
+
const watchConfigs = [];
|
|
1840
|
+
for (const rawEntry of bundleEntries) {
|
|
1841
|
+
let entry;
|
|
1842
|
+
if (typeof rawEntry === "string") {
|
|
1843
|
+
const [input, outDir] = rawEntry.split(":");
|
|
1844
|
+
entry = {
|
|
1845
|
+
type: "bundle",
|
|
1846
|
+
input,
|
|
1847
|
+
outDir: outDir || "dist"
|
|
1848
|
+
};
|
|
1849
|
+
} else entry = rawEntry;
|
|
1850
|
+
entry.input = Array.isArray(entry.input) ? entry.input.map((i) => normalizePath$1(i, ctx.pkgDir)) : normalizePath$1(entry.input, ctx.pkgDir);
|
|
1851
|
+
const watchConfig = {
|
|
1852
|
+
input: Array.isArray(entry.input) ? entry.input[0] : entry.input,
|
|
1853
|
+
output: {
|
|
1854
|
+
dir: entry.outDir,
|
|
1855
|
+
format: "esm"
|
|
1856
|
+
}
|
|
1857
|
+
};
|
|
1858
|
+
watchConfigs.push(watchConfig);
|
|
1987
1859
|
}
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
1860
|
+
const watcher = watch(watchConfigs);
|
|
1861
|
+
watcher.on("event", (event) => {
|
|
1862
|
+
switch (event.code) {
|
|
1863
|
+
case "START":
|
|
1864
|
+
logger.info("🔄 Rebuilding...");
|
|
1865
|
+
break;
|
|
1866
|
+
case "BUNDLE_START":
|
|
1867
|
+
logger.info("📦 Bundling...");
|
|
1868
|
+
break;
|
|
1869
|
+
case "BUNDLE_END":
|
|
1870
|
+
logger.success("✅ Bundle complete");
|
|
1871
|
+
break;
|
|
1872
|
+
case "END":
|
|
1873
|
+
logger.success("🎉 Watch rebuild complete");
|
|
1874
|
+
break;
|
|
1875
|
+
case "ERROR":
|
|
1876
|
+
logger.error("❌ Build error:", event.error);
|
|
1877
|
+
break;
|
|
1878
|
+
}
|
|
2006
1879
|
});
|
|
1880
|
+
const cleanup = async () => {
|
|
1881
|
+
consola.info("🛑 Stopping watch mode...");
|
|
1882
|
+
await watcher.close();
|
|
1883
|
+
process.exit(0);
|
|
1884
|
+
};
|
|
1885
|
+
process.on("SIGINT", cleanup);
|
|
1886
|
+
process.on("SIGTERM", cleanup);
|
|
1887
|
+
return new Promise(() => {});
|
|
2007
1888
|
}
|
|
2008
1889
|
|
|
2009
1890
|
//#endregion
|
|
2010
|
-
//#region src/
|
|
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);
|
|
2045
|
-
});
|
|
2046
|
-
if (process.env.DEBUG) {
|
|
2047
|
-
watcher.on("addDir", (path) => consola.debug(`📁 Directory added: ${path}`));
|
|
2048
|
-
watcher.on("unlinkDir", (path) => consola.debug(`📁 Directory removed: ${path}`));
|
|
2049
|
-
}
|
|
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
|
-
}
|
|
2064
|
-
/**
|
|
2065
|
-
* Handle file change events
|
|
2066
|
-
*/
|
|
2067
|
-
function handleFileChange(watchCtx, filePath, changeType) {
|
|
2068
|
-
const { config, ctx } = watchCtx;
|
|
2069
|
-
const watchOptions = config.watch || {};
|
|
2070
|
-
const delay = watchOptions.delay ?? 100;
|
|
2071
|
-
const relativePath = relative(ctx.pkgDir, join(ctx.pkgDir, filePath));
|
|
2072
|
-
const formattedPath = fmtPath(relativePath);
|
|
2073
|
-
const changeIcon = changeType === "changed" ? "📝" : changeType === "added" ? "➕" : "➖";
|
|
2074
|
-
consola.info(`${changeIcon} ${colors.cyan(formattedPath)} ${changeType}`);
|
|
2075
|
-
if (watchCtx.rebuildTimer) clearTimeout(watchCtx.rebuildTimer);
|
|
2076
|
-
watchCtx.pendingRebuild = true;
|
|
2077
|
-
watchCtx.rebuildTimer = setTimeout(() => {
|
|
2078
|
-
triggerRebuild(watchCtx);
|
|
2079
|
-
}, delay);
|
|
2080
|
-
}
|
|
1891
|
+
//#region src/build.ts
|
|
2081
1892
|
/**
|
|
2082
|
-
*
|
|
1893
|
+
* Normalize tsup-style config to entries-based config
|
|
2083
1894
|
*/
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
if (
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
1895
|
+
function normalizeTsupConfig(config) {
|
|
1896
|
+
if (config.entries && config.entries.length > 0) return config;
|
|
1897
|
+
if (config.entry) {
|
|
1898
|
+
const entry = {
|
|
1899
|
+
type: "bundle",
|
|
1900
|
+
entry: config.entry,
|
|
1901
|
+
format: config.format,
|
|
1902
|
+
outDir: config.outDir,
|
|
1903
|
+
platform: config.platform,
|
|
1904
|
+
target: config.target,
|
|
1905
|
+
globalName: config.name,
|
|
1906
|
+
minify: config.minify,
|
|
1907
|
+
dts: config.dts,
|
|
1908
|
+
dtsOnly: config.dtsOnly,
|
|
1909
|
+
splitting: config.splitting,
|
|
1910
|
+
treeshake: config.treeshake,
|
|
1911
|
+
sourcemap: config.sourcemap,
|
|
1912
|
+
external: config.external,
|
|
1913
|
+
noExternal: config.noExternal,
|
|
1914
|
+
env: config.env,
|
|
1915
|
+
alias: config.alias,
|
|
1916
|
+
banner: config.banner,
|
|
1917
|
+
footer: config.footer,
|
|
1918
|
+
shims: config.shims,
|
|
1919
|
+
rolldown: config.rolldown
|
|
1920
|
+
};
|
|
1921
|
+
return {
|
|
2094
1922
|
...config,
|
|
2095
|
-
|
|
2096
|
-
...config.watch,
|
|
2097
|
-
enabled: false
|
|
2098
|
-
}
|
|
1923
|
+
entries: [entry]
|
|
2099
1924
|
};
|
|
2100
|
-
await buildFn(buildConfig);
|
|
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);
|
|
2113
|
-
}
|
|
2114
|
-
}
|
|
2115
|
-
/**
|
|
2116
|
-
* Get patterns for files to watch
|
|
2117
|
-
*/
|
|
2118
|
-
async function getWatchPatterns(config, ctx, watchOptions) {
|
|
2119
|
-
if (watchOptions.include && watchOptions.include.length > 0) return watchOptions.include;
|
|
2120
|
-
const patterns = [];
|
|
2121
|
-
for (const entry of config.entries || []) if (typeof entry === "string") {
|
|
2122
|
-
const [input] = entry.split(":");
|
|
2123
|
-
if (input.endsWith("/")) patterns.push(`${input}**/*`);
|
|
2124
|
-
else {
|
|
2125
|
-
const inputs = input.split(",");
|
|
2126
|
-
for (const inputFile of inputs) {
|
|
2127
|
-
patterns.push(inputFile);
|
|
2128
|
-
const dir = inputFile.substring(0, inputFile.lastIndexOf("/"));
|
|
2129
|
-
if (dir) patterns.push(`${dir}/**/*`);
|
|
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}/**/*`);
|
|
2139
|
-
}
|
|
2140
1925
|
}
|
|
2141
|
-
|
|
2142
|
-
return [...new Set(patterns)];
|
|
2143
|
-
}
|
|
2144
|
-
/**
|
|
2145
|
-
* Get patterns for files to ignore
|
|
2146
|
-
*/
|
|
2147
|
-
function getIgnorePatterns(config, watchOptions) {
|
|
2148
|
-
const defaultIgnores = [
|
|
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;
|
|
1926
|
+
return config;
|
|
2164
1927
|
}
|
|
2165
|
-
|
|
2166
|
-
//#endregion
|
|
2167
|
-
//#region src/build.ts
|
|
2168
1928
|
/**
|
|
2169
1929
|
* Build dist/ from src/
|
|
2170
1930
|
*/
|
|
@@ -2178,7 +1938,6 @@ async function build(config) {
|
|
|
2178
1938
|
pkg,
|
|
2179
1939
|
pkgDir
|
|
2180
1940
|
};
|
|
2181
|
-
if (config.workspace) return buildWorkspace(config, pkgDir);
|
|
2182
1941
|
let finalConfig = config;
|
|
2183
1942
|
if (config.fromVite) {
|
|
2184
1943
|
logger.verbose("Loading configuration from Vite config file");
|
|
@@ -2188,18 +1947,11 @@ async function build(config) {
|
|
|
2188
1947
|
...config
|
|
2189
1948
|
};
|
|
2190
1949
|
}
|
|
1950
|
+
finalConfig = normalizeTsupConfig(finalConfig);
|
|
2191
1951
|
if (finalConfig.watch?.enabled) {
|
|
2192
1952
|
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(() => {});
|
|
1953
|
+
await performWatchBuild(finalConfig, ctx, startTime);
|
|
1954
|
+
return;
|
|
2203
1955
|
}
|
|
2204
1956
|
logger.info(`📦 Building \`${ctx.pkg.name || "<no name>"}\` (\`${ctx.pkgDir}\`)`);
|
|
2205
1957
|
await performBuild(finalConfig, ctx, startTime);
|
|
@@ -2225,10 +1977,17 @@ async function performBuild(config, ctx, startTime) {
|
|
|
2225
1977
|
outDir
|
|
2226
1978
|
};
|
|
2227
1979
|
} else entry = rawEntry;
|
|
2228
|
-
|
|
1980
|
+
const hasInput = entry.type === "transform" ? !!entry.input : !!(entry.input || entry.entry);
|
|
1981
|
+
if (!hasInput) throw new Error(`Build entry missing \`input\` or \`entry\`: ${JSON.stringify(entry, null, 2)}`);
|
|
2229
1982
|
entry = { ...entry };
|
|
2230
1983
|
entry.outDir = normalizePath(entry.outDir || "dist", ctx.pkgDir);
|
|
2231
|
-
|
|
1984
|
+
const entryInput = entry.input || entry.entry;
|
|
1985
|
+
if (entryInput) if (typeof entryInput === "object" && !Array.isArray(entryInput)) {
|
|
1986
|
+
const normalizedInput = {};
|
|
1987
|
+
for (const [key, value] of Object.entries(entryInput)) normalizedInput[key] = normalizePath(value, ctx.pkgDir);
|
|
1988
|
+
entry.input = normalizedInput;
|
|
1989
|
+
} else if (Array.isArray(entryInput)) entry.input = entryInput.map((p) => normalizePath(p, ctx.pkgDir));
|
|
1990
|
+
else entry.input = normalizePath(entryInput, ctx.pkgDir);
|
|
2232
1991
|
return entry;
|
|
2233
1992
|
});
|
|
2234
1993
|
await hooks.entries?.(entries, ctx);
|
|
@@ -2249,56 +2008,10 @@ async function performBuild(config, ctx, startTime) {
|
|
|
2249
2008
|
function normalizePath(path, resolveFrom) {
|
|
2250
2009
|
return typeof path === "string" && isAbsolute(path) ? path : path instanceof URL ? fileURLToPath(path) : resolve(resolveFrom || ".", path || ".");
|
|
2251
2010
|
}
|
|
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);
|
|
2011
|
+
async function readJSON(specifier) {
|
|
2012
|
+
const module = await import(specifier, { with: { type: "json" } });
|
|
2013
|
+
return module.default;
|
|
2301
2014
|
}
|
|
2302
2015
|
|
|
2303
2016
|
//#endregion
|
|
2304
|
-
export { build };
|
|
2017
|
+
export { SHEBANG_RE, build, hasShebang, makeExecutable, nodeProtocolPlugin, performBuild, shebangPlugin };
|