Skip to content

Commit 5fee230

Browse files
committed
fix(dts): skip cjs dts reexport for non-entry chunks
1 parent 3f8de4c commit 5fee230

4 files changed

Lines changed: 183 additions & 26 deletions

File tree

src/features/cjs.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
import path from 'node:path'
2+
import { filename_js_to_dts, RE_JS } from 'rolldown-plugin-dts/internal'
13
import coerce from 'semver/functions/coerce.js'
24
import satisfies from 'semver/functions/satisfies.js'
35
import type { ResolvedConfig } from '../config/index.ts'
6+
import type { Plugin } from 'rolldown'
47

58
export function warnLegacyCJS(config: ResolvedConfig): void {
69
if (
@@ -26,3 +29,28 @@ export function warnLegacyCJS(config: ResolvedConfig): void {
2629
)
2730
}
2831
}
32+
33+
export function CjsDtsReexportPlugin(): Plugin {
34+
return {
35+
name: 'tsdown:cjs-dts-reexport',
36+
generateBundle(_options, bundle) {
37+
for (const chunk of Object.values(bundle)) {
38+
if (chunk.type !== 'chunk' || !chunk.isEntry) continue
39+
40+
if (!chunk.fileName.endsWith('.cjs') && !chunk.fileName.endsWith('.js'))
41+
continue
42+
43+
const dMtsBasename = path.basename(
44+
chunk.fileName.replace(RE_JS, '.d.mts'),
45+
)
46+
const content = `export type * from './${dMtsBasename}'\n`
47+
48+
this.emitFile({
49+
type: 'prebuilt-chunk',
50+
fileName: filename_js_to_dts(chunk.fileName),
51+
code: content,
52+
})
53+
}
54+
},
55+
}
56+
}

src/features/rolldown.ts

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ import {
1111
type Plugin,
1212
type RolldownPluginOption,
1313
} from 'rolldown'
14-
import { filename_js_to_dts, RE_JS } from 'rolldown-plugin-dts/internal'
1514
import { importGlobPlugin } from 'rolldown/experimental'
1615
import pkg from '../../package.json' with { type: 'json' }
1716
import { mergeUserOptions } from '../config/options.ts'
1817
import { importWithError, pkgExists } from '../utils/general.ts'
1918
import { LogLevels } from '../utils/logger.ts'
19+
import { CjsDtsReexportPlugin } from './cjs.ts'
2020
import { DepsPlugin } from './deps.ts'
2121
import { NodeProtocolPlugin } from './node-protocol.ts'
2222
import { resolveChunkAddon, resolveChunkFilename } from './output.ts'
@@ -343,31 +343,6 @@ function handlePluginInspect(plugins: RolldownPluginOption) {
343343
}
344344
}
345345

