Skip to content

Commit 7fb7286

Browse files
Joery-Mautofix-ci[bot]sxzz
authored
feat(exports): support object option for customExports (#769)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Kevin Deng <[email protected]>
1 parent 530668f commit 7fb7286

File tree

6 files changed

+96
-17
lines changed

6 files changed

+96
-17
lines changed

docs/options/package-exports.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,17 @@ The CSS filename defaults to `style.css` and can be customized via `css.fileName
8080

8181
## Customizing Exports
8282

83-
If you need more control over the generated exports, you can provide a custom function via `exports.customExports`:
83+
If you need more control over the generated exports, you can provide an object or a custom function via `exports.customExports`:
84+
85+
```ts
86+
export default defineConfig({
87+
exports: {
88+
customExports: {
89+
'./foo': './foo.js',
90+
},
91+
},
92+
})
93+
```
8494

8595
```ts
8696
export default defineConfig({

docs/zh-CN/options/package-exports.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,17 @@ CSS 文件名默认为 `style.css`,可通过 `css.fileName` 自定义。
8080

8181
## 自定义导出
8282

83-
如果您需要对生成的导出字段进行更细致的控制,可以通过 `exports.customExports` 提供自定义函数:
83+
如果您需要对生成的导出字段进行更细致的控制,可以通过 `exports.customExports` 提供一个对象或自定义函数:
84+
85+
```ts
86+
export default defineConfig({
87+
exports: {
88+
customExports: {
89+
'./foo': './foo.js',
90+
},
91+
},
92+
})
93+
```
8494

8595
```ts
8696
export default defineConfig({

dts.snapshot.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@
7070
"resolveUserConfig": "declare function resolveUserConfig(_: UserConfig, _: InlineConfig): Promise<ResolvedConfig[]>"
7171
},
7272
"plugins.d.mts": {
73-
"DepPlugin": "declare function DepPlugin(_: ResolvedConfig): Plugin",
7473
"NodeProtocolPlugin": "declare function NodeProtocolPlugin(_: 'strip' | true): Plugin",
7574
"ShebangPlugin": "declare function ShebangPlugin(_: Logger, _: string, _: string, _: boolean): Plugin",
7675
"WatchPlugin": "declare function WatchPlugin(_: string[], _: TsdownBundle): Plugin",
@@ -99,9 +98,10 @@
9998
"CopyOptions": "type CopyOptions = Arrayable<string | CopyEntry>",
10099
"CopyOptionsFn": "type CopyOptionsFn = (_: ResolvedConfig) => Awaitable<CopyOptions>",
101100
"CssOptions": "interface CssOptions {\n splitting?: boolean\n fileName?: string\n}",
101+
"DepPlugin": "declare function DepPlugin(_: ResolvedConfig): Plugin",
102102
"DepsConfig": "interface DepsConfig {\n neverBundle?: ExternalOption\n alwaysBundle?: Arrayable<string | RegExp> | NoExternalFn\n onlyAllowBundle?: Arrayable<string | RegExp> | false\n skipNodeModulesBundle?: boolean\n}",
103103
"DevtoolsOptions": "interface DevtoolsOptions extends NonNullable<InputOptions['devtools']> {\n ui?: boolean | Partial<StartOptions>\n clean?: boolean\n}",
104-
"ExportsOptions": "interface ExportsOptions {\n devExports?: boolean | string\n packageJson?: boolean\n all?: boolean\n exclude?: (RegExp | string)[]\n legacy?: boolean\n customExports?: (_: Record<string, any>, _: { pkg: PackageJson; chunks: ChunksByFormat; isPublish: boolean }) => Awaitable<Record<string, any>>\n}",
104+
"ExportsOptions": "interface ExportsOptions {\n devExports?: boolean | string\n packageJson?: boolean\n all?: boolean\n exclude?: (RegExp | string)[]\n legacy?: boolean\n customExports?: Record<string, any> | ((_: Record<string, any>, _: { pkg: PackageJson; chunks: ChunksByFormat; isPublish: boolean }) => Awaitable<Record<string, any>>)\n}",
105105
"Format": "type Format = ModuleFormat",
106106
"globalLogger": "Logger",
107107
"InlineConfig": "interface InlineConfig extends UserConfig {\n config?: boolean | string\n configLoader?: 'auto' | 'native' | 'unrun'\n filter?: RegExp | Arrayable<string>\n}",

src/features/pkg/exports.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,38 @@ describe('generateExports', () => {
280280
`)
281281
})
282282

