tsdown 0.8.0 → 0.9.0

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
@@ -1,6 +1,8 @@
1
- # tsdown [![npm](https://img.shields.io/npm/v/tsdown.svg)](https://npmjs.com/package/tsdown) [![Unit Test](https://github.com/rolldown/tsdown/actions/workflows/unit-test.yml/badge.svg)](https://github.com/rolldown/tsdown/actions/workflows/unit-test.yml) [![JSR](https://jsr.io/badges/@sxzz/tsdown)](https://jsr.io/@sxzz/tsdown)
1
+ <img src="./assets/header-illustration.svg" alt="tsdown" width="100%" /><br>
2
2
 
3
- ⚡️ An even faster bundler powered by [Rolldown](https://github.com/rolldown/rolldown).
3
+ # tsdown [![npm](https://img.shields.io/npm/v/tsdown.svg)](https://npmjs.com/package/tsdown) [![Unit Test](https://github.com/rolldown/tsdown/actions/workflows/tests.yml/badge.svg)](https://github.com/rolldown/tsdown/actions/workflows/tests.yml) [![JSR](https://jsr.io/badges/@sxzz/tsdown)](https://jsr.io/@sxzz/tsdown)
4
+
5
+ ⚡️ Smooth and fast library bundler powered by Rolldown [Rolldown](https://github.com/rolldown/rolldown).
4
6
 
5
7
  ## Features
6
8
 
@@ -29,7 +31,7 @@ export default defineConfig({
29
31
 
30
32
  ## Usage
31
33
 
32
- ```ts
34
+ ```bash
33
35
  npx tsdown
34
36
  ```
35
37
 
@@ -1,4 +1,4 @@
1
- import { UserConfig } from "./options.d-C08fnFhO.js";
1
+ import { UserConfig } from "./options.d-BUmkLb5_.js";
2
2
 
3
3
  //#region src/config.d.ts
4
4
  /**
package/dist/config.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import "./options.d-C08fnFhO.js";
2
- import { defineConfig$1 as defineConfig } from "./config.d-DBmaLxob.js";
1
+ import "./options.d-BUmkLb5_.js";
2
+ import { defineConfig$1 as defineConfig } from "./config.d-CIuApN_q.js";
3
3
 
4
4
  export { defineConfig };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { Options, ResolvedOptions, UserConfig } from "./options.d-C08fnFhO.js";
2
- import { defineConfig$1 as defineConfig } from "./config.d-DBmaLxob.js";
1
+ import { Options, ResolvedOptions, UserConfig } from "./options.d-BUmkLb5_.js";
2
+ import { defineConfig$1 as defineConfig } from "./config.d-CIuApN_q.js";
3
3
  import Debug from "debug";
4
4
  import { ConsolaInstance } from "consola";
5
5
 
package/dist/index.js CHANGED
@@ -92,14 +92,35 @@ function normalizeFormat(format) {
92
92
 
93
93
  //#endregion
94
94
  //#region src/features/output.ts
95
- function resolveOutputExtension(pkg, format, fixedExtension) {
96
- const moduleType = getPackageType(pkg);
95
+ function resolveOutputExtension(packageType, format, fixedExtension) {
97
96
  switch (format) {
98
- case "es": return !fixedExtension && moduleType === "module" ? "js" : "mjs";
99
- case "cjs": return fixedExtension || moduleType === "module" ? "cjs" : "js";
97
+ case "es": return !fixedExtension && packageType === "module" ? "js" : "mjs";
98
+ case "cjs": return fixedExtension || packageType === "module" ? "cjs" : "js";
100
99
  default: return "js";
101
100
  }
102
101
  }
102
+ function resolveChunkFilename(pkg, inputOptions, format, { outExtensions, fixedExtension }) {
103
+ const packageType = getPackageType(pkg);
104
+ let jsExtension;
105
+ let dtsExtension;
106
+ if (outExtensions) {
107
+ const { js, dts } = outExtensions({
108
+ options: inputOptions,
109
+ format,
110
+ pkgType: packageType
111
+ });
112
+ jsExtension = js;
113
+ dtsExtension = dts;
114
+ }
115
+ jsExtension ||= `.${resolveOutputExtension(packageType, format, fixedExtension)}`;
116
+ return [createChunkFilename("[name]", jsExtension, dtsExtension), createChunkFilename(`[name]-[hash]`, jsExtension, dtsExtension)];
117
+ }
118
+ function createChunkFilename(basename, jsExtension, dtsExtension) {
119
+ if (!dtsExtension) return `${basename}${jsExtension}`;
120
+ return (chunk) => {
121
+ return `${basename}${chunk.name.endsWith(".d") ? dtsExtension : jsExtension}`;
122
+ };
123
+ }
103
124
 
104
125
  //#endregion
105
126
  //#region src/features/publint.ts
@@ -242,6 +263,12 @@ async function toObjectEntry(entry) {
242
263
  }));
243
264
  }
244
265
 
266
+ //#endregion
267
+ //#region src/utils/tsconfig.ts
268
+ async function findTsconfig(cwd, name = "tsconfig.json") {
269
+ return await findUp(name, { cwd }) || false;
270
+ }
271
+
245
272
  //#endregion
246
273
  //#region src/options.ts
247
274
  async function resolveOptions(options) {
@@ -252,10 +279,28 @@ async function resolveOptions(options) {
252
279
  ...subConfig,
253
280
  ...options
254
281
  };
255
- let { entry, format = ["es"], plugins = [], clean = false, silent = false, treeshake = true, platform = "node", outDir = "dist", sourcemap = false, dts = false, unused = false, watch = false, shims = false, skipNodeModulesBundle = false, publint: publint$1 = false, fromVite, alias } = subOptions;
282
+ let { entry, format = ["es"], plugins = [], clean = false, silent = false, treeshake = true, platform = "node", outDir = "dist", sourcemap = false, dts = false, unused = false, watch = false, shims = false, skipNodeModulesBundle = false, publint: publint$1 = false, fromVite, alias, tsconfig } = subOptions;
256
283
  entry = await resolveEntry(entry);
257
284
  if (clean === true) clean = [];
258
285
  if (publint$1 === true) publint$1 = {};
286
+ if (tsconfig !== false) {
287
+ if (tsconfig === true || tsconfig == null) {
288
+ const isSet = tsconfig;
289
+ tsconfig = await findTsconfig(cwd);
290
+ if (isSet && !tsconfig) logger.warn(`No tsconfig found in \`${cwd}\``);
291
+ } else {
292
+ const tsconfigPath = path.resolve(cwd, tsconfig);
293
+ if (await fsExists(tsconfigPath)) tsconfig = tsconfigPath;
294
+ else if (tsconfig.includes("\\") || tsconfig.includes("/")) {
295
+ logger.warn(`tsconfig \`${tsconfig}\` doesn't exist`);
296
+ tsconfig = false;
297
+ } else {
298
+ tsconfig = await findTsconfig(cwd, tsconfig);
299
+ if (!tsconfig) logger.warn(`No \`${tsconfig}\` found in \`${cwd}\``);
300
+ }
301
+ }
302
+ if (tsconfig) logger.info(`Using tsconfig: ${underline(tsconfig)}`);
303
+ }
259
304
  if (fromVite) {
260
305
  const viteUserConfig = await loadViteConfig(fromVite === true ? "vite" : fromVite, cwd);
261
306
  if (viteUserConfig) {
@@ -282,7 +327,8 @@ async function resolveOptions(options) {
282
327
  shims,
283
328
  skipNodeModulesBundle,
284
329
  publint: publint$1,
285
- alias
330
+ alias,
331
+ tsconfig
286
332
  };
287
333
  return config;
288
334
  }));
