Skip to content

Commit 0bd0b47

Browse files
committed
feat: add name option
1 parent 6f9629c commit 0bd0b47

File tree

10 files changed

+166
-65
lines changed

10 files changed

+166
-65
lines changed

src/features/entry.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import path from 'node:path'
2-
import { blue } from 'ansis'
32
import { glob } from 'tinyglobby'
43
import { lowestCommonAncestor } from '../utils/fs'
5-
import { logger } from '../utils/logger'
4+
import { generateColor, logger, prettyName } from '../utils/logger'
65
import type { Options } from '../options'
76

87
export async function resolveEntry(
98
entry: Options['entry'],
109
cwd: string,
10+
name?: string,
1111
): Promise<Record<string, string>> {
1212
if (!entry || Object.keys(entry).length === 0) {
1313
// TODO auto find entry
@@ -20,7 +20,8 @@ export async function resolveEntry(
2020
throw new Error(`Cannot find entry: ${JSON.stringify(entry)}`)
2121
}
2222
logger.info(
23-
`entry: ${blue(entries.map((entry) => path.relative(cwd, entry)).join(', '))}`,
23+
prettyName(name),
24+
`entry: ${generateColor(name)(entries.map((entry) => path.relative(cwd, entry)).join(', '))}`,
2425
)
2526
return entryMap
2627
}

src/features/report.ts

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ import { bold, dim, green } from 'ansis'
66
import Debug from 'debug'
77
import { formatBytes } from '../utils/format'
88
import { noop } from '../utils/general'
9-
import { logger } from '../utils/logger'
10-
import { prettyFormat } from '../utils/package'
9+
import { logger, prettyFormat, prettyName } from '../utils/logger'
1110
import type { OutputAsset, OutputChunk, Plugin } from 'rolldown'
1211

1312
const debug = Debug('tsdown:report')
@@ -24,8 +23,8 @@ interface SizeInfo {
2423
gzip: number
2524
brotli: number
2625
rawText: string
27-
gzipText: string
28-
brotliText: string
26+
gzipText?: string
27+
brotliText?: string
2928
}
3029

3130
export interface ReportOptions {
@@ -48,6 +47,8 @@ export function ReportPlugin(
4847
options: ReportOptions,
4948
cwd: string,
5049
cjsDts?: boolean,
50+
name?: string,
51+
isMultiFormat?: boolean,
5152
): Plugin {
5253
return {
5354
name: 'tsdown:report',
@@ -74,17 +75,21 @@ export function ReportPlugin(
7475
...sizes.map((size) => size.rawText.length),
7576
)
7677
const gzipTextLength = Math.max(
77-
...sizes.map((size) => size.gzipText.length),
78+
...sizes.map((size) =>
79+
size.gzipText == null ? 0 : size.gzipText.length,
80+
),
7881
)
7982
const brotliTextLength = Math.max(
80-
...sizes.map((size) => size.brotliText.length),
83+
...sizes.map((size) =>
84+
size.brotliText == null ? 0 : size.brotliText.length,
85+
),
8186
)
8287

8388
let totalRaw = 0
8489
for (const size of sizes) {
8590
size.rawText = size.rawText.padStart(rawTextLength)
86-
size.gzipText = size.gzipText.padStart(gzipTextLength)
87-
size.brotliText = size.brotliText.padStart(brotliTextLength)
91+
size.gzipText = size.gzipText?.padStart(gzipTextLength)
92+
size.brotliText = size.brotliText?.padStart(brotliTextLength)
8893
totalRaw += size.raw
8994
}
9095

@@ -98,23 +103,33 @@ export function ReportPlugin(
98103
return b.raw - a.raw
99104
})
100105

101-
const formatLabel = prettyFormat(cjsDts ? 'cjs' : outputOptions.format)
106+
const nameLabel = prettyName(name)
107+
const formatLabel =
108+
isMultiFormat && prettyFormat(cjsDts ? 'cjs' : outputOptions.format)
102109

103110
for (const size of sizes) {
104111
const filenameColor = size.dts ? green : noop
105112

106113
logger.info(
114+
nameLabel,
107115
formatLabel,
108116
dim(`${outDir}/`) +
109117
filenameColor((size.isEntry ? bold : noop)(size.filename)),
110118
` `.repeat(filenameLength - size.filename.length),
111-
dim`${size.rawText} │ gzip: ${size.gzipText}`,
112-
options.brotli ? dim` │ brotli: ${size.brotliText}` : '',
119+
dim(size.rawText),
120+
size.gzipText && dim`│ gzip: ${size.gzipText}`,
121+
options.brotli &&
122+
size.brotliText &&
123+
dim`│ brotli: ${size.brotliText}`,
113124
)
114125
}
115126

116127
const totalSizeText = formatBytes(totalRaw)
117-
logger.info(formatLabel, `${sizes.length} files, total: ${totalSizeText}`)
128+
logger.info(
129+
nameLabel,
130+
formatLabel,
131+
`${sizes.length} files, total: ${totalSizeText}`,
132+
)
118133
},
119134
}
120135
}
@@ -149,7 +164,7 @@ async function calcSize(
149164
dts: RE_DTS.test(chunk.fileName),
150165
isEntry: chunk.type === 'chunk' && chunk.isEntry,
151166
raw,
152-
rawText: formatBytes(raw),
167+
rawText: formatBytes(raw)!,
153168
gzip,
154169
gzipText: formatBytes(gzip),
155170
brotli,

src/features/shebang.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@ import { chmod } from 'node:fs/promises'
22
import path from 'node:path'
33
import { underline } from 'ansis'
44
import { fsExists } from '../utils/fs'
5-
import { logger } from '../utils/logger'
6-
import { prettyFormat } from '../utils/package'
5+
import { logger, prettyFormat, prettyName } from '../utils/logger'
76
import type { Plugin } from 'rolldown'
87

98
const RE_SHEBANG = /^#!.*/
109

11-
export function ShebangPlugin(cwd: string): Plugin {
10+
export function ShebangPlugin(
11+
cwd: string,
12+
name?: string,
13+
isMultiFormat?: boolean,
14+
): Plugin {
1215
return {
1316
name: 'tsdown:shebang',
1417
async writeBundle(options, bundle) {
@@ -22,7 +25,8 @@ export function ShebangPlugin(cwd: string): Plugin {
2225
)
2326
if (await fsExists(filepath)) {
2427
logger.info(
25-
prettyFormat(options.format),
28+
prettyName(name),
29+
isMultiFormat && prettyFormat(options.format),
2630
`Granting execute permission to ${underline(path.relative(cwd, filepath))}`,
2731
)
2832
await chmod(filepath, 0o755)

src/features/target.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import { blue } from 'ansis'
21
import minVersion from 'semver/ranges/min-version.js'
32
import { resolveComma, toArray } from '../utils/general'
4-
import { logger } from '../utils/logger'
3+
import { generateColor, logger, prettyName } from '../utils/logger'
54
import type { PackageJson } from 'pkg-types'
65

76
export function resolveTarget(
87
target: string | string[] | false | undefined,
98
pkg?: PackageJson,
9+
name?: string,
1010
): string[] | undefined {
1111
if (target === false) return
1212
if (target == null) {
@@ -20,7 +20,8 @@ export function resolveTarget(
2020
const targets = resolveComma(toArray(target))
2121
if (targets.length)
2222
logger.info(
23-
`target${targets.length > 1 ? 's' : ''}: ${blue(targets.join(', '))}`,
23+
prettyName(name),
24+
`target${targets.length > 1 ? 's' : ''}: ${generateColor(name)(targets.join(', '))}`,
2425
)
2526

2627
return targets

src/features/tsconfig.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import path from 'node:path'
2-
import { blue, underline } from 'ansis'
2+
import { blue } from 'ansis'
33
import { up as findUp } from 'empathic/find'
44
import { fsStat } from '../utils/fs'
5-
import { logger } from '../utils/logger'
5+
import { generateColor, logger, prettyName } from '../utils/logger'
66
import type { Options } from '../options'
77

88
export function findTsconfig(
@@ -15,6 +15,7 @@ export function findTsconfig(
1515
export async function resolveTsconfig(
1616
tsconfig: Options['tsconfig'],
1717
cwd: string,
18+
name?: string,
1819
): Promise<string | false> {
1920
const original = tsconfig
2021

@@ -43,7 +44,10 @@ export async function resolveTsconfig(
4344
}
4445

4546
if (tsconfig) {
46-
logger.info(`Using tsconfig: ${underline(path.relative(cwd, tsconfig))}`)
47+
logger.info(
48+
prettyName(name),
49+
`tsconfig: ${generateColor(name)(path.relative(cwd, tsconfig))}`,
50+
)
4751
}
4852
}
4953

src/index.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import {
3232
} from './options'
3333
import { ShebangPlugin } from './plugins'
3434
import { logger } from './utils/logger'
35-
import { prettyFormat } from './utils/package'
3635
import type { Options as DtsOptions } from 'rolldown-plugin-dts'
3736

3837
const debug = Debug('tsdown:main')
@@ -62,6 +61,7 @@ export async function build(userOptions: Options = {}): Promise<void> {
6261
return (cleanPromise = cleanOutDir(configs))
6362
}
6463

64+
logger.info('Build start')
6565
const rebuilds = await Promise.all(
6666
configs.map((options) => buildSingle(options, clean)),
6767
)
@@ -124,17 +124,21 @@ export async function buildSingle(
124124
await Promise.all(
125125
formats.map(async (format) => {
126126
try {
127-
const formatLabel = prettyFormat(format)
128-
logger.info(formatLabel, 'Build start')
129-
130-
const buildOptions = await getBuildOptions(config, format)
127+
const isMultiFormat = formats.length > 1
128+
const buildOptions = await getBuildOptions(
129+
config,
130+
format,
131+
isMultiFormat,
132+
)
131133
await hooks.callHook('build:before', {
132134
...context,
133135
buildOptions,
134136
})
135137
await rolldownBuild(buildOptions)
136138
if (format === 'cjs' && dts) {
137-
await rolldownBuild(await getBuildOptions(config, format, true))
139+
await rolldownBuild(
140+
await getBuildOptions(config, format, true, isMultiFormat),
141+
)
138142
}
139143
} catch (error) {
140144
if (watch) {
@@ -180,6 +184,7 @@ async function getBuildOptions(
180184
config: ResolvedOptions,
181185
format: NormalizedFormat,
182186
cjsDts?: boolean,
187+
isMultiFormat?: boolean,
183188
): Promise<BuildOptions> {
184189
const {
185190
entry,
@@ -202,6 +207,7 @@ async function getBuildOptions(
202207
env,
203208
removeNodeProtocol,
204209
loader,
210+
name,
205211
} = config
206212

207213
const plugins: RolldownPluginOption = []
@@ -240,11 +246,11 @@ async function getBuildOptions(
240246
}),
241247
)
242248
}
243-
plugins.push(ShebangPlugin(cwd))
249+
plugins.push(ShebangPlugin(cwd, name, isMultiFormat))
244250
}
245251

246252
if (report && !logger.silent) {
247-
plugins.push(ReportPlugin(report, cwd, cjsDts))
253+
plugins.push(ReportPlugin(report, cwd, cjsDts, name, isMultiFormat))
248254
}
249255

250256
if (target) {

src/options/index.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,12 @@ export interface Options {
151151
/** @default false */
152152
shims?: boolean
153153

154+
/**
155+
* The name to show in CLI output. This is useful for monorepos or workspaces.
156+
* Defaults to the package name from `package.json`.
157+
*/
158+
name?: string
159+
154160
/**
155161
* Use a fixed extension for output files.
156162
* The extension will always be `.cjs` or `.mjs`.
@@ -330,6 +336,7 @@ export type ResolvedOptions = Omit<
330336
| 'removeNodeProtocol'
331337
| 'copy'
332338
| 'loader'
339+
| 'name'
333340
>,
334341
{
335342
format: NormalizedFormat[]
@@ -452,19 +459,21 @@ async function resolveConfig(
452459
publicDir,
453460
hash,
454461
cwd = process.cwd(),
462+
name,
455463
} = userConfig
456464

457465
outDir = path.resolve(cwd, outDir)
458466
clean = resolveClean(clean, outDir, cwd)
459467

460468
const pkg = await readPackageJson(cwd)
461-
entry = await resolveEntry(entry, cwd)
469+
name ||= pkg?.name
470+
entry = await resolveEntry(entry, cwd, name)
462471
if (dts == null) {
463472
dts = !!(pkg?.types || pkg?.typings)
464473
}
465-
target = resolveTarget(target, pkg)
474+
target = resolveTarget(target, pkg, name)
475+
tsconfig = await resolveTsconfig(tsconfig, cwd, name)
466476

467-
tsconfig = await resolveTsconfig(tsconfig, cwd)
468477
if (publint === true) publint = {}
469478

470479
if (publicDir) {
@@ -532,6 +541,7 @@ async function resolveConfig(
532541
pkg,
533542
copy: publicDir || copy,
534543
hash: hash ?? true,
544+
name,
535545
}
536546

537547
return config

src/utils/format.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
export function formatBytes(bytes: number): string {
2-
if (bytes === Infinity) {
3-
return 'too large'
4-
}
1+
export function formatBytes(bytes: number): string | undefined {
2+
if (bytes === Infinity) return undefined
53
const numberFormatter = new Intl.NumberFormat('en', {
64
maximumFractionDigits: 2,
75
minimumFractionDigits: 2,

0 commit comments

Comments
 (0)