tsdown 0.2.17 → 0.3.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/dist/{external-m3ERo7i1.js → external-DZ7KC16d.js} +4 -6
- package/dist/features/shortcuts.d.ts +7 -0
- package/dist/features/watch.d.ts +2 -1
- package/dist/index.js +120 -89
- package/dist/options.d.ts +2 -1
- package/dist/plugins.js +1 -1
- package/dist/run.js +4 -4
- package/package.json +15 -15
|
@@ -8,12 +8,10 @@ function ExternalPlugin(pkg, platform) {
|
|
|
8
8
|
resolveId(id) {
|
|
9
9
|
let shouldExternal = deps && deps.some((dep) => id === dep || id.startsWith(`${dep}/`));
|
|
10
10
|
shouldExternal ||= platform === "node" && isBuiltin(id);
|
|
11
|
-
if (shouldExternal) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
};
|
|
16
|
-
}
|
|
11
|
+
if (shouldExternal) return {
|
|
12
|
+
id,
|
|
13
|
+
external: true
|
|
14
|
+
};
|
|
17
15
|
}
|
|
18
16
|
};
|
|
19
17
|
}
|
package/dist/features/watch.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import type { ResolvedOptions } from '../options';
|
|
2
|
-
|
|
2
|
+
import type { FSWatcher } from 'chokidar';
|
|
3
|
+
export declare function watchBuild(options: ResolvedOptions, rebuild: () => void): Promise<FSWatcher>;
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { logger } from "./logger-e0Fr5WMR.js";
|
|
2
|
-
import { ExternalPlugin } from "./external-
|
|
3
|
-
import { default as process, default as process$
|
|
2
|
+
import { ExternalPlugin } from "./external-DZ7KC16d.js";
|
|
3
|
+
import process, { default as process$1, default as process$2, default as process$3 } from "node:process";
|
|
4
4
|
import { rolldown } from "rolldown";
|
|
5
5
|
import { IsolatedDecl } from "unplugin-isolated-decl";
|
|
6
6
|
import { Unused } from "unplugin-unused";
|
|
7
7
|
import { access, readdir, rm, stat } from "node:fs/promises";
|
|
8
|
-
import
|
|
8
|
+
import path, { default as path$1, default as path$2 } from "node:path";
|
|
9
9
|
import { glob, glob as glob$1 } from "tinyglobby";
|
|
10
10
|
import { readPackageJSON } from "pkg-types";
|
|
11
|
-
import
|
|
11
|
+
import readline from "node:readline";
|
|
12
|
+
import pc, { default as pc$1, default as pc$2 } from "picocolors";
|
|
12
13
|
import { loadConfig } from "unconfig";
|
|
13
14
|
|
|
14
15
|
//#region src/utils/fs.ts
|
|
@@ -21,19 +22,15 @@ function fsExists(path$3) {
|
|
|
21
22
|
async function cleanOutDir(cwd, patterns) {
|
|
22
23
|
const files = [];
|
|
23
24
|
if (await fsExists(cwd)) files.push(...(await readdir(cwd)).map((file) => path$2.resolve(cwd, file)));
|
|
24
|
-
if (patterns.length) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}));
|
|
29
|
-
}
|
|
25
|
+
if (patterns.length) files.push(...await glob$1(patterns, {
|
|
26
|
+
cwd,
|
|
27
|
+
absolute: true
|
|
28
|
+
}));
|
|
30
29
|
logger.info("Cleaning output folder");
|
|
31
|
-
for (const file of files) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
});
|
|
36
|
-
}
|
|
30
|
+
for (const file of files) await rm(file, {
|
|
31
|
+
force: true,
|
|
32
|
+
recursive: true
|
|
33
|
+
});
|
|
37
34
|
}
|
|
38
35
|
|
|
39
36
|
//#endregion
|
|
@@ -46,9 +43,7 @@ async function readPackageJson(dir) {
|
|
|
46
43
|
}
|
|
47
44
|
function getPackageType(pkg) {
|
|
48
45
|
if (pkg?.type) {
|
|
49
|
-
if (!["module", "commonjs"].includes(pkg.type)) {
|
|
50
|
-
throw new Error(`Invalid package.json type: ${pkg.type}`);
|
|
51
|
-
}
|
|
46
|
+
if (!["module", "commonjs"].includes(pkg.type)) throw new Error(`Invalid package.json type: ${pkg.type}`);
|
|
52
47
|
return pkg.type;
|
|
53
48
|
}
|
|
54
49
|
return "commonjs";
|
|
@@ -62,27 +57,71 @@ function resolveOutputExtension(pkg, format) {
|
|
|
62
57
|
case "iife": return "js";
|
|
63
58
|
case "es":
|
|
64
59
|
case "esm":
|
|
65
|
-
case "module":
|
|
66
|
-
return moduleType === "module" ? "js" : "mjs";
|
|
67
|
-
}
|
|
60
|
+
case "module": return moduleType === "module" ? "js" : "mjs";
|
|
68
61
|
case "cjs":
|
|
69
|
-
case "commonjs":
|
|
70
|
-
|
|
62
|
+
case "commonjs": return moduleType === "module" ? "cjs" : "js";
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region src/features/shortcuts.ts
|
|
68
|
+
function shortcuts(watcher, rebuild) {
|
|
69
|
+
let actionRunning = false;
|
|
70
|
+
async function onInput(input) {
|
|
71
|
+
if (actionRunning) return;
|
|
72
|
+
const SHORTCUTS = [
|
|
73
|
+
{
|
|
74
|
+
key: "r",
|
|
75
|
+
description: "rebuild",
|
|
76
|
+
action() {
|
|
77
|
+
rebuild();
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
key: "c",
|
|
82
|
+
description: "clear console",
|
|
83
|
+
action() {
|
|
84
|
+
console.clear();
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
key: "q",
|
|
89
|
+
description: "quit",
|
|
90
|
+
action() {
|
|
91
|
+
rl.close();
|
|
92
|
+
return watcher.close();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
];
|
|
96
|
+
if (input === "h") {
|
|
97
|
+
const loggedKeys = new Set();
|
|
98
|
+
logger.info(" Shortcuts");
|
|
99
|
+
for (const shortcut$1 of SHORTCUTS) {
|
|
100
|
+
if (loggedKeys.has(shortcut$1.key)) continue;
|
|
101
|
+
loggedKeys.add(shortcut$1.key);
|
|
102
|
+
if (shortcut$1.action == null) continue;
|
|
103
|
+
logger.info(pc$2.dim(" press ") + pc$2.bold(`${shortcut$1.key} + enter`) + pc$2.dim(` to ${shortcut$1.description}`));
|
|
104
|
+
}
|
|
105
|
+
return;
|
|
71
106
|
}
|
|
107
|
+
const shortcut = SHORTCUTS.find((shortcut$1) => shortcut$1.key === input);
|
|
108
|
+
if (!shortcut) return;
|
|
109
|
+
actionRunning = true;
|
|
110
|
+
await shortcut.action();
|
|
111
|
+
actionRunning = false;
|
|
72
112
|
}
|
|
113
|
+
const rl = readline.createInterface({ input: process$3.stdin });
|
|
114
|
+
rl.on("line", onInput);
|
|
73
115
|
}
|
|
74
116
|
|
|
75
117
|
//#endregion
|
|
76
118
|
//#region src/utils/general.ts
|
|
77
119
|
function toArray(val, defaultValue) {
|
|
78
|
-
if (Array.isArray(val))
|
|
79
|
-
|
|
80
|
-
} else if (val == null) {
|
|
120
|
+
if (Array.isArray(val)) return val;
|
|
121
|
+
else if (val == null) {
|
|
81
122
|
if (defaultValue) return [defaultValue];
|
|
82
123
|
return [];
|
|
83
|
-
} else
|
|
84
|
-
return [val];
|
|
85
|
-
}
|
|
124
|
+
} else return [val];
|
|
86
125
|
}
|
|
87
126
|
function debounce(fn, wait) {
|
|
88
127
|
let timeout;
|
|
@@ -114,31 +153,24 @@ async function watchBuild(options, rebuild) {
|
|
|
114
153
|
logger.info(`Change detected: ${type} ${file}`);
|
|
115
154
|
debouncedRebuild();
|
|
116
155
|
});
|
|
156
|
+
return watcher;
|
|
117
157
|
}
|
|
118
158
|
|
|
119
159
|
//#endregion
|
|
120
160
|
//#region src/features/entry.ts
|
|
121
161
|
async function resolveEntry(entry) {
|
|
122
|
-
if (!entry || Object.keys(entry).length === 0)
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
if (typeof entry === "string") {
|
|
126
|
-
entry = [entry];
|
|
127
|
-
}
|
|
162
|
+
if (!entry || Object.keys(entry).length === 0) throw new Error(`No input files, try "tsdown <your-file>" instead`);
|
|
163
|
+
if (typeof entry === "string") entry = [entry];
|
|
128
164
|
if (Array.isArray(entry)) {
|
|
129
165
|
const resolvedEntry = await glob(entry);
|
|
130
166
|
if (resolvedEntry.length > 0) {
|
|
131
167
|
entry = resolvedEntry;
|
|
132
168
|
logger.info(`entry: ${pc$1.blue(entry.join(", "))}`);
|
|
133
|
-
} else {
|
|
134
|
-
throw new Error(`Cannot find entry: ${entry}`);
|
|
135
|
-
}
|
|
169
|
+
} else throw new Error(`Cannot find entry: ${entry}`);
|
|
136
170
|
} else {
|
|
137
171
|
const files = Object.values(entry);
|
|
138
172
|
files.forEach((filename) => {
|
|
139
|
-
if (!fsExists(filename)) {
|
|
140
|
-
throw new Error(`Cannot find entry: ${filename}`);
|
|
141
|
-
}
|
|
173
|
+
if (!fsExists(filename)) throw new Error(`Cannot find entry: ${filename}`);
|
|
142
174
|
});
|
|
143
175
|
logger.info(`entry: ${pc$1.blue(files.join(", "))}`);
|
|
144
176
|
}
|
|
@@ -152,7 +184,7 @@ async function normalizeOptions(options) {
|
|
|
152
184
|
...await loadConfigFile(options),
|
|
153
185
|
...options
|
|
154
186
|
};
|
|
155
|
-
let { entry, format = ["es"], plugins = [], external, clean = false, silent = false, treeshake = true, platform = "node", outDir = "dist", sourcemap = false, dts = false, unused = false, minify, alias, watch = false, inputOptions, outputOptions } = options;
|
|
187
|
+
let { entry, format = ["es"], plugins = [], external, clean = false, silent = false, treeshake = true, platform = "node", outDir = "dist", sourcemap = false, dts = false, unused = false, minify, alias, watch = false, inputOptions, outputOptions, onSuccess } = options;
|
|
156
188
|
entry = await resolveEntry(entry);
|
|
157
189
|
format = toArray(format, "es");
|
|
158
190
|
if (clean === true) clean = [];
|
|
@@ -173,7 +205,8 @@ async function normalizeOptions(options) {
|
|
|
173
205
|
minify,
|
|
174
206
|
watch,
|
|
175
207
|
inputOptions,
|
|
176
|
-
outputOptions
|
|
208
|
+
outputOptions,
|
|
209
|
+
onSuccess
|
|
177
210
|
};
|
|
178
211
|
}
|
|
179
212
|
async function loadConfigFile(options) {
|
|
@@ -188,9 +221,7 @@ async function loadConfigFile(options) {
|
|
|
188
221
|
overrideConfig = true;
|
|
189
222
|
filePath = resolved;
|
|
190
223
|
cwd = path.dirname(filePath);
|
|
191
|
-
} else
|
|
192
|
-
cwd = resolved;
|
|
193
|
-
}
|
|
224
|
+
} else cwd = resolved;
|
|
194
225
|
}
|
|
195
226
|
const { config, sources } = await loadConfig({
|
|
196
227
|
sources: overrideConfig ? [{
|
|
@@ -216,9 +247,7 @@ async function loadConfigFile(options) {
|
|
|
216
247
|
cwd,
|
|
217
248
|
defaults: {}
|
|
218
249
|
});
|
|
219
|
-
if (sources.length > 0) {
|
|
220
|
-
logger.info(`Using tsdown config: ${pc.underline(sources.join(", "))}`);
|
|
221
|
-
}
|
|
250
|
+
if (sources.length > 0) logger.info(`Using tsdown config: ${pc.underline(sources.join(", "))}`);
|
|
222
251
|
return config;
|
|
223
252
|
}
|
|
224
253
|
|
|
@@ -226,49 +255,51 @@ async function loadConfigFile(options) {
|
|
|
226
255
|
//#region src/index.ts
|
|
227
256
|
async function build(userOptions = {}) {
|
|
228
257
|
const resolved = await normalizeOptions(userOptions);
|
|
229
|
-
const { entry, external, plugins, outDir, format, clean, platform, alias, treeshake, sourcemap, dts, minify, watch, unused } = resolved;
|
|
258
|
+
const { entry, external, plugins, outDir, format, clean, platform, alias, treeshake, sourcemap, dts, minify, watch, unused, onSuccess } = resolved;
|
|
230
259
|
if (clean) await cleanOutDir(outDir, clean);
|
|
231
260
|
const pkg = await readPackageJson(process.cwd());
|
|
232
|
-
let startTime;
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
261
|
+
let startTime = performance.now();
|
|
262
|
+
const inputOptions = {
|
|
263
|
+
input: entry,
|
|
264
|
+
external,
|
|
265
|
+
resolve: { alias },
|
|
266
|
+
treeshake,
|
|
267
|
+
platform,
|
|
268
|
+
plugins: [
|
|
269
|
+
ExternalPlugin(pkg, platform),
|
|
270
|
+
dts && IsolatedDecl.rolldown(dts === true ? {} : dts),
|
|
271
|
+
unused && Unused.rolldown(unused === true ? {} : unused),
|
|
272
|
+
...plugins
|
|
273
|
+
].filter((plugin) => !!plugin),
|
|
274
|
+
...resolved.inputOptions
|
|
275
|
+
};
|
|
276
|
+
const build$1 = await rolldown(inputOptions);
|
|
277
|
+
const outputOptions = await Promise.all(format.map(async (format$1) => {
|
|
278
|
+
const extension = resolveOutputExtension(pkg, format$1);
|
|
279
|
+
const outputOptions$1 = {
|
|
280
|
+
format: format$1,
|
|
281
|
+
sourcemap,
|
|
282
|
+
dir: outDir,
|
|
283
|
+
minify,
|
|
284
|
+
entryFileNames: `[name].${extension}`,
|
|
285
|
+
chunkFileNames: `[name]-[hash].${extension}`
|
|
286
|
+
};
|
|
287
|
+
const userOutputOptions = typeof resolved.outputOptions === "function" ? await resolved.outputOptions(outputOptions$1, format$1) : resolved.outputOptions;
|
|
288
|
+
return {
|
|
289
|
+
...outputOptions$1,
|
|
290
|
+
...userOutputOptions
|
|
252
291
|
};
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
chunkFileNames: `[name]-[hash].${extension}`
|
|
263
|
-
};
|
|
264
|
-
const userOutputOptions = typeof resolved.outputOptions === "function" ? await resolved.outputOptions(outputOptions, format$1) : resolved.outputOptions;
|
|
265
|
-
return await build$1.write({
|
|
266
|
-
...outputOptions,
|
|
267
|
-
...userOutputOptions
|
|
268
|
-
});
|
|
269
|
-
}));
|
|
270
|
-
await build$1.close();
|
|
292
|
+
}));
|
|
293
|
+
await writeBundle(true);
|
|
294
|
+
if (watch) {
|
|
295
|
+
const watcher = await watchBuild(resolved, writeBundle);
|
|
296
|
+
shortcuts(watcher, writeBundle);
|
|
297
|
+
} else await build$1.close();
|
|
298
|
+
async function writeBundle(first) {
|
|
299
|
+
if (!first) startTime = performance.now();
|
|
300
|
+
await Promise.all(outputOptions.map((outputOptions$1) => build$1.write(outputOptions$1)));
|
|
271
301
|
logger.success(`${first ? "Build" : "Rebuild"} complete in ${Math.round(performance.now() - startTime)}ms`);
|
|
302
|
+
await onSuccess?.();
|
|
272
303
|
}
|
|
273
304
|
}
|
|
274
305
|
function defineConfig(options) {
|
package/dist/options.d.ts
CHANGED
|
@@ -36,12 +36,13 @@ export interface Options {
|
|
|
36
36
|
watch?: boolean | string | string[];
|
|
37
37
|
inputOptions?: InputOptions;
|
|
38
38
|
outputOptions?: OutputOptions | ((options: OutputOptions, format: Format) => MaybePromise<OutputOptions | void | null>);
|
|
39
|
+
onSuccess?: () => void | Promise<void>;
|
|
39
40
|
}
|
|
40
41
|
/**
|
|
41
42
|
* Options without specifying config file path.
|
|
42
43
|
*/
|
|
43
44
|
export type OptionsWithoutConfig = Omit<Options, 'config'>;
|
|
44
|
-
export type ResolvedOptions = Omit<Overwrite<MarkPartial<Options, 'inputOptions' | 'outputOptions' | 'minify' | 'alias' | 'external'>, {
|
|
45
|
+
export type ResolvedOptions = Omit<Overwrite<MarkPartial<Options, 'inputOptions' | 'outputOptions' | 'minify' | 'alias' | 'external' | 'onSuccess'>, {
|
|
45
46
|
format: Format[];
|
|
46
47
|
clean: string[] | false;
|
|
47
48
|
}>, 'config'>;
|
package/dist/plugins.js
CHANGED
package/dist/run.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { logger } from "./logger-e0Fr5WMR.js";
|
|
2
|
-
import
|
|
2
|
+
import process from "node:process";
|
|
3
3
|
import { VERSION as rolldownVersion } from "rolldown";
|
|
4
|
-
import
|
|
4
|
+
import pc from "picocolors";
|
|
5
5
|
import { cac } from "cac";
|
|
6
6
|
|
|
7
7
|
//#region package.json
|
|
8
|
-
const version = "0.
|
|
8
|
+
const version = "0.3.0";
|
|
9
9
|
|
|
10
10
|
//#endregion
|
|
11
11
|
//#region src/cli.ts
|
|
12
12
|
async function runCLI() {
|
|
13
13
|
const cli = cac("tsdown");
|
|
14
|
-
cli.command("[...files]", "Bundle files", { ignoreOptionDefaultValue: true }).option("-c, --config <filename>", "Use a custom config file").option("--no-config", "Disable config file").option("--format <format>", "Bundle format: esm, cjs, iife", { default: "esm" }).option("--clean", "Clean output directory").option("--minify", "Minify output").option("--silent", "Suppress non-error logs").option("-d, --out-dir <dir>", "Output directory", { default: "dist" }).option("--treeshake", "Tree-shake bundle", { default: true }).option("--sourcemap", "Generate source map", { default: false }).option("--platform <platform>", "Target platform", { default: "node" }).option("--watch", "Watch mode").action(async (input, flags) => {
|
|
14
|
+
cli.command("[...files]", "Bundle files", { ignoreOptionDefaultValue: true }).option("-c, --config <filename>", "Use a custom config file").option("--no-config", "Disable config file").option("--format <format>", "Bundle format: esm, cjs, iife", { default: "esm" }).option("--clean", "Clean output directory").option("--minify", "Minify output").option("--silent", "Suppress non-error logs").option("-d, --out-dir <dir>", "Output directory", { default: "dist" }).option("--treeshake", "Tree-shake bundle", { default: true }).option("--sourcemap", "Generate source map", { default: false }).option("--platform <platform>", "Target platform", { default: "node" }).option("-w, --watch", "Watch mode").action(async (input, flags) => {
|
|
15
15
|
logger.level = flags.silent ? 0 : 3;
|
|
16
16
|
logger.info(`tsdown ${pc.dim(`v${version}`)} powered by rolldown ${pc.dim(`v${rolldownVersion}`)}`);
|
|
17
17
|
const { build } = await import("./index.js");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tsdown",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "An even faster bundler powered by Rolldown.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -42,27 +42,27 @@
|
|
|
42
42
|
"cac": "^6.7.14",
|
|
43
43
|
"chokidar": "^4.0.1",
|
|
44
44
|
"consola": "^3.2.3",
|
|
45
|
-
"picocolors": "^1.1.
|
|
46
|
-
"pkg-types": "^1.2.
|
|
45
|
+
"picocolors": "^1.1.1",
|
|
46
|
+
"pkg-types": "^1.2.1",
|
|
47
47
|
"rolldown": "nightly",
|
|
48
|
-
"tinyglobby": "^0.2.
|
|
48
|
+
"tinyglobby": "^0.2.10",
|
|
49
49
|
"unconfig": "^0.6.0",
|
|
50
|
-
"unplugin-isolated-decl": "^0.6.
|
|
50
|
+
"unplugin-isolated-decl": "^0.6.8",
|
|
51
51
|
"unplugin-unused": "^0.2.3"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
|
-
"@sxzz/eslint-config": "^4.
|
|
54
|
+
"@sxzz/eslint-config": "^4.4.0",
|
|
55
55
|
"@sxzz/prettier-config": "^2.0.2",
|
|
56
|
-
"@types/node": "^22.
|
|
57
|
-
"bumpp": "^9.
|
|
58
|
-
"eslint": "^9.
|
|
59
|
-
"execa": "^9.
|
|
60
|
-
"fdir": "^6.
|
|
56
|
+
"@types/node": "^22.8.2",
|
|
57
|
+
"bumpp": "^9.8.0",
|
|
58
|
+
"eslint": "^9.13.0",
|
|
59
|
+
"execa": "^9.5.1",
|
|
60
|
+
"fdir": "^6.4.2",
|
|
61
61
|
"prettier": "^3.3.3",
|
|
62
|
-
"tsup": "^8.3.
|
|
63
|
-
"tsx": "^4.19.
|
|
64
|
-
"typescript": "~5.6.
|
|
65
|
-
"vitest": "^2.1.
|
|
62
|
+
"tsup": "^8.3.5",
|
|
63
|
+
"tsx": "^4.19.2",
|
|
64
|
+
"typescript": "~5.6.3",
|
|
65
|
+
"vitest": "^2.1.4"
|
|
66
66
|
},
|
|
67
67
|
"engines": {
|
|
68
68
|
"node": ">=18.0.0"
|