@@ -409,7 +455,7 @@ async function build(userOptions = {}) {
409
455
  const dirname$1 = path.dirname(fileURLToPath(import.meta.url));
410
456
  const pkgRoot = path.resolve(dirname$1, "..");
411
457
  async function buildSingle(config) {
412
- const { entry, external, plugins: userPlugins, outDir, format: formats, clean, platform, alias, treeshake, sourcemap, dts, minify, watch, unused, target, define, shims, fixedExtension, onSuccess } = config;
458
+ const { outDir, format: formats, clean, dts, watch, onSuccess } = config;
413
459
  let onSuccessCleanup;
414
460
  const pkg = await readPackageJson(process.cwd());
415
461
  await rebuild(true);
@@ -421,8 +467,8 @@ async function buildSingle(config) {
421
467
  let hasErrors = false;
422
468
  await Promise.all(formats.map(async (format) => {
423
469
  try {
424
- await build$1(await getBuildOptions(format));
425
- if (format === "cjs" && dts) await build$1(await getBuildOptions(format, true));
470
+ await build$1(await getBuildOptions(config, pkg, format));
471
+ if (format === "cjs" && dts) await build$1(await getBuildOptions(config, pkg, format, true));
426
472
  } catch (error) {
427
473
  if (watch) {
428
474
  logger.error(error);
@@ -447,51 +493,59 @@ async function buildSingle(config) {
447
493
  onSuccessCleanup = () => p.kill("SIGTERM");
448
494
  } else await onSuccess?.(config);
449
495
  }
450
- async function getBuildOptions(format, cjsDts) {
451
- const extension = resolveOutputExtension(pkg, format, fixedExtension);
452
- const plugins = [];
453
- if (pkg || config.skipNodeModulesBundle) plugins.push(ExternalPlugin(config, pkg));
454
- if (unused && !cjsDts) {
455
- const { Unused } = await import("unplugin-unused");
456
- plugins.push(Unused.rolldown(unused === true ? {} : unused));
457
- }
458
- if (dts) {
459
- const { dts: dtsPlugin } = await import("rolldown-plugin-dts");
460
- if (format === "es") plugins.push(dtsPlugin(dts));
461
- else if (cjsDts) plugins.push(dtsPlugin({
462
- ...dts,
463
- emitDtsOnly: true
464
- }));
465
- }
466
- if (target && !cjsDts) plugins.push(transformPlugin({
467
- target: target && (typeof target === "string" ? target : target.join(",")),
468
- exclude: /\.d\.[cm]?ts$/
469
- }));
470
- plugins.push(userPlugins);
471
- const inputOptions = await mergeUserOptions({
472
- input: entry,
473
- external,
474
- resolve: { alias },
475
- treeshake,
476
- platform,
477
- define,
478
- plugins,
479
- inject: { ...shims && !cjsDts && getShimsInject(format, platform) }
480
- }, config.inputOptions, [format]);
481
- const outputOptions = await mergeUserOptions({
482
- format: cjsDts ? "es" : format,
483
- name: config.globalName,
484
- sourcemap,
485
- dir: outDir,
486
- minify,
487
- entryFileNames: `[name].${extension}`,
488
- chunkFileNames: `[name]-[hash].${extension}`
489
- }, config.outputOptions, [format]);
490
- return {
491
- ...inputOptions,
492
- output: outputOptions
496
+ }
497
+ async function getBuildOptions(config, pkg, format, cjsDts) {
498
+ const { entry, external, plugins: userPlugins, outDir, platform, alias, treeshake, sourcemap, dts, minify, unused, target, define, shims, tsconfig } = config;
499
+ const plugins = [];
500
+ if (pkg || config.skipNodeModulesBundle) plugins.push(ExternalPlugin(config, pkg));
501
+ if (unused && !cjsDts) {
502
+ const { Unused } = await import("unplugin-unused");
503
+ plugins.push(Unused.rolldown(unused === true ? {} : unused));
504
+ }
505
+ if (dts) {
506
+ const { dts: dtsPlugin } = await import("rolldown-plugin-dts");
507
+ const options = {
508
+ tsconfig,
509
+ ...dts
493
510
  };
511
+ if (format === "es") plugins.push(dtsPlugin(options));
512
+ else if (cjsDts) plugins.push(dtsPlugin({
513
+ ...options,
514
+ emitDtsOnly: true
515
+ }));
494
516
  }
517
+ if (target && !cjsDts) plugins.push(transformPlugin({
518
+ target: target && (typeof target === "string" ? target : target.join(",")),
519
+ exclude: /\.d\.[cm]?ts$/
520
+ }));
521
+ plugins.push(userPlugins);
522
+ const inputOptions = await mergeUserOptions({
523
+ input: entry,
524
+ external,
525
+ resolve: {
526
+ alias,
527
+ tsconfigFilename: tsconfig || void 0
528
+ },
529
+ treeshake,
530
+ platform,
531
+ define,
532
+ plugins,
533
+ inject: { ...shims && !cjsDts && getShimsInject(format, platform) }
534
+ }, config.inputOptions, [format]);
535
+ const [entryFileNames, chunkFileNames] = resolveChunkFilename(pkg, inputOptions, format, config);
536
+ const outputOptions = await mergeUserOptions({
537
+ format: cjsDts ? "es" : format,
538
+ name: config.globalName,
539
+ sourcemap,
540
+ dir: outDir,
541
+ minify,
542
+ entryFileNames,
543
+ chunkFileNames
544
+ }, config.outputOptions, [format]);
545
+ return {
546
+ ...inputOptions,
547
+ output: outputOptions
548
+ };
495
549
  }
496
550
 
497
551
  //#endregion
@@ -1,4 +1,4 @@
1
- import { version } from "./package-DtsCM7oZ.js";
1
+ import { version } from "./package-BnNFONow.js";
2
2
  import process from "node:process";
3
3
  import { readFile, unlink, writeFile } from "node:fs/promises";
4
4
  import consola from "consola";
@@ -52,7 +52,7 @@ async function migratePackageJson(dryRun) {
52
52
  for (const key of Object.keys(pkg.scripts)) if (pkg.scripts[key].includes("tsup")) {
53
53
  consola.info(`Migrating \`${key}\` script to tsdown`);
54
54
  found = true;
55
- pkg.scripts[key] = pkg.scripts[key].replaceAll("tsup", "tsdown");
55
+ pkg.scripts[key] = pkg.scripts[key].replaceAll(/tsup(?:-node)?/g, "tsdown");
56
56
  }
57
57
  }
58
58
  if (pkg.tsup) {
@@ -2,7 +2,12 @@ import { ExternalOption, InputOptions, InternalModuleFormat, ModuleFormat, Outpu
2
2
  import { Options } from "publint";
3
3
  import { Options as Options$1 } from "rolldown-plugin-dts";
4
4
  import { Options as Options$2 } from "unplugin-unused";
5
+ import { PackageJson } from "pkg-types";
5
6
 
7
+ //#region src/utils/package.d.ts
8
+ type PackageType = "module" | "commonjs";
9
+
10
+ //#endregion
6
11
  //#region src/utils/types.d.ts
7
12
  type Overwrite<
8
13
  T,
@@ -18,6 +23,17 @@ type Arrayable<T> = T | T[];
18
23
  //#endregion
19
24
  //#region src/options.d.ts
20
25
  type Sourcemap = boolean | "inline" | "hidden";
26
+ interface OutExtensionContext {
27
+ options: InputOptions;
28
+ format: NormalizedFormat;
29
+ /** "type" field in project's package.json */
30
+ pkgType: PackageType;
31
+ }
32
+ interface OutExtensionObject {
33
+ js?: string;
34
+ dts?: string;
35
+ }
36
+ type OutExtensionFactory = (ctx: OutExtensionContext) => OutExtensionObject;
21
37
  /**
22
38
  * Options for tsdown.
23
39
  */
@@ -26,6 +42,7 @@ interface Options$3 {
26
42
  external?: ExternalOption;
27
43
  noExternal?: Arrayable<string | RegExp> | ((id: string, importer: string | undefined) => boolean | null | undefined | void);
28
44
  alias?: Record<string, string>;
45
+ tsconfig?: string | boolean;
29
46
  /** @default 'node' */
30
47
  platform?: "node" | "neutral" | "browser";
31
48
  inputOptions?: InputOptions | ((options: InputOptions, format: NormalizedFormat) => Awaitable<InputOptions | void | null>);
@@ -39,6 +56,7 @@ interface Options$3 {
39
56
  target?: string | string[];
40
57
  define?: Record<string, string>;
41
58
  shims?: boolean;
59
+ outExtensions?: OutExtensionFactory;
42
60
  outputOptions?: OutputOptions | ((options: OutputOptions, format: NormalizedFormat) => Awaitable<OutputOptions | void | null>);
43
61
  /** @default true */
44
62
  treeshake?: boolean;
@@ -86,10 +104,11 @@ interface Options$3 {
86
104
  */
87
105
  type UserConfig = Arrayable<Omit<Options$3, "config">>;
88
106
  type NormalizedFormat = Exclude<InternalModuleFormat, "app"> | "experimental-app";
89
- type ResolvedOptions = Omit<Overwrite<MarkPartial<Options$3, "globalName" | "inputOptions" | "outputOptions" | "minify" | "target" | "define" | "alias" | "external" | "noExternal" | "onSuccess" | "dts" | "fixedExtension">, {
107
+ type ResolvedOptions = Omit<Overwrite<MarkPartial<Options$3, "globalName" | "inputOptions" | "outputOptions" | "minify" | "target" | "define" | "alias" | "external" | "noExternal" | "onSuccess" | "dts" | "fixedExtension" | "outExtensions">, {
90
108
  format: NormalizedFormat[]
91
109
  clean: string[] | false
92
110
  dts: false | Options$1
111
+ tsconfig: string | false
93
112
  }>, "config" | "fromVite">;
94
113
 
95
114
  //#endregion
@@ -0,0 +1,6 @@
1
+
2
+ //#region package.json
3
+ var version = "0.9.0";
4
+
5
+ //#endregion
6
+ export { version };
package/dist/plugins.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ResolvedOptions } from "./options.d-C08fnFhO.js";
1
+ import { ResolvedOptions } from "./options.d-BUmkLb5_.js";
2
2
  import { Plugin } from "rolldown";
3
3
  import { PackageJson } from "pkg-types";
4
4
 
package/dist/run.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { logger, setSilent } from "./logger-4bmpqibt.js";
2
- import { version } from "./package-DtsCM7oZ.js";
2
+ import { version } from "./package-BnNFONow.js";
3
3
  import process from "node:process";
4
4
  import { VERSION } from "rolldown";
5
5
  import { dim } from "ansis";
@@ -16,7 +16,7 @@ cli.command("[...files]", "Bundle files", { ignoreOptionDefaultValue: true }).op
16
16
  await build$1(flags);
17
17
  });
18
18
  cli.command("migrate", "Migrate from tsup to tsdown").option("-c, --cwd <dir>", "Working directory").option("-d, --dry-run", "Dry run").action(async (args) => {
19
- const { migrate } = await import("./migrate-DKCgygvz.js");
19
+ const { migrate } = await import("./migrate-D8koNtWX.js");
20
20
  await migrate(args);
21
21
  });
22
22
  async function runCLI() {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tsdown",
3
- "version": "0.8.0",
4
- "description": "An even faster bundler powered by Rolldown.",
3
+ "version": "0.9.0",
4
+ "description": "Smooth and fast library bundler powered by Rolldown.",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "homepage": "https://github.com/rolldown/tsdown#readme",
@@ -62,7 +62,7 @@
62
62
  "diff": "^7.0.0",
63
63
  "find-up-simple": "^1.0.1",
64
64
  "rolldown": "^1.0.0-beta.7",
65
- "rolldown-plugin-dts": "^0.6.0",
65
+ "rolldown-plugin-dts": "^0.8.0",
66
66
  "tinyexec": "^1.0.1",
67
67
  "tinyglobby": "^0.2.12",
68
68
  "unconfig": "^7.3.1"
@@ -70,13 +70,12 @@
70
70
  "devDependencies": {
71
71
  "@sxzz/eslint-config": "^6.1.1",
72
72
  "@sxzz/prettier-config": "^2.2.1",
73
- "@sxzz/test-utils": "^0.5.4",
73
+ "@sxzz/test-utils": "^0.5.5",
74
74
  "@types/debug": "^4.1.12",
75
75
  "@types/diff": "^7.0.2",
76
76
  "@types/node": "^22.14.1",
77
77
  "bumpp": "^10.1.0",
78
- "eslint": "^9.24.0",
79
- "oxc-transform": "^0.63.0",
78
+ "eslint": "^9.25.0",
80
79
  "pkg-types": "^2.1.0",
81
80
  "prettier": "^3.5.3",
82
81
  "publint": "^0.3.12",
@@ -85,7 +84,7 @@
85
84
  "typescript": "~5.8.3",
86
85
  "unplugin-ast": "^0.14.6",
87
86
  "unplugin-unused": "^0.4.4",
88
- "vite": "^6.2.6",
87
+ "vite": "^6.3.2",
89
88
  "vitest": "^3.1.1"
90
89
  },
91
90
  "engines": {
@@ -1,6 +0,0 @@
1
-
2
- //#region package.json
3
- var version = "0.8.0";
4
-
5
- //#endregion
6
- export { version };