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 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
- 🏢 **Enterprise**: Workspace support, package filtering, migration tools
24
+ 📤 **Exports**: Automatic package.json exports generation
25
25
 
26
26
  ## Installation
27
27
 
@@ -0,0 +1,3 @@
1
+ import { build, performBuild } from "./build-Dtx2Wt3D.mjs";
2
+
3
+ export { performBuild };
@@ -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 (id.includes("node_modules") || !id.startsWith(".") && !id.startsWith("/")) return {
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, filePath, entry) {
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, quote, pattern, optionsStr] = match;
233
+ const [fullMatch, , pattern, optionsStr] = match;
235
234
  let globOptions = {};
236
235
  if (optionsStr) try {
237
236
  globOptions = parseGlobOptions(optionsStr);
238
- } catch (error) {
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 (error) {
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}(\.|$)/.test(filename);
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": return `export default ${content}`;
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, options) {
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, options) {
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 [...new Set(matches.map((match) => match.slice(1)))];
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?.[extname(id)]?.options;
521
+ const options = loaders?.[ext]?.options;
516
522
  return await transformWithLoader(id, content, loader, options);
517
- } catch (error) {
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/builders/plugins/node-protocol.ts
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/builders/plugins/shebang.ts
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/features/workspace.ts
1908
- /**
1909
- * Discover workspace packages based on patterns
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
- * Build workspace packages in dependency order
1748
+ * Perform watch build using rolldown's built-in watch mode
1991
1749
  */
1992
- async function buildWorkspacePackages(packages, buildFn) {
1993
- await Promise.all(packages.map(buildFn));
1994
- }
1995
-
1996
- //#endregion
1997
- //#region src/features/ignore-watch.ts
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 (process.env.DEBUG) {
2047
- watcher.on("addDir", (path) => consola.debug(`📁 Directory added: ${path}`));
2048
- watcher.on("unlinkDir", (path) => consola.debug(`📁 Directory removed: ${path}`));
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
- * Handle file change events
1764
+ * Start rolldown watch mode for bundle entries
2066
1765
  */
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
- }
2081
- /**
2082
- * Trigger a rebuild
2083
- */
2084
- async function triggerRebuild(watchCtx) {
2085
- const { config, buildFn } = watchCtx;
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
- 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);
1787
+ watchConfigs.push(watchConfig);
2113
1788
  }
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}/**/*`);
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
- if (patterns.length === 0) patterns.push("src/**/*", "*.ts", "*.js", "*.mjs", "*.json");
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;
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 performBuild(finalConfig, ctx, startTime);
2194
- const stopWatch = await startWatch(finalConfig, ctx, build);
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
- * Build workspace packages
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.13";
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 vitest",
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-C9gSlxzR.mjs";
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
- --workspace Enable workspace mode for monorepo builds
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-BDpkh_pL.mjs";
1
+ import { defineConfig } from "./_chunks/config-BOcpEsqS.mjs";
2
2
  export { defineConfig };
package/dist/config.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { defineConfig } from "./_chunks/config-B_2eqpNJ.mjs";
1
+ import { defineConfig } from "./_chunks/config-C1aXyI1S.mjs";
2
2
 
3
3
  export { defineConfig };
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { BuildConfig, BuildEntry, BundleEntry, TransformEntry, defineConfig } from "./_chunks/config-BDpkh_pL.mjs";
1
+ import { BuildConfig, BuildEntry, BundleEntry, TransformEntry, defineConfig } from "./_chunks/config-BOcpEsqS.mjs";
2
2
 
3
3
  //#region src/build.d.ts
4
4
 
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { build } from "./_chunks/build-C9gSlxzR.mjs";
2
- import { defineConfig } from "./_chunks/config-B_2eqpNJ.mjs";
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.13",
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 vitest",
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",