robuild 0.0.18 → 0.0.19

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.
@@ -1,4 +1,4 @@
1
- import { RobuildPluginManager } from "./plugin-manager-w5yRGJRn.mjs";
1
+ import { t as RobuildPluginManager } from "./plugin-manager-CwMXjVtp.mjs";
2
2
  import { builtinModules } from "node:module";
3
3
  import { basename, dirname, extname, isAbsolute, join, relative, resolve } from "node:path";
4
4
  import { fileURLToPath, pathToFileURL } from "node:url";
@@ -52,9 +52,7 @@ function createSkipNodeModulesPlugin(options) {
52
52
  * Unbundle mode: preserve file structure without bundling
53
53
  */
54
54
  async function unbundleTransform(ctx, entry) {
55
- const inputDir = isAbsolute(entry.input) ? entry.input : join(ctx.pkgDir, entry.input);
56
- const outputDir = join(ctx.pkgDir, entry.outDir || "dist");
57
- await processDirectoryUnbundled(inputDir, outputDir, entry);
55
+ await processDirectoryUnbundled(isAbsolute(entry.input) ? entry.input : join(ctx.pkgDir, entry.input), join(ctx.pkgDir, entry.outDir || "dist"), entry);
58
56
  }
59
57
  /**
60
58
  * Process directory in unbundle mode
@@ -87,8 +85,7 @@ async function processFileUnbundled(inputPath, outputPath, entry) {
87
85
  ".cts"
88
86
  ].includes(ext)) return;
89
87
  try {
90
- const content = await readFile(inputPath, "utf-8");
91
- const transformedContent = transformImportsForUnbundle(content, inputPath, entry);
88
+ const transformedContent = transformImportsForUnbundle(await readFile(inputPath, "utf-8"), inputPath, entry);
92
89
  const outputExt = getUnbundleOutputExtension(ext, entry);
93
90
  const finalOutputPath = outputPath.replace(ext, outputExt);
94
91
  await mkdir(dirname(finalOutputPath), { recursive: true });
@@ -159,10 +156,9 @@ function getUnbundleOutputExtension(inputExt, entry) {
159
156
  * Resolve banner/footer addon for specific format
160
157
  */
161
158
  function resolveChunkAddon(addon, format) {
162
- if (!addon) return void 0;
159
+ if (!addon) return;
163
160
  if (typeof addon === "string") return addon;
164
- const formatKey = format === "es" ? "js" : format;
165
- return addon[formatKey] || addon.js;
161
+ return addon[format === "es" ? "js" : format] || addon.js;
166
162
  }
167
163
  /**
168
164
  * Add banner to content
@@ -213,6 +209,88 @@ async function copyFiles(cwd, outDir, copyOptions) {
213
209
  consola.debug("✅ Files copied successfully");
214
210
  }
215
211
 
212
+ //#endregion
213
+ //#region src/features/external.ts
214
+ /**
215
+ * Build external dependencies list from package.json dependencies and peerDependencies.
216
+ * This is the shared logic used by both bundle and watch modes.
217
+ */
218
+ function buildExternalDeps(ctx) {
219
+ return [
220
+ ...builtinModules,
221
+ ...builtinModules.map((m) => `node:${m}`),
222
+ ...[...Object.keys(ctx.pkg.dependencies || {}), ...Object.keys(ctx.pkg.peerDependencies || {})].flatMap((p) => [p, new RegExp(`^${p}/`)])
223
+ ];
224
+ }
225
+ /**
226
+ * Escape special regex characters in a string
227
+ */
228
+ function escapeRegExp(s) {
229
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
230
+ }
231
+ /**
232
+ * Apply noExternal configuration to filter out dependencies that should be bundled.
233
+ * Supports both function and array forms.
234
+ */
235
+ function applyNoExternal(externalDeps, noExternal, ctx) {
236
+ if (!noExternal) return externalDeps;
237
+ if (typeof noExternal === "function") {
238
+ const predicate = noExternal;
239
+ const depNames = [...Object.keys(ctx.pkg.dependencies || {}), ...Object.keys(ctx.pkg.peerDependencies || {})];
240
+ const excludedNames = /* @__PURE__ */ new Set();
241
+ for (const name of depNames) try {
242
+ if (predicate(name)) excludedNames.add(name);
243
+ } catch {}
244
+ return externalDeps.filter((dep) => {
245
+ if (typeof dep === "string") return !excludedNames.has(dep);
246
+ if (dep instanceof RegExp) {
247
+ for (const name of Array.from(excludedNames)) if (dep.source.startsWith(`^${escapeRegExp(name)}/`)) return false;
248
+ return true;
249
+ }
250
+ return true;
251
+ });
252
+ }
253
+ if (Array.isArray(noExternal)) {
254
+ const rules = noExternal;
255
+ return externalDeps.filter((dep) => {
256
+ for (const rule of rules) if (typeof rule === "string") {
257
+ if (typeof dep === "string") {
258
+ if (dep === rule) return false;
259
+ } else if (dep instanceof RegExp) {
260
+ if (dep.source.startsWith(`^${escapeRegExp(rule)}/`)) return false;
261
+ }
262
+ } else if (rule instanceof RegExp) {
263
+ if (typeof dep === "string") {
264
+ if (rule.test(dep)) return false;
265
+ } else if (dep instanceof RegExp) {
266
+ if (dep.source === rule.source && dep.flags === rule.flags) return false;
267
+ }
268
+ }
269
+ return true;
270
+ });
271
+ }
272
+ return externalDeps;
273
+ }
274
+ /**
275
+ * Add custom external dependencies to the list.
276
+ * Only handles array form; function form is handled separately.
277
+ */
278
+ function addCustomExternal(externalDeps, external) {
279
+ if (external && typeof external !== "function") return [...externalDeps, ...external];
280
+ return externalDeps;
281
+ }
282
+ /**
283
+ * Build the complete external configuration for rolldown.
284
+ * Returns either a function (if entry.external is a function) or the processed array.
285
+ */
286
+ function resolveExternalConfig(ctx, options) {
287
+ let externalDeps = buildExternalDeps(ctx);
288
+ externalDeps = applyNoExternal(externalDeps, options.noExternal, ctx);
289
+ externalDeps = addCustomExternal(externalDeps, options.external);
290
+ if (typeof options.external === "function") return options.external;
291
+ return externalDeps;
292
+ }
293
+
216
294
  //#endregion
217
295
  //#region src/features/glob-import.ts
218
296
  /**
@@ -258,8 +336,7 @@ async function generateGlobImport(pattern, importer, eager, asUrls, allowedPatte
258
336
  if (!isPatternAllowed(pattern, allowedPatterns)) throw new Error(`Glob pattern "${pattern}" is not allowed`);
259
337
  let files = [];
260
338
  try {
261
- const absolutePattern = resolve(importerDir, pattern);
262
- files = await glob(absolutePattern, { ignore: ["**/node_modules/**", "**/.git/**"] });
339
+ files = await glob(resolve(importerDir, pattern), { ignore: ["**/node_modules/**", "**/.git/**"] });
263
340
  } catch {
264
341
  if (pattern.includes("*.js")) files = [resolve(importerDir, pattern.replace("*", "module1")), resolve(importerDir, pattern.replace("*", "module2"))];
265
342
  }
@@ -336,9 +413,7 @@ function addHashToFilename(filename, content, hashLength = 8) {
336
413
  const hash = generateContentHash(content, hashLength);
337
414
  const dotIndex = filename.lastIndexOf(".");
338
415
  if (dotIndex === -1) return `${filename}-${hash}`;
339
- const name = filename.slice(0, dotIndex);
340
- const ext = filename.slice(dotIndex);
341
- return `${name}-${hash}${ext}`;
416
+ return `${filename.slice(0, dotIndex)}-${hash}${filename.slice(dotIndex)}`;
342
417
  }
343
418
  /**
344
419
  * Check if filename already has hash
@@ -402,15 +477,11 @@ if (typeof exports === 'undefined') {
402
477
  */
403
478
  function detectShimNeeds(code) {
404
479
  const cleanCode = removeCommentsAndStrings(code);
405
- const needsDirname = /\b__dirname\b/.test(cleanCode) || /\b__filename\b/.test(cleanCode);
406
- const needsRequire = /\brequire\s*\(/.test(cleanCode);
407
- const needsExports = /\bmodule\.exports\b/.test(cleanCode) || /\bexports\.\w+/.test(cleanCode);
408
- const needsEnv = /\bprocess\.env\b/.test(cleanCode);
409
480
  return {
410
- needsDirname,
411
- needsRequire,
412
- needsExports,
413
- needsEnv
481
+ needsDirname: /\b__dirname\b/.test(cleanCode) || /\b__filename\b/.test(cleanCode),
482
+ needsRequire: /\brequire\s*\(/.test(cleanCode),
483
+ needsExports: /\bmodule\.exports\b/.test(cleanCode) || /\bexports\.\w+/.test(cleanCode),
484
+ needsEnv: /\bprocess\.env\b/.test(cleanCode)
414
485
  };
415
486
  }
416
487
  /**
@@ -438,8 +509,7 @@ const require = createRequire(import.meta.url)
438
509
  * Transform code to use shims
439
510
  */
440
511
  function transformWithShims(code, config) {
441
- const needs = detectShimNeeds(code);
442
- const shims = generateShims(config, needs);
512
+ const shims = generateShims(config, detectShimNeeds(code));
443
513
  if (!shims) return code;
444
514
  return `${shims}\n${code}`;
445
515
  }
@@ -552,8 +622,7 @@ function processNodeProtocol(id, nodeProtocol) {
552
622
  */
553
623
  function transformNodeProtocol(code, nodeProtocol) {
554
624
  if (!nodeProtocol) return code;
555
- const importRegex = /(?:import|export)(?:\s[^'"]*)?\s['"]([^'"]+)['"]/g;
556
- return code.replace(importRegex, (match, moduleId) => {
625
+ return code.replace(/(?:import|export)(?:\s[^'"]*)?\s['"]([^'"]+)['"]/g, (match, moduleId) => {
557
626
  const processedId = processNodeProtocol(moduleId, nodeProtocol);
558
627
  return match.replace(moduleId, processedId);
559
628
  });
@@ -586,10 +655,7 @@ function shebangPlugin() {
586
655
  async writeBundle(options, bundle) {
587
656
  for (const [fileName, output] of Object.entries(bundle)) {
588
657
  if (output.type !== "chunk") continue;
589
- if (hasShebang(output.code)) {
590
- const outFile = resolve(options.dir, fileName);
591
- await makeExecutable(outFile);
592
- }
658
+ if (hasShebang(output.code)) await makeExecutable(resolve(options.dir, fileName));
593
659
  }
594
660
  }
595
661
  };
@@ -608,15 +674,15 @@ function fmtPath(path) {
608
674
  }
609
675
  function analyzeDir(dir) {
610
676
  if (Array.isArray(dir)) {
611
- let totalSize$1 = 0;
677
+ let totalSize = 0;
612
678
  let totalFiles = 0;
613
679
  for (const d of dir) {
614
680
  const { size, files } = analyzeDir(d);
615
- totalSize$1 += size;
681
+ totalSize += size;
616
682
  totalFiles += files;
617
683
  }
618
684
  return {
619
- size: totalSize$1,
685
+ size: totalSize,
620
686
  files: totalFiles
621
687
  };
622
688
  }
@@ -646,13 +712,12 @@ function analyzeDir(dir) {
646
712
  }
647
713
  }
648
714
  async function distSize(dir, entry) {
649
- const build$1 = await rolldown({
715
+ const { output } = await (await rolldown({
650
716
  input: join(dir, entry),
651
717
  plugins: [],
652
718
  platform: "neutral",
653
719
  external: (id) => id[0] !== "." && !id.startsWith(dir)
654
- });
655
- const { output } = await build$1.generate({ inlineDynamicImports: true });
720
+ })).generate({ inlineDynamicImports: true });
656
721
  const code = output[0].code;
657
722
  const { code: minified } = await minify(entry, code);
658
723
  return {
@@ -662,26 +727,24 @@ async function distSize(dir, entry) {
662
727
  };
663
728
  }
664
729
  async function sideEffectSize(dir, entry) {
665
- const virtualEntry = {
666
- name: "virtual-entry",
667
- async resolveId(id, importer, opts) {
668
- if (id === "#entry") return { id };
669
- const resolved = await this.resolve(id, importer, opts);
670
- if (!resolved) return null;
671
- resolved.moduleSideEffects = null;
672
- return resolved;
673
- },
674
- load(id) {
675
- if (id === "#entry") return `import * as _lib from "${join(dir, entry)}";`;
676
- }
677
- };
678
- const build$1 = await rolldown({
730
+ const { output } = await (await rolldown({
679
731
  input: "#entry",
680
732
  platform: "neutral",
681
733
  external: (id) => id[0] !== "." && !id.startsWith(dir),
682
- plugins: [virtualEntry]
683
- });
684
- const { output } = await build$1.generate({ inlineDynamicImports: true });
734
+ plugins: [{
735
+ name: "virtual-entry",
736
+ async resolveId(id, importer, opts) {
737
+ if (id === "#entry") return { id };
738
+ const resolved = await this.resolve(id, importer, opts);
739
+ if (!resolved) return null;
740
+ resolved.moduleSideEffects = null;
741
+ return resolved;
742
+ },
743
+ load(id) {
744
+ if (id === "#entry") return `import * as _lib from "${join(dir, entry)}";`;
745
+ }
746
+ }]
747
+ })).generate({ inlineDynamicImports: true });
685
748
  if (process.env.INSPECT_BUILD) {
686
749
  console.log("---------[side effects]---------");
687
750
  console.log(entry);
@@ -715,9 +778,9 @@ function getFormatExtension(format, platform, fixedExtension = false) {
715
778
  async function cleanOutputDir$1(projectRoot, outDir, cleanPaths) {
716
779
  if (!cleanPaths) return;
717
780
  const { rm } = await import("node:fs/promises");
718
- const { existsSync: existsSync$1 } = await import("node:fs");
781
+ const { existsSync } = await import("node:fs");
719
782
  if (cleanPaths === true) {
720
- if (existsSync$1(outDir)) {
783
+ if (existsSync(outDir)) {
721
784
  consola.log(`🧻 Cleaning up ${fmtPath(outDir)}`);
722
785
  await rm(outDir, {
723
786
  recursive: true,
@@ -726,7 +789,7 @@ async function cleanOutputDir$1(projectRoot, outDir, cleanPaths) {
726
789
  }
727
790
  } else if (Array.isArray(cleanPaths)) for (const path of cleanPaths) {
728
791
  const fullPath = resolve(projectRoot, path);
729
- if (existsSync$1(fullPath)) {
792
+ if (existsSync(fullPath)) {
730
793
  consola.log(`🧻 Cleaning up ${fmtPath(fullPath)}`);
731
794
  await rm(fullPath, {
732
795
  recursive: true,
@@ -765,9 +828,7 @@ async function rolldownBuild(ctx, entry, hooks, config) {
765
828
  await mkdir(dirname(distPath), { recursive: true });
766
829
  consola.log(`${colors.magenta("[stub bundle] ")} ${colors.underline(fmtPath(distPath))}`);
767
830
  const srcContents = await readFile(srcPath, "utf8");
768
- const parsed = parseSync(srcPath, srcContents);
769
- const exportNames = parsed.module.staticExports.flatMap((e) => e.entries.map((e$1) => e$1.exportName.kind === "Default" ? "default" : e$1.exportName.name));
770
- const hasDefaultExport = exportNames.includes("default");
831
+ const hasDefaultExport = parseSync(srcPath, srcContents).module.staticExports.flatMap((e) => e.entries.map((e) => e.exportName.kind === "Default" ? "default" : e.exportName.name)).includes("default");
771
832
  const firstLine = srcContents.split("\n")[0];
772
833
  const hasShebangLine = firstLine.startsWith("#!");
773
834
  await writeFile(distPath, `${hasShebangLine ? `${firstLine}\n` : ""}export * from "${srcPath}";\n${hasDefaultExport ? `export { default } from "${srcPath}";\n` : ""}`, "utf8");
@@ -776,49 +837,10 @@ async function rolldownBuild(ctx, entry, hooks, config) {
776
837
  }
777
838
  return;
778
839
  }
779
- let externalDeps = [
780
- ...builtinModules,
781
- ...builtinModules.map((m) => `node:${m}`),
782
- ...[...Object.keys(ctx.pkg.dependencies || {}), ...Object.keys(ctx.pkg.peerDependencies || {})].flatMap((p) => [p, /* @__PURE__ */ new RegExp(`^${p}/`)])
783
- ];
784
- if (entry.noExternal) {
785
- const escapeRegExp = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
786
- if (typeof entry.noExternal === "function") {
787
- const predicate = entry.noExternal;
788
- const depNames = [...Object.keys(ctx.pkg.dependencies || {}), ...Object.keys(ctx.pkg.peerDependencies || {})];
789
- const excludedNames = /* @__PURE__ */ new Set();
790
- for (const name of depNames) try {
791
- if (predicate(name)) excludedNames.add(name);
792
- } catch {}
793
- externalDeps = externalDeps.filter((dep) => {
794
- if (typeof dep === "string") return !excludedNames.has(dep);
795
- if (dep instanceof RegExp) {
796
- for (const name of Array.from(excludedNames)) if (dep.source.startsWith(`^${escapeRegExp(name)}/`)) return false;
797
- return true;
798
- }
799
- return true;
800
- });
801
- } else if (Array.isArray(entry.noExternal)) {
802
- const rules = entry.noExternal;
803
- externalDeps = externalDeps.filter((dep) => {
804
- for (const rule of rules) if (typeof rule === "string") {
805
- if (typeof dep === "string") {
806
- if (dep === rule) return false;
807
- } else if (dep instanceof RegExp) {
808
- if (dep.source.startsWith(`^${escapeRegExp(rule)}/`)) return false;
809
- }
810
- } else if (rule instanceof RegExp) {
811
- if (typeof dep === "string") {
812
- if (rule.test(dep)) return false;
813
- } else if (dep instanceof RegExp) {
814
- if (dep.source === rule.source && dep.flags === rule.flags) return false;
815
- }
816
- }
817
- return true;
818
- });
819
- }
820
- }
821
- if (entry.external) if (typeof entry.external === "function") {} else externalDeps.push(...entry.external);
840
+ const externalConfig = resolveExternalConfig(ctx, {
841
+ external: entry.external,
842
+ noExternal: entry.noExternal
843
+ });
822
844
  const defineOptions = {};
823
845
  if (entry.env) for (const [key, value] of Object.entries(entry.env)) defineOptions[`process.env.${key}`] = JSON.stringify(value);
824
846
  if (entry.define) for (const [key, value] of Object.entries(entry.define)) defineOptions[key] = value;
@@ -852,21 +874,23 @@ async function rolldownBuild(ctx, entry, hooks, config) {
852
874
  }
853
875
  rolldownPlugins.push(...pluginManager.getRolldownPlugins());
854
876
  const moduleTypes = {};
855
- if (entry.loaders) for (const [ext, config$1] of Object.entries(entry.loaders)) moduleTypes[ext] = config$1.loader;
877
+ if (entry.loaders) for (const [ext, config] of Object.entries(entry.loaders)) moduleTypes[ext] = config.loader;
856
878
  const robuildGeneratedConfig = {
857
879
  cwd: ctx.pkgDir,
858
880
  input: inputs,
859
881
  plugins: rolldownPlugins,
860
882
  platform: platform === "node" ? "node" : "neutral",
861
- external: typeof entry.external === "function" ? entry.external : externalDeps,
862
- define: defineOptions,
883
+ external: externalConfig,
863
884
  resolve: { alias: entry.alias || {} },
864
- transform: { target },
885
+ transform: {
886
+ target,
887
+ define: defineOptions
888
+ },
865
889
  ...Object.keys(moduleTypes).length > 0 ? { moduleTypes } : {}
866
890
  };
867
891
  if (entry.treeshake !== void 0) if (typeof entry.treeshake === "boolean") robuildGeneratedConfig.treeshake = entry.treeshake;
868
892
  else robuildGeneratedConfig.treeshake = entry.treeshake;
869
- const { output: userOutputConfig, plugins: userPlugins,...userRolldownConfig } = entry.rolldown || {};
893
+ const { output: userOutputConfig, plugins: userPlugins, ...userRolldownConfig } = entry.rolldown || {};
870
894
  const baseRolldownConfig = {
871
895
  ...robuildGeneratedConfig,
872
896
  ...userRolldownConfig,
@@ -894,7 +918,10 @@ async function rolldownBuild(ctx, entry, hooks, config) {
894
918
  dir: formatOutDir,
895
919
  format,
896
920
  entryFileNames: entryFileName,
897
- chunkFileNames: `_chunks/[name]-[hash]${extension}`,
921
+ chunkFileNames: (chunk) => {
922
+ if (chunk.name.endsWith(".d") || chunk.name.includes(".d.")) return `[name].mjs`;
923
+ return `_chunks/[name]-[hash]${extension}`;
924
+ },
898
925
  minify: entry.minify,
899
926
  name: entry.globalName,
900
927
  banner: resolveChunkAddon(entry.banner, format),
@@ -938,9 +965,7 @@ async function rolldownBuild(ctx, entry, hooks, config) {
938
965
  const { rename } = await import("node:fs/promises");
939
966
  await rename(finalFilePath, hashedFilePath);
940
967
  try {
941
- const mapOld = `${finalFilePath}.map`;
942
- const mapNew = `${hashedFilePath}.map`;
943
- await rename(mapOld, mapNew);
968
+ await rename(`${finalFilePath}.map`, `${hashedFilePath}.map`);
944
969
  } catch {}
945
970
  finalFileName = hashedFileName;
946
971
  finalFilePath = hashedFilePath;
@@ -968,19 +993,16 @@ async function rolldownBuild(ctx, entry, hooks, config) {
968
993
  function normalizeBundleInputs(input, ctx) {
969
994
  const inputs = {};
970
995
  if (typeof input === "object" && !Array.isArray(input)) {
971
- for (const [name, src] of Object.entries(input)) {
972
- const resolvedSrc = resolveModulePath(src, {
973
- from: ctx.pkgDir,
974
- extensions: [
975
- ".ts",
976
- ".js",
977
- ".mjs",
978
- ".cjs",
979
- ".json"
980
- ]
981
- });
982
- inputs[name] = resolvedSrc;
983
- }
996
+ for (const [name, src] of Object.entries(input)) inputs[name] = resolveModulePath(src, {
997
+ from: ctx.pkgDir,
998
+ extensions: [
999
+ ".ts",
1000
+ ".js",
1001
+ ".mjs",
1002
+ ".cjs",
1003
+ ".json"
1004
+ ]
1005
+ });
984
1006
  return inputs;
985
1007
  }
986
1008
  for (let src of Array.isArray(input) ? input : [input]) {
@@ -1049,14 +1071,14 @@ function applyOutExtensions(format, outExtensions) {
1049
1071
  /**
1050
1072
  * Create filename with proper extension
1051
1073
  */
1052
- function createFilename(basename$1, format, isDts = false, options = {}) {
1074
+ function createFilename(basename, format, isDts = false, options = {}) {
1053
1075
  const { platform, fixedExtension, outExtensions } = options;
1054
1076
  if (outExtensions) {
1055
1077
  const extensions = applyOutExtensions(format, outExtensions);
1056
- return `${basename$1}.${isDts ? extensions.dts : extensions.js}`;
1078
+ return `${basename}.${isDts ? extensions.dts : extensions.js}`;
1057
1079
  }
1058
- if (isDts) return `${basename$1}.${resolveDtsOutputExtension(format, fixedExtension)}`;
1059
- return `${basename$1}.${resolveJsOutputExtension(format, platform, fixedExtension)}`;
1080
+ if (isDts) return `${basename}.${resolveDtsOutputExtension(format, fixedExtension)}`;
1081
+ return `${basename}.${resolveJsOutputExtension(format, platform, fixedExtension)}`;
1060
1082
  }
1061
1083
 
1062
1084
  //#endregion
@@ -1067,9 +1089,9 @@ function createFilename(basename$1, format, isDts = false, options = {}) {
1067
1089
  async function cleanOutputDir(projectRoot, outDir, cleanPaths) {
1068
1090
  if (!cleanPaths) return;
1069
1091
  const { rm } = await import("node:fs/promises");
1070
- const { existsSync: existsSync$1 } = await import("node:fs");
1092
+ const { existsSync } = await import("node:fs");
1071
1093
  if (cleanPaths === true) {
1072
- if (existsSync$1(outDir)) {
1094
+ if (existsSync(outDir)) {
1073
1095
  consola.log(`🧻 Cleaning up ${fmtPath(outDir)}`);
1074
1096
  await rm(outDir, {
1075
1097
  recursive: true,
@@ -1078,7 +1100,7 @@ async function cleanOutputDir(projectRoot, outDir, cleanPaths) {
1078
1100
  }
1079
1101
  } else if (Array.isArray(cleanPaths)) for (const path of cleanPaths) {
1080
1102
  const fullPath = resolve(projectRoot, path);
1081
- if (existsSync$1(fullPath)) {
1103
+ if (existsSync(fullPath)) {
1082
1104
  consola.log(`🧻 Cleaning up ${fmtPath(fullPath)}`);
1083
1105
  await rm(fullPath, {
1084
1106
  recursive: true,
@@ -1103,23 +1125,21 @@ async function transformDir(ctx, entry) {
1103
1125
  }
1104
1126
  const fullOutDir = resolve(ctx.pkgDir, entry.outDir);
1105
1127
  await cleanOutputDir(ctx.pkgDir, fullOutDir, entry.clean ?? true);
1106
- const { statSync: statSync$1 } = await import("node:fs");
1128
+ const { statSync } = await import("node:fs");
1107
1129
  let inputDir = entry.input;
1108
1130
  try {
1109
- const stats = statSync$1(inputDir);
1110
- if (stats.isFile()) {
1131
+ if (statSync(inputDir).isFile()) {
1111
1132
  inputDir = dirname(inputDir);
1112
1133
  consola.warn(`Transform input should be a directory, not a file. Using directory: ${fmtPath(inputDir)}`);
1113
1134
  }
1114
1135
  } catch (error) {
1115
1136
  if (error.code !== "ENOENT") throw error;
1116
1137
  }
1117
- const promises$1 = [];
1138
+ const promises = [];
1118
1139
  const files = await glob$1("**/*.*", { cwd: inputDir });
1119
- for await (const entryName of files) promises$1.push((async () => {
1140
+ for await (const entryName of files) promises.push((async () => {
1120
1141
  const entryPath = join(inputDir, entryName);
1121
- const ext = extname(entryPath);
1122
- switch (ext) {
1142
+ switch (extname(entryPath)) {
1123
1143
  case ".ts":
1124
1144
  case ".tsx":
1125
1145
  case ".jsx": {
@@ -1133,11 +1153,7 @@ async function transformDir(ctx, entry) {
1133
1153
  let entryDistPath = join(entry.outDir, outputFileName);
1134
1154
  await mkdir(dirname(entryDistPath), { recursive: true });
1135
1155
  await writeFile(entryDistPath, transformed.code, "utf8");
1136
- if (entry.sourcemap && transformed.map) {
1137
- const mapPath = `${entryDistPath}.map`;
1138
- const mapContent = typeof transformed.map === "string" ? transformed.map : JSON.stringify(transformed.map);
1139
- await writeFile(mapPath, mapContent, "utf8");
1140
- }
1156
+ if (entry.sourcemap && transformed.map) await writeFile(`${entryDistPath}.map`, typeof transformed.map === "string" ? transformed.map : JSON.stringify(transformed.map), "utf8");
1141
1157
  if (entry.hash && !hasHash(entryDistPath)) {
1142
1158
  const hashedPath = addHashToFilename(entryDistPath, transformed.code);
1143
1159
  const { rename } = await import("node:fs/promises");
@@ -1151,8 +1167,7 @@ async function transformDir(ctx, entry) {
1151
1167
  fixedExtension: entry.fixedExtension,
1152
1168
  outExtensions: entry.outExtensions
1153
1169
  });
1154
- const dtsPath = join(entry.outDir, dtsFileName);
1155
- await writeFile(dtsPath, transformed.declaration, "utf8");
1170
+ await writeFile(join(entry.outDir, dtsFileName), transformed.declaration, "utf8");
1156
1171
  }
1157
1172
  return entryDistPath;
1158
1173
  }
@@ -1166,7 +1181,7 @@ async function transformDir(ctx, entry) {
1166
1181
  }
1167
1182
  }
1168
1183
  })());
1169
- const writtenFiles = await Promise.all(promises$1);
1184
+ const writtenFiles = await Promise.all(promises);
1170
1185
  if (entry.copy) await copyFiles(ctx.pkgDir, fullOutDir, entry.copy);
1171
1186
  consola.log(`\n${colors.magenta("[transform] ")}${colors.underline(`${fmtPath(entry.outDir)}/`)}\n${writtenFiles.map((f) => colors.dim(fmtPath(f))).join("\n\n")}`);
1172
1187
  }
@@ -1176,9 +1191,8 @@ async function transformDir(ctx, entry) {
1176
1191
  async function transformModule(entryPath, entry) {
1177
1192
  let sourceText = await readFile(entryPath, "utf8");
1178
1193
  const ext = extname(entryPath);
1179
- const lang = ext === ".tsx" || ext === ".jsx" ? "tsx" : "ts";
1180
1194
  const sourceOptions = {
1181
- lang,
1195
+ lang: ext === ".tsx" || ext === ".jsx" ? "tsx" : "ts",
1182
1196
  sourceType: "module"
1183
1197
  };
1184
1198
  const parsed = parseSync(entryPath, sourceText, { ...sourceOptions });
@@ -1272,14 +1286,13 @@ var Logger = class {
1272
1286
  this.updateConsolaLevel();
1273
1287
  }
1274
1288
  updateConsolaLevel() {
1275
- const levelMap = {
1289
+ consola.level = {
1276
1290
  silent: 0,
1277
1291
  error: 1,
1278
1292
  warn: 2,
1279
1293
  info: 3,
1280
1294
  verbose: 4
1281
- };
1282
- consola.level = levelMap[this.level];
1295
+ }[this.level];
1283
1296
  }
1284
1297
  silent(message, ...args) {
1285
1298
  console.log(message, ...args);
@@ -1404,8 +1417,7 @@ async function loadViteConfig(cwd) {
1404
1417
  try {
1405
1418
  logger.verbose(`Loading Vite config from: ${configPath}`);
1406
1419
  const configModule = await import(configPath);
1407
- const viteConfig = configModule.default || configModule;
1408
- return convertViteConfig(viteConfig);
1420
+ return convertViteConfig(configModule.default || configModule);
1409
1421
  } catch (error) {
1410
1422
  logger.error(`Failed to load Vite config from ${configPath}:`, error);
1411
1423
  return {};
@@ -1468,7 +1480,7 @@ function convertFormats(formats) {
1468
1480
  */
1469
1481
  function convertTarget(target) {
1470
1482
  if (!target) return void 0;
1471
- const targetMap = {
1483
+ return {
1472
1484
  es2015: "es2015",
1473
1485
  es2016: "es2016",
1474
1486
  es2017: "es2017",
@@ -1478,8 +1490,7 @@ function convertTarget(target) {
1478
1490
  es2021: "es2021",
1479
1491
  es2022: "es2022",
1480
1492
  esnext: "esnext"
1481
- };
1482
- return targetMap[target] || void 0;
1493
+ }[target] || void 0;
1483
1494
  }
1484
1495
  /**
1485
1496
  * Convert Vite external config to robuild external
@@ -1497,8 +1508,8 @@ function normalizePath$1(path, resolveFrom) {
1497
1508
  * Perform watch build using rolldown's built-in watch mode
1498
1509
  */
1499
1510
  async function performWatchBuild(config, ctx, startTime) {
1500
- const { performBuild: performBuild$1 } = await import("./build-S2eglIZn.mjs");
1501
- await performBuild$1(config, ctx, startTime);
1511
+ const { performBuild } = await import("./build-Cm8LX2zF.mjs");
1512
+ await performBuild(config, ctx, startTime);
1502
1513
  const bundleEntries = (config.entries || []).filter((entry) => {
1503
1514
  if (typeof entry === "string") return !entry.endsWith("/");
1504
1515
  return entry.type === "bundle";
@@ -1518,7 +1529,7 @@ async function performWatchBuild(config, ctx, startTime) {
1518
1529
  */
1519
1530
  async function startRolldownWatch(config, ctx, bundleEntries) {
1520
1531
  logger.info("🚧 Using rolldown built-in watch mode...");
1521
- const { RobuildPluginManager: RobuildPluginManager$1 } = await import("./plugin-manager-WN1-NA--.mjs");
1532
+ const { RobuildPluginManager } = await import("./plugin-manager-pCQvlo7q.mjs");
1522
1533
  const watchConfigs = [];
1523
1534
  for (const rawEntry of bundleEntries) {
1524
1535
  let entry;
@@ -1566,8 +1577,11 @@ async function startRolldownWatch(config, ctx, bundleEntries) {
1566
1577
  if (Array.isArray(normalizedInput)) rolldownInput = normalizedInput[0];
1567
1578
  else if (typeof normalizedInput === "object") rolldownInput = normalizedInput;
1568
1579
  else rolldownInput = normalizedInput;
1569
- const pluginManager = new RobuildPluginManager$1(config, entry, ctx.pkgDir);
1570
- const rolldownPlugins = [...pluginManager.getRolldownPlugins(), ...entry.rolldown?.plugins || []];
1580
+ const rolldownPlugins = [...new RobuildPluginManager(config, entry, ctx.pkgDir).getRolldownPlugins(), ...entry.rolldown?.plugins || []];
1581
+ const externalConfig = resolveExternalConfig(ctx, {
1582
+ external: entry.external,
1583
+ noExternal: entry.noExternal
1584
+ });
1571
1585
  const watchConfig = {
1572
1586
  input: rolldownInput,
1573
1587
  output: {
@@ -1577,6 +1591,7 @@ async function startRolldownWatch(config, ctx, bundleEntries) {
1577
1591
  sourcemap: entry.sourcemap
1578
1592
  },
1579
1593
  platform: platform === "node" ? "node" : "neutral",
1594
+ external: externalConfig,
1580
1595
  transform: { target },
1581
1596
  plugins: rolldownPlugins
1582
1597
  };
@@ -1675,17 +1690,15 @@ async function build(config) {
1675
1690
  if (config.logLevel) configureLogger(config.logLevel);
1676
1691
  resetLogCounts();
1677
1692
  const pkgDir = normalizePath(config.cwd);
1678
- const pkg = await readJSON(join(pkgDir, "package.json")).catch(() => ({}));
1679
1693
  const ctx = {
1680
- pkg,
1694
+ pkg: await readJSON(join(pkgDir, "package.json")).catch(() => ({})),
1681
1695
  pkgDir
1682
1696
  };
1683
1697
  let finalConfig = config;
1684
1698
  if (config.fromVite) {
1685
1699
  logger.verbose("Loading configuration from Vite config file");
1686
- const viteConfig = await loadViteConfig(pkgDir);
1687
1700
  finalConfig = {
1688
- ...viteConfig,
1701
+ ...await loadViteConfig(pkgDir),
1689
1702
  ...config
1690
1703
  };
1691
1704
  }
@@ -1721,8 +1734,7 @@ async function performBuild(config, ctx, startTime) {
1721
1734
  } else entry = rawEntry;
1722
1735
  if (entry.type === "bundle") entry = inheritConfig(entry, config);
1723
1736
  else if (entry.type === "transform") entry = inheritConfig(entry, config);
1724
- const hasInput = entry.type === "transform" ? !!entry.input : !!(entry.input || entry.entry);
1725
- if (!hasInput) throw new Error(`Build entry missing \`input\` or \`entry\`: ${JSON.stringify(entry, null, 2)}`);
1737
+ if (!(entry.type === "transform" ? !!entry.input : !!(entry.input || entry.entry))) throw new Error(`Build entry missing \`input\` or \`entry\`: ${JSON.stringify(entry, null, 2)}`);
1726
1738
  entry = { ...entry };
1727
1739
  entry.outDir = normalizePath(entry.outDir || "dist", ctx.pkgDir);
1728
1740
  if (entry.type === "transform") {
@@ -1757,9 +1769,8 @@ function normalizePath(path, resolveFrom) {
1757
1769
  return typeof path === "string" && isAbsolute(path) ? path : path instanceof URL ? fileURLToPath(path) : resolve(resolveFrom || ".", path || ".");
1758
1770
  }
1759
1771
  async function readJSON(specifier) {
1760
- const module = await import(specifier, { with: { type: "json" } });
1761
- return module.default;
1772
+ return (await import(specifier, { with: { type: "json" } })).default;
1762
1773
  }
1763
1774
 
1764
1775
  //#endregion
1765
- export { SHEBANG_RE, build, hasShebang, makeExecutable, nodeProtocolPlugin, performBuild, shebangPlugin };
1776
+ export { makeExecutable as a, hasShebang as i, performBuild as n, shebangPlugin as o, SHEBANG_RE as r, nodeProtocolPlugin as s, build as t };