283+
test('customExports via object', async ({ expect }) => {
284+
const results = await generateExports(
285+
{ es: [genChunk('index.js')] },
286+
{
287+
exports: {
288+
devExports: 'dev',
289+
customExports: {
290+
'./TEST': './TEST',
291+
},
292+
},
293+
},
294+
)
295+
// key order matters
296+
expect(JSON.stringify(results, undefined, 2)).toMatchInlineSnapshot(`
297+
"{
298+
"exports": {
299+
".": {
300+
"dev": "./SRC/index.js",
301+
"default": "./index.js"
302+
},
303+
"./package.json": "./package.json",
304+
"./TEST": "./TEST"
305+
},
306+
"publishExports": {
307+
".": "./index.js",
308+
"./package.json": "./package.json",
309+
"./TEST": "./TEST"
310+
}
311+
}"
312+
`)
313+
})
314+
283315
test('exclude via regex', async ({ expect }) => {
284316
const results = generateExports(
285317
{ es: [genChunk('index.js'), genChunk('foo.js'), genChunk('bar.js')] },

src/features/pkg/exports.ts

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,38 @@ export interface ExportsOptions {
5757
*/
5858
legacy?: boolean
5959

60-
customExports?: (
61-
exports: Record<string, any>,
62-
context: {
63-
pkg: PackageJson
64-
chunks: ChunksByFormat
65-
isPublish: boolean
66-
},
67-
) => Awaitable<Record<string, any>>
60+
/**
61+
* Specifies custom exports to add to the package exports in addition to the ones generated by tsdown.
62+
* Use this to add additional exports in the exported package, such as workers or assets.
63+
*
64+
* @example
65+
* customExports(exports) {
66+
* exports['./worker.js'] = './dist/worker.js';
67+
* return exports;
68+
* }
69+
*
70+
* @example
71+
* ```jsonc
72+
* {
73+
* "customExports": {
74+
* "./worker.js": {
75+
* "types": "./dist/worker.d.ts",
76+
* "default": "./dist/worker.js"
77+
* }
78+
* }
79+
* }
80+
* ```
81+
*/
82+
customExports?:
83+
| Record<string, any>
84+
| ((
85+
exports: Record<string, any>,
86+
context: {
87+
pkg: PackageJson
88+
chunks: ChunksByFormat
89+
isPublish: boolean
90+
},
91+
) => Awaitable<Record<string, any>>)
6892
}
6993

7094
export async function writeExports(
@@ -228,7 +252,9 @@ export async function generateExports(
228252
)
229253
exportMeta(exports, all, packageJson)
230254
exportCss(exports, chunks, css, pkgRoot)
231-
if (customExports) {
255+
if (typeof customExports === 'object') {
256+
exports = { ...exports, ...customExports }
257+
} else if (typeof customExports === 'function') {
232258
exports = await customExports(exports, {
233259
pkg,
234260
chunks,
@@ -246,7 +272,9 @@ export async function generateExports(
246272
)
247273
exportMeta(publishExports, all, packageJson)
248274
exportCss(publishExports, chunks, css, pkgRoot)
249-
if (customExports) {
275+
if (typeof customExports === 'object') {
276+
publishExports = { ...publishExports, ...customExports }
277+
} else if (typeof customExports === 'function') {
250278
publishExports = await customExports(publishExports, {
251279
pkg,
252280
chunks,

tsdown.config.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,8 @@ export default defineConfig([
3838
profile: 'esm-only',
3939
},
4040
exports: {
41-
customExports(exports) {
42-
exports['./client'] = './client.d.ts'
43-
return exports
41+
customExports: {
42+
'./client': './client.d.ts',
4443
},
4544
},
4645
plugins: [

0 commit comments

Comments
 (0)