tsdown 0.15.4 → 0.15.6

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 { UserConfig, UserConfigFn } from "./types-CDDBvUh8.mjs";
1
+ import { UserConfig, UserConfigFn } from "./types-DMJKFE0E.mjs";
2
2
 
3
3
  //#region src/config.d.ts
4
4
 
package/dist/config.d.mts CHANGED
@@ -1,3 +1,3 @@
1
- import { UserConfig, UserConfigFn } from "./types-CDDBvUh8.mjs";
2
- import { defineConfig } from "./config-Bm-9Qi9v.mjs";
1
+ import { UserConfig, UserConfigFn } from "./types-DMJKFE0E.mjs";
2
+ import { defineConfig } from "./config-oNMlaVK7.mjs";
3
3
  export { UserConfig, UserConfigFn, defineConfig };
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { AttwOptions, BuildContext, ChunkAddon, ChunkAddonFunction, ChunkAddonObject, CopyEntry, CopyOptions, CopyOptionsFn, DtsOptions, ExportsOptions, Format, Logger, ModuleTypes, NormalizedFormat, NormalizedUserConfig, Options, OutExtensionContext, OutExtensionFactory, OutExtensionObject, PackageType, PublintOptions, ReportOptions, ResolvedOptions, RolldownContext, Sourcemap, TsdownChunks, TsdownHooks, UnusedOptions, UserConfig, UserConfigFn, Workspace, globalLogger } from "./types-CDDBvUh8.mjs";
2
- import { defineConfig } from "./config-Bm-9Qi9v.mjs";
1
+ import { AttwOptions, BuildContext, ChunkAddon, ChunkAddonFunction, ChunkAddonObject, CopyEntry, CopyOptions, CopyOptionsFn, DtsOptions, ExportsOptions, Format, Logger, NoExternalFn, NormalizedFormat, NormalizedUserConfig, Options, OutExtensionContext, OutExtensionFactory, OutExtensionObject, PackageType, PublintOptions, ReportOptions, ResolvedOptions, RolldownContext, Sourcemap, TsdownChunks, TsdownHooks, UnusedOptions, UserConfig, UserConfigFn, Workspace, globalLogger } from "./types-DMJKFE0E.mjs";
2
+ import { defineConfig } from "./config-oNMlaVK7.mjs";
3
3
 
4
4
  //#region src/index.d.ts
5
5
 
@@ -19,4 +19,4 @@ declare const shimFile: string;
19
19
  */
20
20
  declare function buildSingle(config: ResolvedOptions, clean: () => Promise<void>): Promise<(() => Promise<void>) | undefined>;
21
21
  //#endregion
22
- export { AttwOptions, BuildContext, ChunkAddon, ChunkAddonFunction, ChunkAddonObject, CopyEntry, CopyOptions, CopyOptionsFn, DtsOptions, ExportsOptions, Format, type Logger, ModuleTypes, NormalizedFormat, NormalizedUserConfig, type Options, OutExtensionContext, OutExtensionFactory, OutExtensionObject, PackageType, PublintOptions, ReportOptions, type ResolvedOptions, RolldownContext, Sourcemap, TsdownChunks, TsdownHooks, UnusedOptions, type UserConfig, type UserConfigFn, Workspace, build, buildSingle, defineConfig, globalLogger, shimFile };
22
+ export { AttwOptions, BuildContext, ChunkAddon, ChunkAddonFunction, ChunkAddonObject, CopyEntry, CopyOptions, CopyOptionsFn, DtsOptions, ExportsOptions, Format, type Logger, NoExternalFn, NormalizedFormat, NormalizedUserConfig, type Options, OutExtensionContext, OutExtensionFactory, OutExtensionObject, PackageType, PublintOptions, ReportOptions, type ResolvedOptions, RolldownContext, Sourcemap, TsdownChunks, TsdownHooks, UnusedOptions, type UserConfig, type UserConfigFn, Workspace, build, buildSingle, defineConfig, globalLogger, shimFile };
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { defineConfig } from "./config-CCGWF4al.mjs";
2
- import { build, buildSingle, shimFile } from "./src-BouWk1_F.mjs";
3
- import { globalLogger } from "./logger-C09npKHT.mjs";
2
+ import { build, buildSingle, shimFile } from "./src-Bl9Gdsdl.mjs";
3
+ import { globalLogger } from "./logger-BjPuONhe.mjs";
4
4
 
5
5
  export { build, buildSingle, defineConfig, globalLogger, shimFile };
@@ -29,6 +29,15 @@ function slash(string) {
29
29
  return string.replaceAll("\\", "/");
30
30
  }
31
31
  const noop = (v) => v;
32
+ function matchPattern(id, patterns) {
33
+ return patterns.some((pattern) => {
34
+ if (pattern instanceof RegExp) {
35
+ pattern.lastIndex = 0;
36
+ return pattern.test(id);
37
+ }
38
+ return id === pattern;
39
+ });
40
+ }
32
41
 
33
42
  //#endregion
34
43
  //#region src/utils/logger.ts
@@ -137,4 +146,4 @@ function hue2rgb(p, q, t) {
137
146
  }
