Skip to content

Commit cda6f99

Browse files
committed
feat!: clean output dir by default
1 parent bb75cbc commit cda6f99

File tree

6 files changed

+58
-35
lines changed

6 files changed

+58
-35
lines changed

pnpm-lock.yaml

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pnpm-workspace.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ catalogs:
3939
hookable: ^5.5.3
4040
lightningcss: ^1.29.3
4141
rolldown: 1.0.0-beta.8-commit.151352b
42-
rolldown-plugin-dts: ^0.9.4
42+
rolldown-plugin-dts: ^0.9.5
4343
tinyexec: ^1.0.1
4444
tinyglobby: ^0.2.13
4545
unconfig: ^7.3.2

src/features/clean.ts

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,29 @@
1-
import { readdir } from 'node:fs/promises'
2-
import path from 'node:path'
31
import Debug from 'debug'
42
import { glob } from 'tinyglobby'
5-
import { fsExists, fsRemove } from '../utils/fs'
3+
import { fsRemove } from '../utils/fs'
64
import { logger } from '../utils/logger'
5+
import type { ResolvedOptions } from '../options'
76

87
const debug = Debug('tsdown:clean')
98

10-
// clean cwd dir + patterns
11-
export async function cleanOutDir(
12-
cwd: string,
13-
patterns: string[],
14-
): Promise<void> {
15-
const files = []
9+
export async function cleanOutDir(configs: ResolvedOptions[]): Promise<void> {
10+
const removes = new Set<string>()
1611

17-
if (await fsExists(cwd))
18-
files.push(...(await readdir(cwd)).map((file) => path.resolve(cwd, file)))
19-
20-
if (patterns.length) {
21-
files.push(...(await glob(patterns, { cwd, absolute: true })))
12+
for (const config of configs) {
13+
if (!config.clean.length) continue
14+
const files = await glob(config.clean, { cwd: config.cwd, absolute: true })
15+
for (const file of files) {
16+
removes.add(file)
17+
}
2218
}
19+
if (!removes.size) return
2320

24-
logger.info('Cleaning output folder')
25-
for (const file of files) {
26-
debug('Removing', file)
27-
await fsRemove(file)
28-
}
21+
logger.info('Cleaning %d files', removes.size)
22+
await Promise.all(
23+
[...removes].map(async (file) => {
24+
debug('Removing', file)
25+
await fsRemove(file)
26+
}),
27+
)
28+
debug('Removed %d files', removes.size)
2929
}

src/index.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,15 @@ export async function build(userOptions: Options = {}): Promise<void> {
5555
debug('No config file found')
5656
}
5757

58-
const rebuilds = await Promise.all(configs.map(buildSingle))
58+
let cleanPromise: Promise<void> | undefined
59+
const clean = () => {
60+
if (cleanPromise) return cleanPromise
61+
return (cleanPromise = cleanOutDir(configs))
62+
}
63+
64+
const rebuilds = await Promise.all(
65+
configs.map((options) => buildSingle(options, clean)),
66+
)
5967
const cleanCbs: (() => Promise<void>)[] = []
6068

6169
for (const [i, config] of configs.entries()) {
@@ -84,12 +92,16 @@ export const pkgRoot: string = path.resolve(dirname, '..')
8492
/**
8593
* Build a single configuration, without watch and shortcuts features.
8694
*
95+
* Internal API, not for public use
96+
*
97+
* @private
8798
* @param config Resolved options
8899
*/
89100
export async function buildSingle(
90101
config: ResolvedOptions,
102+
clean: () => Promise<void>,
91103
): Promise<(() => Promise<void>) | undefined> {
92-
const { outDir, format: formats, clean, dts, watch, onSuccess } = config
104+
const { format: formats, dts, watch, onSuccess } = config
93105
let onSuccessCleanup: (() => any) | undefined
94106

95107
const pkg = await readPackageJson(process.cwd())
@@ -104,9 +116,9 @@ export async function buildSingle(
104116
const startTime = performance.now()
105117

106118
await hooks.callHook('build:prepare', context)
107-
108119
onSuccessCleanup?.()
109-
if (clean) await cleanOutDir(outDir, clean)
120+
121+
await clean()
110122

111123
let hasErrors = false
112124
await Promise.all(

src/options.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ export interface Options {
7373
/** @default 'dist' */
7474
outDir?: string
7575
sourcemap?: Sourcemap
76+
/**
77+
* Clean directories before build.
78+
*
79+
* Default to output directory.
80+
*/
7681
clean?: boolean | string[]
7782
/** @default false */
7883
minify?: boolean | 'dce-only' | MinifyOptions
@@ -196,7 +201,7 @@ export type ResolvedOptions = Omit<
196201
{
197202
format: NormalizedFormat[]
198203
target?: string[]
199-
clean: string[] | false
204+
clean: string[]
200205
dts: false | DtsOptions
201206
report: false | ReportOptions
202207
tsconfig: string | false
@@ -223,7 +228,7 @@ export async function resolveOptions(options: Options): Promise<{
223228
entry,
224229
format = ['es'],
225230
plugins = [],
226-
clean = false,
231+
clean = true,
227232
silent = false,
228233
treeshake = true,
229234
platform = 'node',
@@ -243,8 +248,15 @@ export async function resolveOptions(options: Options): Promise<{
243248
env = {},
244249
} = subOptions
245250

251+
outDir = path.resolve(outDir)
246252
entry = await resolveEntry(entry, cwd)
247-
if (clean === true) clean = []
253+
254+
if (clean === true) {
255+
clean = [outDir]
256+
} else if (!clean) {
257+
clean = []
258+
}
259+
248260
if (publint === true) publint = {}
249261

250262
if (tsconfig !== false) {
@@ -309,7 +321,7 @@ export async function resolveOptions(options: Options): Promise<{
309321
plugins,
310322
format: normalizeFormat(format),
311323
target: target ? resolveComma(toArray(target)) : undefined,
312-
outDir: path.resolve(outDir),
324+
outDir,
313325
clean,
314326
silent,
315327
treeshake,

tsdown.config.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { defineConfig } from './src/config.ts'
33
export default defineConfig({
44
entry: ['./src/{index,run,plugins,config}.ts'],
55
target: 'node18',
6-
clean: true,
76
platform: 'node',
87
skipNodeModulesBundle: true,
98
shims: true,

0 commit comments

Comments
 (0)