Skip to content

Commit c710932

Browse files
committed
feat!: enable dts based on typings field in package.json
1 parent fac9829 commit c710932

File tree

7 files changed

+76
-50
lines changed

7 files changed

+76
-50
lines changed

src/cli.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ cli
3333
.option('--platform <platform>', 'Target platform', {
3434
default: 'node',
3535
})
36-
.option('--dts', 'Generate dts files', { default: false })
36+
.option('--dts', 'Generate dts files')
3737
.option('--publint', 'Enable publint', { default: false })
3838
.option('--unused', 'Enable unused dependencies check', { default: false })
3939
.option('-w, --watch [path]', 'Watch mode')

src/features/clean.ts

+13-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import Debug from 'debug'
22
import { glob } from 'tinyglobby'
33
import { fsRemove } from '../utils/fs'
44
import { logger } from '../utils/logger'
5-
import type { ResolvedOptions } from '../options'
5+
import type { Options, ResolvedOptions } from '../options'
66

77
const debug = Debug('tsdown:clean')
88

@@ -27,3 +27,15 @@ export async function cleanOutDir(configs: ResolvedOptions[]): Promise<void> {
2727
)
2828
debug('Removed %d files', removes.size)
2929
}
30+
31+
export function resolveClean(
32+
clean: Options['clean'],
33+
outDir: string,
34+
): string[] {
35+
if (clean === true) {
36+
clean = [outDir]
37+
} else if (!clean) {
38+
clean = []
39+
}
40+
return clean
41+
}

src/features/tsconfig.ts

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import path from 'node:path'
2+
import { underline } from 'ansis'
3+
import { up as findUp } from 'empathic/find'
4+
import { fsExists } from '../utils/fs'
5+
import { logger } from '../utils/logger'
6+
import type { Options } from '../options'
7+
8+
export function findTsconfig(
9+
cwd?: string,
10+
name: string = 'tsconfig.json',
11+
): string | false {
12+
return findUp(name, { cwd }) || false
13+
}
14+
15+
export async function resolveTsconfig(
16+
tsconfig: Options['tsconfig'],
17+
cwd: string,
18+
): Promise<string | false> {
19+
if (tsconfig !== false) {
20+
if (tsconfig === true || tsconfig == null) {
21+
const isSet = tsconfig
22+
tsconfig = findTsconfig(cwd)
23+
if (isSet && !tsconfig) {
24+
logger.warn(`No tsconfig found in \`${cwd}\``)
25+
}
26+
} else {
27+
const tsconfigPath = path.resolve(cwd, tsconfig)
28+
if (await fsExists(tsconfigPath)) {
29+
tsconfig = tsconfigPath
30+
} else if (tsconfig.includes('\\') || tsconfig.includes('/')) {
31+
logger.warn(`tsconfig \`${tsconfig}\` doesn't exist`)
32+
tsconfig = false
33+
} else {
34+
tsconfig = findTsconfig(cwd, tsconfig)
35+
if (!tsconfig) {
36+
logger.warn(`No \`${tsconfig}\` found in \`${cwd}\``)
37+
}
38+
}
39+
}
40+
41+
if (tsconfig) {
42+
logger.info(`Using tsconfig: ${underline(path.relative(cwd, tsconfig))}`)
43+
}
44+
}
45+
46+
return tsconfig
47+
}

src/options.ts