138
147
 
139
148
  //#endregion
140
- export { LogLevels, createLogger, debounce, generateColor, globalLogger, noop, prettyFormat, prettyName, resolveComma, resolveRegex, slash, toArray };
149
+ export { LogLevels, createLogger, debounce, generateColor, globalLogger, matchPattern, noop, prettyFormat, prettyName, resolveComma, resolveRegex, slash, toArray };
@@ -1,5 +1,5 @@
1
- import { globalLogger } from "./logger-C09npKHT.mjs";
2
- import { version } from "./package-CtgHh8kt.mjs";
1
+ import { globalLogger } from "./logger-BjPuONhe.mjs";
2
+ import { version } from "./package-f3XEXjm-.mjs";
3
3
  import process from "node:process";
4
4
  import { bold, green, underline } from "ansis";
5
5
  import { readFile, unlink, writeFile } from "node:fs/promises";
@@ -42,7 +42,7 @@ async function migratePackageJson(dryRun) {
42
42
  globalLogger.error("No package.json found");
43
43
  return false;
44
44
  }
45
- const pkgRaw = await readFile("package.json", "utf-8");
45
+ const pkgRaw = await readFile("package.json", "utf8");
46
46
  let pkg = JSON.parse(pkgRaw);
47
47
  let found = false;