346-
export function CjsDtsReexportPlugin(): Plugin {
347-
return {
348-
name: 'tsdown:cjs-dts-reexport',
349-
generateBundle(_options, bundle) {
350-
for (const chunk of Object.values(bundle)) {
351-
if (chunk.type !== 'chunk') continue
352-
353-
if (!chunk.fileName.endsWith('.cjs') && !chunk.fileName.endsWith('.js'))
354-
continue
355-
356-
const dMtsBasename = path.basename(
357-
chunk.fileName.replace(RE_JS, '.d.mts'),
358-
)
359-
const content = `export type * from './${dMtsBasename}'\n`
360-
361-
this.emitFile({
362-
type: 'prebuilt-chunk',
363-
fileName: filename_js_to_dts(chunk.fileName),
364-
code: content,
365-
})
366-
}
367-
},
368-
}
369-
}
370-
371346
export function CssGuardPlugin(): Plugin {
372347
return {
373348
name: 'tsdown:css-guard',
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
## a.cjs
2+
3+
```cjs
4+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
5+
const require_shared = require("./shared-Ccciw35G.cjs");
6+
//#region a.ts
7+
const loadDynamic = () => Promise.resolve().then(() => require("./dynamic-wQmydOCv.cjs"));
8+
//#endregion
9+
exports.loadDynamic = loadDynamic;
10+
exports.shared = require_shared.shared;
11+
12+
```
13+
14+
## a.d.cts
15+
16+
```cts
17+
export type * from './a.d.mts'
18+
19+
```
20+
21+
## a.d.mts
22+
23+
```mts
24+
import { t as shared } from "./shared-BoxP0Nhj.mjs";
25+
26+
//#region \0rolldown/runtime.js
27+
declare namespace dynamic_d_exports {
28+
export { dynamic };
29+
}
30+
declare const dynamic = 2;
31+
//#endregion
32+
//#region a.d.ts
33+
declare const loadDynamic: () => Promise<typeof dynamic_d_exports>;
34+
//#endregion
35+
export { loadDynamic, shared };
36+
```
37+
38+
## a.mjs
39+
40+
```mjs
41+
import { t as shared } from "./shared-BVEkDxo-.mjs";
42+
//#region a.ts
43+
const loadDynamic = () => import("./dynamic-BUNvldLi.mjs");
44+
//#endregion
45+
export { loadDynamic, shared };
46+
47+
```
48+
49+
## b.cjs
50+
51+
```cjs
52+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
53+
const require_shared = require("./shared-Ccciw35G.cjs");
54+
exports.shared = require_shared.shared;
55+
56+
```
57+
58+
## b.d.cts
59+
60+
```cts
61+
export type * from './b.d.mts'
62+
63+
```
64+
65+
## b.d.mts
66+
67+
```mts
68+
import { t as shared } from "./shared-BoxP0Nhj.mjs";
69+
export { shared };
70+
```
71+
72+
## b.mjs
73+
74+
```mjs
75+
import { t as shared } from "./shared-BVEkDxo-.mjs";
76+
export { shared };
77+
78+
```
79+
80+
## dynamic-BUNvldLi.mjs
81+
82+
```mjs
83+
//#region dynamic.ts
84+
const dynamic = 2;
85+
//#endregion
86+
export { dynamic };
87+
88+
```
89+
90+
## dynamic-wQmydOCv.cjs
91+
92+
```cjs
93+
//#region dynamic.ts
94+
const dynamic = 2;
95+
//#endregion
96+
exports.dynamic = dynamic;
97+
98+
```
99+
100+
## shared-BVEkDxo-.mjs
101+
102+
```mjs
103+
//#region shared.ts
104+
const shared = 1;
105+
//#endregion
106+
export { shared as t };
107+
108+
```
109+
110+
## shared-BoxP0Nhj.d.mts
111+
112+
```mts
113+
//#region shared.d.ts
114+
declare const shared = 1;
115+
//#endregion
116+
export { shared as t };
117+
```
118+
119+
## shared-Ccciw35G.cjs
120+
121+
```cjs
122+
//#region shared.ts
123+
const shared = 1;
124+
//#endregion
125+
Object.defineProperty(exports, "shared", {
126+
enumerable: true,
127+
get: function() {
128+
return shared;
129+
}
130+
});
131+
132+
```

tests/issues.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,28 @@ button {
252252
expect(css).toMatch(/\[data-v-[\da-f]+\]/)
253253
})
254254

255+
test('#903', async (context) => {
256+
const { outputFiles } = await testBuild({
257+
context,
258+
files: {
259+
'a.ts': `export { shared } from './shared'
260+
export const loadDynamic = () => import('./dynamic')`,
261+
'b.ts': `export { shared } from './shared'`,
262+
'shared.ts': `export const shared = 1`,
263+
'dynamic.ts': `export const dynamic = 2`,
264+
},
265+
options: {
266+
entry: ['a.ts', 'b.ts'],
267+
format: ['cjs', 'esm'],
268+
dts: { cjsReexport: true },
269+
platform: 'node',
270+
},
271+
})
272+
expect(outputFiles.some((f) => /^chunk-.*\.d\.cts$/.test(f))).toBe(false)
273+
expect(outputFiles).toContain('a.d.cts')
274+
expect(outputFiles).toContain('b.d.cts')
275+
})
276+
255277
test('#772', async (context) => {
256278
const { fileMap, outputFiles } = await testBuild({
257279
context,

0 commit comments

Comments
 (0)