+14-39
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ import { pathToFileURL } from 'node:url'
55
import { underline } from 'ansis'
66
import Debug from 'debug'
77
import { loadConfig } from 'unconfig'
8+
import { resolveClean } from './features/clean'
89
import { resolveEntry } from './features/entry'
9-
import { fsExists } from './utils/fs'
10+
import { resolveTsconfig } from './features/tsconfig'
1011
import { resolveComma, toArray } from './utils/general'
1112
import { logger } from './utils/logger'
1213
import { normalizeFormat, readPackageJson } from './utils/package'
13-
import { findTsconfig } from './utils/tsconfig'
1414
import type { TsdownHooks } from './features/hooks'
1515
import type { OutExtensionFactory } from './features/output'
1616
import type { ReportOptions } from './features/report'
@@ -139,7 +139,11 @@ export interface Options {
139139

140140
/// addons
141141
/**
142-
* Emit declaration files
142+
* Emit TypeScript declaration files (.d.ts).
143+
*
144+
* By default, this feature is auto-detected based on the presence of the `types` field in the `package.json` file.
145+
* - If the `types` field is present in `package.json`, declaration file emission is enabled.
146+
* - If the `types` field is absent, declaration file emission is disabled by default.
143147
*/
144148
dts?: boolean | DtsOptions
145149

@@ -242,7 +246,7 @@ export async function resolveOptions(options: Options): Promise<{
242246
platform = 'node',
243247
outDir = 'dist',
244248
sourcemap = false,
245-
dts = false,
249+
dts,
246250
unused = false,
247251
watch = false,
248252
shims = false,
@@ -258,44 +262,17 @@ export async function resolveOptions(options: Options): Promise<{
258262

259263
outDir = path.resolve(outDir)
260264
entry = await resolveEntry(entry, cwd)
265+
clean = resolveClean(clean, outDir)
266+
267+
const pkg = await readPackageJson(cwd)
261268

262-
if (clean === true) {
263-
clean = [outDir]
264-
} else if (!clean) {
265-
clean = []
269+
if (dts == null) {
270+
dts = !!(pkg?.types || pkg?.typings)
266271
}
267272

273+
tsconfig = await resolveTsconfig(tsconfig, cwd)
268274
if (publint === true) publint = {}
269275

270-
if (tsconfig !== false) {
271-
if (tsconfig === true || tsconfig == null) {
272-
const isSet = tsconfig
273-
tsconfig = findTsconfig(cwd)
274-
if (isSet && !tsconfig) {
275-
logger.warn(`No tsconfig found in \`${cwd}\``)
276-
}
277-
} else {
278-
const tsconfigPath = path.resolve(cwd, tsconfig)
279-
if (await fsExists(tsconfigPath)) {
280-
tsconfig = tsconfigPath
281-
} else if (tsconfig.includes('\\') || tsconfig.includes('/')) {
282-
logger.warn(`tsconfig \`${tsconfig}\` doesn't exist`)
283-
tsconfig = false
284-
} else {
285-
tsconfig = findTsconfig(cwd, tsconfig)
286-
if (!tsconfig) {
287-
logger.warn(`No \`${tsconfig}\` found in \`${cwd}\``)
288-
}
289-
}
290-
}
291-
292-
if (tsconfig) {
293-
logger.info(
294-
`Using tsconfig: ${underline(path.relative(cwd, tsconfig))}`,
295-
)
296-
}
297-
}
298-
299276
if (fromVite) {
300277
const viteUserConfig = await loadViteConfig(
301278
fromVite === true ? 'vite' : fromVite,
@@ -323,8 +300,6 @@ export async function resolveOptions(options: Options): Promise<{
323300
}
324301
}
325302

326-
const pkg = await readPackageJson(cwd)
327-
328303
const config: ResolvedOptions = {
329304
...subOptions,
330305
entry,

src/utils/tsconfig.ts

-8
This file was deleted.

tests/utils.ts

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export async function testBuild(
5656
entry: 'index.ts',
5757
config: false,
5858
outDir: 'dist',
59+
dts: false,
5960
...options,
6061
}
6162
await build(resolvedOptions)

tsdown.config.ts

-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ export default defineConfig({
66
platform: 'node',
77
skipNodeModulesBundle: true,
88
shims: true,
9-
dts: { isolatedDeclarations: true, resolve: [] },
109
unused: { level: 'error' },
1110
publint: true,
1211
onSuccess() {

0 commit comments

Comments
 (0)