48
48
  for (const [field, semver] of Object.entries(DEP_FIELDS)) if (pkg[field]?.tsup) {
@@ -92,7 +92,7 @@ async function migrateTsupConfig(dryRun) {
92
92
  if (!existsSync(file)) continue;
93
93
  globalLogger.info(`Found \`${file}\``);
94
94
  found = true;
95
- const tsupConfigRaw = await readFile(file, "utf-8");
95
+ const tsupConfigRaw = await readFile(file, "utf8");
96
96
  const tsupConfig = tsupConfigRaw.replaceAll(/\btsup\b/g, "tsdown").replaceAll(/\bTSUP\b/g, "TSDOWN");
97
97
  const renamed = file.replaceAll("tsup", "tsdown");
98
98
  if (dryRun) {
@@ -0,0 +1,5 @@
1
+ //#region package.json
2
+ var version = "0.15.6";
3
+
4
+ //#endregion
5
+ export { version };
@@ -1,9 +1,14 @@
1
- import { Logger, ReportPlugin, ResolvedOptions } from "./types-CDDBvUh8.mjs";
1
+ import { Logger, ReportPlugin, ResolvedOptions } from "./types-DMJKFE0E.mjs";
2
2
  import { Plugin } from "rolldown";
3
3
  import { PackageJson } from "pkg-types";
4
4
 
5
5
  //#region src/features/external.d.ts
6
- declare function ExternalPlugin(options: ResolvedOptions): Plugin;
6
+ declare function ExternalPlugin({
7
+ pkg,
8
+ noExternal,
9
+ inlineOnly,
10
+ skipNodeModulesBundle
11
+ }: ResolvedOptions): Plugin;
7
12
  //#endregion
8
13
  //#region src/features/shebang.d.ts
9
14
  declare function ShebangPlugin(logger: Logger, cwd: string, name?: string, isMultiFormat?: boolean): Plugin;
package/dist/plugins.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import "./config-CCGWF4al.mjs";
2
- import { ExternalPlugin, NodeProtocolPlugin, ReportPlugin, ShebangPlugin } from "./src-BouWk1_F.mjs";
3
- import "./logger-C09npKHT.mjs";
2
+ import { ExternalPlugin, NodeProtocolPlugin, ReportPlugin, ShebangPlugin } from "./src-Bl9Gdsdl.mjs";
3
+ import "./logger-BjPuONhe.mjs";
4
4
 
5
5
  export { ExternalPlugin, NodeProtocolPlugin, ReportPlugin, ShebangPlugin };
package/dist/run.mjs CHANGED
@@ -1,11 +1,13 @@
1
1
  #!/usr/bin/env node
2
- import { globalLogger, resolveComma, toArray } from "./logger-C09npKHT.mjs";
3
- import { version } from "./package-CtgHh8kt.mjs";
2
+ import { createRequire as __cjs_createRequire } from "node:module";
3
+ const __cjs_require = __cjs_createRequire(import.meta.url);
4
+ import { globalLogger, resolveComma, toArray } from "./logger-BjPuONhe.mjs";
5
+ import { version } from "./package-f3XEXjm-.mjs";
4
6
  import module from "node:module";
5
7
  import process from "node:process";
6
8
  import { dim } from "ansis";
7
9
  import { VERSION } from "rolldown";
8
- import Debug from "debug";
10
+ const Debug = __cjs_require("debug");
9
11
  import { cac } from "cac";
10
12
 
11
13
  //#region src/cli.ts
@@ -15,14 +17,14 @@ cli.command("[...files]", "Bundle files", {
15
17
  ignoreOptionDefaultValue: true,
16
18
  allowUnknownOptions: true
17
19
  }).option("-c, --config <filename>", "Use a custom config file").option("--config-loader <loader>", "Config loader to use: auto, native, unconfig", { default: "auto" }).option("--no-config", "Disable config file").option("-f, --format <format>", "Bundle format: esm, cjs, iife, umd", { default: "esm" }).option("--clean", "Clean output directory, --no-clean to disable").option("--external <module>", "Mark dependencies as external").option("--minify", "Minify output").option("--debug [feat]", "Show debug logs").option("--target <target>", "Bundle target, e.g \"es2015\", \"esnext\"").option("-l, --logLevel <level>", "Set log level: info, warn, error, silent").option("--fail-on-warn", "Fail on warnings", { default: true }).option("-d, --out-dir <dir>", "Output directory", { default: "dist" }).option("--treeshake", "Tree-shake bundle", { default: true }).option("--sourcemap", "Generate source map", { default: false }).option("--shims", "Enable cjs and esm shims ", { default: false }).option("--platform <platform>", "Target platform", { default: "node" }).option("--dts", "Generate dts files").option("--publint", "Enable publint", { default: false }).option("--attw", "Enable Are the types wrong integration", { default: false }).option("--unused", "Enable unused dependencies check", { default: false }).option("-w, --watch [path]", "Watch mode").option("--ignore-watch <path>", "Ignore custom paths in watch mode").option("--from-vite [vitest]", "Reuse config from Vite or Vitest").option("--report", "Size report", { default: true }).option("--env.* <value>", "Define compile-time env variables").option("--on-success <command>", "Command to run on success").option("--copy <dir>", "Copy files to output dir").option("--public-dir <dir>", "Alias for --copy, deprecated").option("--tsconfig <tsconfig>", "Set tsconfig path").option("--unbundle", "Unbundle mode").option("-W, --workspace [dir]", "Enable workspace mode").option("-F, --filter <pattern>", "Filter workspace packages, e.g. /regex/ or substring").option("--exports", "Generate export-related metadata for package.json (experimental)").action(async (input, flags) => {
18
- globalLogger.level = flags.logLevel || (flags.silent ? "silent" : "info");
20
+ globalLogger.level = flags.logLevel || (flags.silent ? "error" : "info");
19
21
  globalLogger.info(`tsdown ${dim`v${version}`} powered by rolldown ${dim`v${VERSION}`}`);
20
22
  const { build: build$1 } = await import("./index.mjs");
21
23
  if (input.length > 0) flags.entry = input;
22
24
  await build$1(flags);
23
25
  });
24
26
  cli.command("migrate", "Migrate from tsup to tsdown").option("-c, --cwd <dir>", "Working directory").option("-d, --dry-run", "Dry run").action(async (args) => {
25
- const { migrate } = await import("./migrate-BsOBsX36.mjs");
27
+ const { migrate } = await import("./migrate-CeG6I3xh.mjs");
26
28
  await migrate(args);
27
29
  });
28
30
  async function runCLI() {
@@ -1,4 +1,6 @@
1
- import { LogLevels, createLogger, debounce, generateColor, globalLogger, noop, prettyFormat, prettyName, resolveComma, resolveRegex, slash, toArray } from "./logger-C09npKHT.mjs";
1
+ import { createRequire as __cjs_createRequire } from "node:module";
2
+ const __cjs_require = __cjs_createRequire(import.meta.url);
3
+ import { LogLevels, createLogger, debounce, generateColor, globalLogger, matchPattern, noop, prettyFormat, prettyName, resolveComma, resolveRegex, slash, toArray } from "./logger-BjPuONhe.mjs";
2
4
  import { builtinModules } from "node:module";
3
5
  import path, { dirname, normalize, sep } from "node:path";
4
6
  import process from "node:process";
@@ -6,19 +8,19 @@ import { fileURLToPath, pathToFileURL } from "node:url";
6
8
  import { blue, bold, dim, green, underline } from "ansis";
7
9
  import { build } from "rolldown";
8
10
  import { exec } from "tinyexec";
9
- import treeKill from "tree-kill";
11
+ const treeKill = __cjs_require("tree-kill");
10
12
  import child_process from "node:child_process";
11
13
  import { access, chmod, cp, mkdtemp, readFile, rm, stat, writeFile } from "node:fs/promises";
12
14
  import { tmpdir } from "node:os";
13
15
  import { promisify } from "node:util";
14
- import Debug from "debug";
15
- import coerce from "semver/functions/coerce.js";
16
- import satisfies from "semver/functions/satisfies.js";
16
+ const Debug = __cjs_require("debug");
17
+ const coerce = __cjs_require("semver/functions/coerce.js");
18
+ const satisfies = __cjs_require("semver/functions/satisfies.js");
17
19
  import { glob } from "tinyglobby";
18
- import { RE_CSS, RE_DTS, RE_JS } from "rolldown-plugin-dts/filename";
20
+ import { RE_CSS, RE_DTS, RE_JS, RE_NODE_MODULES } from "rolldown-plugin-dts/filename";
19
21
  import { createHooks } from "hookable";
20
22
  import { importGlobPlugin } from "rolldown/experimental";
21
- import minVersion from "semver/ranges/min-version.js";
23
+ const minVersion = __cjs_require("semver/ranges/min-version.js");
22
24
  import { up } from "empathic/find";
23
25
  import { up as up$1 } from "empathic/package";
24
26
  import { loadConfig } from "unconfig";
@@ -270,11 +272,11 @@ async function generateExports(pkg, outDir, chunks, { devExports, all, customExp
270
272
  }
271
273
  }
272
274
  }
273
- const sorttedExportsMap = Array.from(exportsMap.entries()).sort(([a], [b]) => {
275
+ const sortedExportsMap = Array.from(exportsMap.entries()).toSorted(([a], [b]) => {
274
276
  if (a === "index") return -1;
275
277
  return a.localeCompare(b);
276
278
  });
277
- let exports = Object.fromEntries(sorttedExportsMap.map(([name, subExport]) => [name, genSubExport(devExports, subExport)]));
279
+ let exports = Object.fromEntries(sortedExportsMap.map(([name, subExport]) => [name, genSubExport(devExports, subExport)]));
278
280
  exportMeta(exports, all);
279
281
  if (customExports) exports = await customExports(exports, {
280
282
  pkg,
@@ -284,7 +286,7 @@ async function generateExports(pkg, outDir, chunks, { devExports, all, customExp
284
286
  });
285
287
  let publishExports;
286
288
  if (devExports) {
287
- publishExports = Object.fromEntries(sorttedExportsMap.map(([name, subExport]) => [name, genSubExport(false, subExport)]));
289
+ publishExports = Object.fromEntries(sortedExportsMap.map(([name, subExport]) => [name, genSubExport(false, subExport)]));
288
290
  exportMeta(publishExports, all);
289
291
  if (customExports) publishExports = await customExports(publishExports, {
290
292
  pkg,
@@ -674,7 +676,7 @@ async function resolveWorkspace(config, options) {
674
676
  };
675
677
  }
676
678
  async function resolveConfig(userConfig) {
677
- let { entry, format = ["es"], plugins = [], clean = true, silent = false, logLevel = silent ? "silent" : "info", failOnWarn = false, customLogger, treeshake = true, platform = "node", outDir = "dist", sourcemap = false, dts, unused = false, watch = false, ignoreWatch = [], shims = false, skipNodeModulesBundle = false, publint: publint$1 = false, attw: attw$1 = false, fromVite, alias, tsconfig, report = true, target, env = {}, copy: copy$1, publicDir, hash, cwd = process.cwd(), name, workspace, external, noExternal, exports = false, bundle, unbundle = typeof bundle === "boolean" ? !bundle : false, removeNodeProtocol, nodeProtocol, cjsDefault = true, globImport = true } = userConfig;
679
+ let { entry, format = ["es"], plugins = [], clean = true, silent = false, logLevel = silent ? "silent" : "info", failOnWarn = false, customLogger, treeshake = true, platform = "node", outDir = "dist", sourcemap = false, dts, unused = false, watch = false, ignoreWatch, shims = false, skipNodeModulesBundle = false, publint: publint$1 = false, attw: attw$1 = false, fromVite, alias, tsconfig, report = true, target, env = {}, copy: copy$1, publicDir, hash, cwd = process.cwd(), name, workspace, external, noExternal, exports = false, bundle, unbundle = typeof bundle === "boolean" ? !bundle : false, removeNodeProtocol, nodeProtocol, cjsDefault = true, globImport = true, inlineOnly } = userConfig;
678
680
  const logger = createLogger(logLevel, {
679
681
  customLogger,
680
682
  failOnWarn
@@ -714,6 +716,11 @@ async function resolveConfig(userConfig) {
714
716
  if (typeof ignore === "string") return path.resolve(cwd, ignore);
715
717
  return ignore;
716
718
  });
719
+ if (noExternal != null && typeof noExternal !== "function") {
720
+ const noExternalPatterns = toArray(noExternal);
721
+ noExternal = (id) => matchPattern(id, noExternalPatterns);
722
+ }
723
+ if (inlineOnly != null) inlineOnly = toArray(inlineOnly);
717
724
  return {
718
725
  ...userConfig,
719
726
  entry,
@@ -749,7 +756,8 @@ async function resolveConfig(userConfig) {
749
756
  unbundle,
750
757
  nodeProtocol,
751
758
  cjsDefault,
752
- globImport
759
+ globImport,
760
+ inlineOnly
753
761
  };
754
762
  }
755
763
  async function mergeUserOptions(defaults, user, args) {
@@ -763,41 +771,49 @@ async function mergeUserOptions(defaults, user, args) {
763
771
  //#endregion
764
772
  //#region src/features/external.ts
765
773
  const debug$2 = Debug("tsdown:external");
766
- function ExternalPlugin(options) {
767
- const deps = options.pkg && Array.from(getProductionDeps(options.pkg));
774
+ function ExternalPlugin({ pkg, noExternal, inlineOnly, skipNodeModulesBundle }) {
775
+ const deps = pkg && Array.from(getProductionDeps(pkg));
768
776
  return {
769
777
  name: "tsdown:external",
770
778
  async resolveId(id, importer, extraOptions) {
771
- if (extraOptions.isEntry) return;
772
- if (id === shimFile) return;
773
- const { noExternal } = options;
774
- if (typeof noExternal === "function" && noExternal(id, importer)) return;
775
- if (noExternal) {
776
- if (toArray(noExternal).some((pattern) => {
777
- if (pattern instanceof RegExp) {
778
- pattern.lastIndex = 0;
779
- return pattern.test(id);
780
- }
781
- return id === pattern;
782
- })) return;
783
- }
784
- let shouldExternal = false;
785
- if (options.skipNodeModulesBundle) {
779
+ if (extraOptions.isEntry || !importer) return;
780
+ const shouldExternal = await externalStrategy(this, id, importer, extraOptions);
781
+ const nodeBuiltinModule = id.startsWith("node:") || builtinModules.includes(id);
782
+ debug$2("shouldExternal: %s = %s", id, shouldExternal);
783
+ if (shouldExternal === true || shouldExternal === "absolute") return {
784
+ id,
785
+ external: shouldExternal,
786
+ moduleSideEffects: nodeBuiltinModule ? false : void 0
787
+ };
788
+ if (inlineOnly && !RE_DTS.test(importer) && !nodeBuiltinModule && id[0] !== "." && !path.isAbsolute(id)) {
789
+ const shouldInline = shouldExternal === "no-external" || matchPattern(id, inlineOnly);
790
+ debug$2("shouldInline: %s = %s", id, shouldInline);
791
+ if (shouldInline) return;
786
792
  const resolved = await this.resolve(id, importer, extraOptions);
787
- if (!resolved) return resolved;
788
- shouldExternal = resolved.external || /[\\/]node_modules[\\/]/.test(resolved.id);
789
- }
790
- if (deps) shouldExternal ||= deps.some((dep) => id === dep || id.startsWith(`${dep}/`));
791
- if (shouldExternal) {
792
- debug$2("External dependency:", id);
793
- return {
794
- id,
795
- external: shouldExternal,
796
- moduleSideEffects: id.startsWith("node:") || builtinModules.includes(id) ? false : void 0
797
- };
793
+ if (!resolved) return;
794
+ if (RE_NODE_MODULES.test(resolved.id)) throw new Error(`${underline(id)} is located in node_modules but is not included in ${blue`inlineOnly`} option.
795
+ To fix this, either add it to ${blue`inlineOnly`}, declare it as a production or peer dependency in your package.json, or externalize it manually.
796
+ Imported by ${underline(importer)}`);
798
797
  }
799
798
  }
800
799
  };
800
+ /**
801
+ * - `true`: always external
802
+ * - `false`: skip, let other plugins handle it
803
+ * - `'absolute'`: external as absolute path
804
+ * - `'no-external'`: skip, but mark as non-external for inlineOnly check
805
+ */
806
+ async function externalStrategy(context, id, importer, extraOptions) {
807
+ if (id === shimFile) return false;
808
+ if (noExternal?.(id, importer)) return "no-external";
809
+ if (skipNodeModulesBundle) {
810
+ const resolved = await context.resolve(id, importer, extraOptions);
811
+ if (!resolved) return false;
812
+ return resolved.external || RE_NODE_MODULES.test(resolved.id);
813
+ }
814
+ if (deps) return deps.some((dep) => id === dep || id.startsWith(`${dep}/`));
815
+ return false;
816
+ }
801
817
  }
802
818
  function getProductionDeps(pkg) {
803
819
  return new Set([...Object.keys(pkg.dependencies || {}), ...Object.keys(pkg.peerDependencies || {})]);
@@ -953,7 +969,16 @@ function formatBytes(bytes) {
953
969
  const debug$1 = Debug("tsdown:report");
954
970
  const brotliCompressAsync = promisify(brotliCompress);
955
971
  const gzipAsync = promisify(gzip);
956
- function ReportPlugin(options, logger, cwd, cjsDts, name, isMultiFormat) {
972
+ const defaultOptions = {
973
+ gzip: true,
974
+ brotli: false,
975
+ maxCompressSize: 1e6
976
+ };
977
+ function ReportPlugin(userOptions, logger, cwd, cjsDts, name, isMultiFormat) {
978
+ const options = {
979
+ ...defaultOptions,
980
+ ...userOptions
981
+ };
957
982
  return {
958
983
  name: "tsdown:report",
959
984
  async writeBundle(outputOptions, bundle) {
@@ -983,7 +1008,7 @@ function ReportPlugin(options, logger, cwd, cjsDts, name, isMultiFormat) {
983
1008
  const formatLabel = isMultiFormat && prettyFormat(cjsDts ? "cjs" : outputOptions.format);
984
1009
  for (const size of sizes) {
985
1010
  const filenameColor = size.dts ? green : noop;
986
- logger.info(nameLabel, formatLabel, dim(outDir + path.sep) + filenameColor((size.isEntry ? bold : noop)(size.filename)), ` `.repeat(filenameLength - size.filename.length), dim(size.rawText), size.gzipText && dim`│ gzip: ${size.gzipText}`, options.brotli && size.brotliText && dim`│ brotli: ${size.brotliText}`);
1011
+ logger.info(nameLabel, formatLabel, dim(outDir + path.sep) + filenameColor((size.isEntry ? bold : noop)(size.filename)), ` `.repeat(filenameLength - size.filename.length), dim(size.rawText), options.gzip && size.gzipText && dim`│ gzip: ${size.gzipText}`, options.brotli && size.brotliText && dim`│ brotli: ${size.brotliText}`);
987
1012
  }
988
1013
  const totalSizeText = formatBytes(totalRaw);
989
1014
  logger.info(nameLabel, formatLabel, `${sizes.length} files, total: ${totalSizeText}`);
@@ -997,10 +1022,12 @@ async function calcSize(options, chunk) {
997
1022
  debug$1("[size]", chunk.fileName, raw);
998
1023
  let gzip$1 = Infinity;
999
1024
  let brotli = Infinity;
1000
- if (raw > (options.maxCompressSize ?? 1e6)) debug$1(chunk.fileName, "file size exceeds limit, skip gzip/brotli");
1025
+ if (raw > options.maxCompressSize) debug$1(chunk.fileName, "file size exceeds limit, skip gzip/brotli");
1001
1026
  else {
1002
- gzip$1 = (await gzipAsync(content)).length;
1003
- debug$1("[gzip]", chunk.fileName, gzip$1);
1027
+ if (options.gzip) {
1028
+ gzip$1 = (await gzipAsync(content)).length;
1029
+ debug$1("[gzip]", chunk.fileName, gzip$1);
1030
+ }
1004
1031
  if (options.brotli) {
1005
1032
  brotli = (await brotliCompressAsync(content)).length;
1006
1033
  debug$1("[brotli]", chunk.fileName, brotli);
@@ -1113,11 +1140,11 @@ async function resolveInputOptions(config, format, cjsDts, isMultiFormat) {
1113
1140
  plugins,
1114
1141
  inject: { ...shims && !cjsDts && getShimsInject(format, platform) },
1115
1142
  moduleTypes: loader,
1143
+ logLevel: logger.level === "error" ? "silent" : logger.level,
1116
1144
  onLog: cjsDefault ? (level, log, defaultHandler) => {
1117
1145
  if (log.code === "MIXED_EXPORT") return;
1118
1146
  defaultHandler(level, log);
1119
- } : void 0,
1120
- experimental: { resolveNewUrlToAsset: true }
1147
+ } : void 0
1121
1148
  }, config.inputOptions, [format, { cjsDts }]);
1122
1149
  }
1123
1150
  async function resolveOutputOptions(inputOptions, config, format, cjsDts) {
@@ -1192,35 +1219,46 @@ function shortcuts(restart) {
1192
1219
 
1193
1220
  //#endregion
1194
1221
  //#region src/features/watch.ts
1195
- const endsWithConfig = /[\\/](?:package\.json|tsdown\.config.*)$/;
1222
+ const endsWithConfig = /[\\/](?:(?:package|tsconfig)\.json|pnpm-(?:workspace|lock)\.yaml|tsdown\.config.*)$/;
1196
1223
  async function watchBuild(options, configFiles, rebuild, restart) {
1197
1224
  if (typeof options.watch === "boolean" && options.outDir === options.cwd) throw new Error(`Watch is enabled, but output directory is the same as the current working directory.Please specify a different watch directory using ${blue`watch`} option,or set ${blue`outDir`} to a different directory.`);
1198
1225
  const files = toArray(typeof options.watch === "boolean" ? options.cwd : options.watch);
1199
1226
  options.logger.info(`Watching for changes in ${files.join(", ")}`);
1200
1227
  files.push(...configFiles);
1201
1228
  const { watch } = await import("chokidar");
1202
- const debouncedRebuild = debounce(rebuild, 100);
1229
+ const debouncedOnChange = debounce(onChange, 100);
1203
1230
  const watcher = watch(files, {
1231
+ cwd: options.cwd,
1204
1232
  ignoreInitial: true,
1205
1233
  ignorePermissionErrors: true,
1206
1234
  ignored: [
1207
1235
  /[\\/]\.git[\\/]/,
1208
- /[\\/]node_modules[\\/]/,
1236
+ RE_NODE_MODULES,
1209
1237
  options.outDir,
1210
1238
  ...options.ignoreWatch
1211
1239
  ]
1212
1240
  });
1241
+ let pending = [];
1242
+ let pendingPromise;
1213
1243
  watcher.on("all", (type, file) => {
1214
- if (configFiles.includes(file) || endsWithConfig.test(file)) {
1215
- options.logger.info(`Reload config: ${file}`);
1216
- restart();
1217
- return;
1218
- }
1219
- options.logger.info(`Change detected: ${type} ${file}`);
1220
- invalidateContextFile(globalContext, file);
1221
- debouncedRebuild();
1244
+ pending.push(path.resolve(options.cwd, file));
1245
+ debouncedOnChange();
1222
1246
  });
1223
1247
  return watcher;
1248
+ async function onChange() {
1249
+ await pendingPromise;
1250
+ if (!pending.length) return;
1251
+ for (const file of pending) invalidateContextFile(globalContext, file);
1252
+ if (pending.some((file) => configFiles.includes(file) || endsWithConfig.test(file))) {
1253
+ options.logger.info(`Restarting due to config change...`);
1254
+ pendingPromise = restart();
1255
+ } else {
1256
+ options.logger.info(`Change detected: ${pending.join(", ")}`);
1257
+ pendingPromise = rebuild();
1258
+ }
1259
+ pending = [];
1260
+ await pendingPromise;
1261
+ }
1224
1262
  }
1225
1263
 
1226
1264
  //#endregion
@@ -1229,7 +1267,7 @@ async function watchBuild(options, configFiles, rebuild, restart) {
1229
1267
  * Build with tsdown.
1230
1268
  */
1231
1269
  async function build$1(userOptions = {}) {
1232
- globalLogger.level = userOptions.logLevel || (userOptions.silent ? "silent" : "info");
1270
+ globalLogger.level = userOptions.logLevel || (userOptions.silent ? "error" : "info");
1233
1271
  const { configs, files: configFiles } = await resolveOptions(userOptions);
1234
1272
  let cleanPromise;
1235
1273
  const clean = () => {
@@ -1,5 +1,5 @@
1
1
  import "ansis";
2
- import { BuildOptions, ExternalOption, InputOption, InputOptions, InternalModuleFormat, MinifyOptions, ModuleFormat, OutputAsset, OutputChunk, OutputOptions, Plugin } from "rolldown";
2
+ import { BuildOptions, ExternalOption, InputOption, InputOptions, InternalModuleFormat, MinifyOptions, ModuleFormat, ModuleTypes, OutputAsset, OutputChunk, OutputOptions, Plugin } from "rolldown";
3
3
  import { Hookable } from "hookable";
4
4
  import { CheckPackageOptions } from "@arethetypeswrong/core";
5
5
  import { Options as PublintOptions } from "publint";
@@ -139,6 +139,13 @@ declare const globalLogger: Logger;
139
139
  //#endregion
140
140
  //#region src/features/report.d.ts
141
141
  interface ReportOptions {
142
+ /**
143
+ * Enable/disable gzip-compressed size reporting.
144
+ * Compressing large output files can be slow, so disabling this may increase build performance for large projects.
145
+ *
146
+ * @default true
147
+ */
148
+ gzip?: boolean;
142
149
  /**
143
150
  * Enable/disable brotli-compressed size reporting.
144
151
  * Compressing large output files can be slow, so disabling this may increase build performance for large projects.
@@ -152,13 +159,12 @@ interface ReportOptions {
152
159
  */
153
160
  maxCompressSize?: number;
154
161
  }
155
- declare function ReportPlugin(options: ReportOptions, logger: Logger, cwd: string, cjsDts?: boolean, name?: string, isMultiFormat?: boolean): Plugin;
162
+ declare function ReportPlugin(userOptions: ReportOptions, logger: Logger, cwd: string, cjsDts?: boolean, name?: string, isMultiFormat?: boolean): Plugin;
156
163
  //#endregion
157
164
  //#region src/options/types.d.ts
158
165
  type Sourcemap = boolean | "inline" | "hidden";
159
166
  type Format = ModuleFormat;
160
167
  type NormalizedFormat = InternalModuleFormat;
161
- type ModuleTypes = Record<string, "js" | "jsx" | "ts" | "tsx" | "json" | "text" | "base64" | "dataurl" | "binary" | "empty" | "css" | "asset">;
162
168
  interface Workspace {
163
169
  /**
164
170
  * Workspace directories. Glob patterns are supported.
@@ -176,6 +182,7 @@ interface Workspace {
176
182
  */
177
183
  config?: boolean | string;
178
184
  }
185
+ type NoExternalFn = (id: string, importer: string | undefined) => boolean | null | undefined | void;
179
186
  /**
180
187
  * Options for tsdown.
181
188
  */
@@ -185,7 +192,13 @@ interface Options {
185
192
  */
186
193
  entry?: InputOption;
187
194
  external?: ExternalOption;
188
- noExternal?: Arrayable<string | RegExp> | ((id: string, importer: string | undefined) => boolean | null | undefined | void);
195
+ noExternal?: Arrayable<string | RegExp> | NoExternalFn;
196
+ /**
197
+ * Bundle only the dependencies listed here; throw an error if any others are missing.
198
+ *
199
+ * Note: Be sure to include all required sub-dependencies as well.
200
+ */
201
+ inlineOnly?: Arrayable<string | RegExp>;
189
202
  /**
190
203
  * Skip bundling `node_modules`.
191
204
  * @default false
@@ -488,7 +501,7 @@ interface Options {
488
501
  type UserConfig = Arrayable<Omit<Options, "config" | "filter" | "configLoader">>;
489
502
  type UserConfigFn = (cliOptions: Options) => Awaitable<UserConfig>;
490
503
  type NormalizedUserConfig = Exclude<UserConfig, any[]>;
491
- type ResolvedOptions = Omit<Overwrite<MarkPartial<Omit<Options, "publicDir" | "workspace" | "filter" | "silent" | "logLevel" | "failOnWarn" | "customLogger" | "configLoader">, "globalName" | "inputOptions" | "outputOptions" | "minify" | "define" | "alias" | "external" | "noExternal" | "onSuccess" | "fixedExtension" | "outExtensions" | "hooks" | "removeNodeProtocol" | "copy" | "loader" | "name" | "bundle" | "banner" | "footer">, {
504
+ type ResolvedOptions = Omit<Overwrite<MarkPartial<Omit<Options, "publicDir" | "workspace" | "filter" | "silent" | "logLevel" | "failOnWarn" | "customLogger" | "configLoader">, "globalName" | "inputOptions" | "outputOptions" | "minify" | "define" | "alias" | "external" | "onSuccess" | "fixedExtension" | "outExtensions" | "hooks" | "removeNodeProtocol" | "copy" | "loader" | "name" | "bundle" | "banner" | "footer">, {
492
505
  format: NormalizedFormat[];
493
506
  target?: string[];
494
507
  clean: string[];
@@ -500,6 +513,8 @@ type ResolvedOptions = Omit<Overwrite<MarkPartial<Omit<Options, "publicDir" | "w
500
513
  nodeProtocol: "strip" | boolean;
501
514
  logger: Logger;
502
515
  ignoreWatch: Array<string | RegExp>;
516
+ noExternal?: NoExternalFn;
517
+ inlineOnly?: Array<string | RegExp>;
503
518
  }>, "config" | "fromVite">;
504
519
  //#endregion
505
- export { type AttwOptions, type BuildContext, type ChunkAddon, type ChunkAddonFunction, type ChunkAddonObject, type CopyEntry, type CopyOptions, type CopyOptionsFn, type DtsOptions, type ExportsOptions, Format, Logger, ModuleTypes, NormalizedFormat, NormalizedUserConfig, Options, type OutExtensionContext, type OutExtensionFactory, type OutExtensionObject, type PackageType, type PublintOptions, type ReportOptions, ReportPlugin, ResolvedOptions, type RolldownContext, Sourcemap, type TsdownChunks, type TsdownHooks, type UnusedOptions, UserConfig, UserConfigFn, Workspace, globalLogger };
520
+ export { type AttwOptions, type BuildContext, type ChunkAddon, type ChunkAddonFunction, type ChunkAddonObject, type CopyEntry, type CopyOptions, type CopyOptionsFn, type DtsOptions, type ExportsOptions, Format, Logger, NoExternalFn, NormalizedFormat, NormalizedUserConfig, Options, type OutExtensionContext, type OutExtensionFactory, type OutExtensionObject, type PackageType, type PublintOptions, type ReportOptions, ReportPlugin, ResolvedOptions, type RolldownContext, Sourcemap, type TsdownChunks, type TsdownHooks, type UnusedOptions, UserConfig, UserConfigFn, Workspace, globalLogger };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tsdown",
3
- "version": "0.15.4",
3
+ "version": "0.15.6",
4
4
  "description": "The Elegant Bundler for Libraries",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -77,7 +77,7 @@
77
77
  "empathic": "^2.0.0",
78
78
  "hookable": "^5.5.3",
79
79
  "rolldown": "latest",
80
- "rolldown-plugin-dts": "^0.16.7",
80
+ "rolldown-plugin-dts": "^0.16.8",
81
81
  "semver": "^7.7.2",
82
82
  "tinyexec": "^1.0.1",
83
83
  "tinyglobby": "^0.2.15",
@@ -86,23 +86,24 @@
86
86
  },
87
87
  "devDependencies": {
88
88
  "@arethetypeswrong/core": "^0.18.2",
89
- "@sxzz/eslint-config": "^7.1.4",
89
+ "@sxzz/eslint-config": "^7.2.5",
90
90
  "@sxzz/prettier-config": "^2.2.4",
91
91
  "@sxzz/test-utils": "^0.5.11",
92
92
  "@types/debug": "^4.1.12",
93
- "@types/node": "^24.5.0",
93
+ "@types/node": "^24.5.2",
94
94
  "@types/semver": "^7.7.1",
95
- "@unocss/eslint-plugin": "^66.5.1",
95
+ "@unocss/eslint-plugin": "^66.5.2",
96
96
  "@vueuse/core": "^13.9.0",
97
97
  "bumpp": "^10.2.3",
98
- "eslint": "^9.35.0",
98
+ "eslint": "^9.36.0",
99
99
  "lightningcss": "^1.30.1",
100
100
  "pkg-types": "^2.3.0",
101
101
  "prettier": "^3.6.2",
102
- "publint": "^0.3.12",
103
- "tsx": "^4.20.5",
102
+ "publint": "^0.3.13",
103
+ "rolldown-plugin-require-cjs": "^0.3.0",
104
+ "tsx": "^4.20.6",
104
105
  "typescript": "~5.9.2",
105
- "unocss": "^66.5.1",
106
+ "unocss": "^66.5.2",
106
107
  "unplugin-lightningcss": "^0.4.3",
107
108
  "unplugin-unused": "^0.5.3",
108
109
  "vite": "npm:rolldown-vite@latest",
@@ -1,5 +0,0 @@
1
- //#region package.json
2
- var version = "0.15.4";
3
-
4
- //#endregion
5
- export { version };