Skip to content

Commit 0d8bd49

Browse files
committed
Fix experimentalDts for Node16/NodeNext module resolution
1 parent db7a022 commit 0d8bd49

File tree

4 files changed

+169
-72
lines changed

4 files changed

+169
-72
lines changed

src/exports.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import path from 'node:path'
2-
import { slash, trimDtsExtension, truthy } from './utils'
2+
import { replaceDtsWithJsExtensions, slash, truthy } from './utils'
33

44
export type ExportDeclaration = ModuleExport | NamedExport
55

@@ -41,14 +41,14 @@ function formatAggregationExport(
4141
declaration: ExportDeclaration,
4242
declarationDirPath: string,
4343
): string {
44-
const dest = trimDtsExtension(
44+
const dest = replaceDtsWithJsExtensions(
4545
`./${path.posix.normalize(
4646
slash(path.relative(declarationDirPath, declaration.destFileName)),
4747
)}`,
4848
)
4949

5050
if (declaration.kind === 'module') {
51-
// No implemeted
51+
// No implemented
5252
return ''
5353
} else if (declaration.kind === 'named') {
5454
return [
@@ -72,7 +72,7 @@ export function formatDistributionExports(
7272
fromFilePath: string,
7373
toFilePath: string,
7474
) {
75-
let importPath = trimDtsExtension(
75+
let importPath = replaceDtsWithJsExtensions(
7676
path.posix.relative(
7777
path.posix.dirname(path.posix.normalize(slash(fromFilePath))),
7878
path.posix.normalize(slash(toFilePath)),

src/utils.ts

+28
Original file line numberDiff line numberDiff line change
@@ -242,3 +242,31 @@ export function writeFileSync(filePath: string, content: string) {
242242
fs.mkdirSync(path.dirname(filePath), { recursive: true })
243243
fs.writeFileSync(filePath, content)
244244
}
245+
246+
/**
247+
* Replaces TypeScript declaration file
248+
* extensions (`.d.ts`, `.d.mts`, `.d.cts`)
249+
* with their corresponding JavaScript variants (`.js`, `.mjs`, `.cjs`).
250+
*
251+
* @param dtsFilePath - The file path to be transformed.
252+
* @returns The updated file path with the JavaScript extension.
253+
*
254+
* @internal
255+
*/
256+
export function replaceDtsWithJsExtensions(dtsFilePath: string) {
257+
return dtsFilePath.replace(
258+
/\.d\.(ts|mts|cts)$/,
259+
(_, fileExtension: string) => {
260+
switch (fileExtension) {
261+
case 'ts':
262+
return '.js'
263+
case 'mts':
264+
return '.mjs'
265+
case 'cts':
266+
return '.cjs'
267+
default:
268+
return ''
269+
}
270+
},
271+
)
272+
}

test/__snapshots__/dts.test.ts.snap

+60-60
Original file line numberDiff line numberDiff line change
@@ -234,95 +234,95 @@ export { }
234234
// dist/index.d.mts
235235
//////////////////////////////////////////////////////////////////////
236236
237-
export { VERSION } from './_tsup-dts-rollup';
238-
export { render_alias_1 as render } from './_tsup-dts-rollup';
239-
export { ClientRenderOptions_alias_1 as ClientRenderOptions } from './_tsup-dts-rollup';
240-
export { sharedFunction_alias_1 as sharedFunction } from './_tsup-dts-rollup';
241-
export { sharedType_alias_1 as sharedType } from './_tsup-dts-rollup';
237+
export { VERSION } from './_tsup-dts-rollup.mjs';
238+
export { render_alias_1 as render } from './_tsup-dts-rollup.mjs';
239+
export { ClientRenderOptions_alias_1 as ClientRenderOptions } from './_tsup-dts-rollup.mjs';
240+
export { sharedFunction_alias_1 as sharedFunction } from './_tsup-dts-rollup.mjs';
241+
export { sharedType_alias_1 as sharedType } from './_tsup-dts-rollup.mjs';
242242
243243
244244
//////////////////////////////////////////////////////////////////////
245245
// dist/index.d.ts
246246
//////////////////////////////////////////////////////////////////////
247247
248-
export { VERSION } from './_tsup-dts-rollup';
249-
export { render_alias_1 as render } from './_tsup-dts-rollup';
250-
export { ClientRenderOptions_alias_1 as ClientRenderOptions } from './_tsup-dts-rollup';
251-
export { sharedFunction_alias_1 as sharedFunction } from './_tsup-dts-rollup';
252-
export { sharedType_alias_1 as sharedType } from './_tsup-dts-rollup';
248+
export { VERSION } from './_tsup-dts-rollup.js';
249+
export { render_alias_1 as render } from './_tsup-dts-rollup.js';
250+
export { ClientRenderOptions_alias_1 as ClientRenderOptions } from './_tsup-dts-rollup.js';
251+
export { sharedFunction_alias_1 as sharedFunction } from './_tsup-dts-rollup.js';
252+
export { sharedType_alias_1 as sharedType } from './_tsup-dts-rollup.js';
253253
254254
255255
//////////////////////////////////////////////////////////////////////
256256
// dist/my-lib-client.d.mts
257257
//////////////////////////////////////////////////////////////////////
258258
259-
export { render } from './_tsup-dts-rollup';
260-
export { ClientRenderOptions } from './_tsup-dts-rollup';
261-
export { sharedFunction } from './_tsup-dts-rollup';
262-
export { sharedType } from './_tsup-dts-rollup';
259+
export { render } from './_tsup-dts-rollup.mjs';
260+
export { ClientRenderOptions } from './_tsup-dts-rollup.mjs';
261+
export { sharedFunction } from './_tsup-dts-rollup.mjs';
262+
export { sharedType } from './_tsup-dts-rollup.mjs';
263263
264264
265265
//////////////////////////////////////////////////////////////////////
266266
// dist/my-lib-client.d.ts
267267
//////////////////////////////////////////////////////////////////////
268268
269-
export { render } from './_tsup-dts-rollup';
270-
export { ClientRenderOptions } from './_tsup-dts-rollup';
271-
export { sharedFunction } from './_tsup-dts-rollup';
272-
export { sharedType } from './_tsup-dts-rollup';
269+
export { render } from './_tsup-dts-rollup.js';
270+
export { ClientRenderOptions } from './_tsup-dts-rollup.js';
271+
export { sharedFunction } from './_tsup-dts-rollup.js';
272+
export { sharedType } from './_tsup-dts-rollup.js';
273273
274274
275275
//////////////////////////////////////////////////////////////////////
276276
// dist/server/index.d.mts
277277
//////////////////////////////////////////////////////////////////////
278278
279-
export { render_alias_2 as render } from '../_tsup-dts-rollup';
280-
export { default_alias as default } from '../_tsup-dts-rollup';
281-
export { ServerRenderOptions } from '../_tsup-dts-rollup';
282-
export { serverConstant } from '../_tsup-dts-rollup';
283-
export { serverConstantAlias } from '../_tsup-dts-rollup';
284-
export { ServerClass } from '../_tsup-dts-rollup';
285-
export { ServerThirdPartyNamespace } from '../_tsup-dts-rollup';
286-
export { sharedFunction_alias_2 as sharedFunction } from '../_tsup-dts-rollup';
287-
export { sharedType_alias_2 as sharedType } from '../_tsup-dts-rollup';
288-
export { renderToPipeableStream } from '../_tsup-dts-rollup';
289-
export { renderToString } from '../_tsup-dts-rollup';
290-
export { renderToNodeStream } from '../_tsup-dts-rollup';
291-
export { renderToStaticMarkup } from '../_tsup-dts-rollup';
292-
export { renderToStaticNodeStream } from '../_tsup-dts-rollup';
293-
export { renderToReadableStream } from '../_tsup-dts-rollup';
294-
export { RenderToPipeableStreamOptions } from '../_tsup-dts-rollup';
295-
export { PipeableStream } from '../_tsup-dts-rollup';
296-
export { ServerOptions } from '../_tsup-dts-rollup';
297-
export { RenderToReadableStreamOptions } from '../_tsup-dts-rollup';
298-
export { ReactDOMServerReadableStream } from '../_tsup-dts-rollup';
299-
export { version } from '../_tsup-dts-rollup';
279+
export { render_alias_2 as render } from '../_tsup-dts-rollup.mjs';
280+
export { default_alias as default } from '../_tsup-dts-rollup.mjs';
281+
export { ServerRenderOptions } from '../_tsup-dts-rollup.mjs';
282+
export { serverConstant } from '../_tsup-dts-rollup.mjs';
283+
export { serverConstantAlias } from '../_tsup-dts-rollup.mjs';
284+
export { ServerClass } from '../_tsup-dts-rollup.mjs';
285+
export { ServerThirdPartyNamespace } from '../_tsup-dts-rollup.mjs';
286+
export { sharedFunction_alias_2 as sharedFunction } from '../_tsup-dts-rollup.mjs';
287+
export { sharedType_alias_2 as sharedType } from '../_tsup-dts-rollup.mjs';
288+
export { renderToPipeableStream } from '../_tsup-dts-rollup.mjs';
289+
export { renderToString } from '../_tsup-dts-rollup.mjs';
290+
export { renderToNodeStream } from '../_tsup-dts-rollup.mjs';
291+
export { renderToStaticMarkup } from '../_tsup-dts-rollup.mjs';
292+
export { renderToStaticNodeStream } from '../_tsup-dts-rollup.mjs';
293+
export { renderToReadableStream } from '../_tsup-dts-rollup.mjs';
294+
export { RenderToPipeableStreamOptions } from '../_tsup-dts-rollup.mjs';
295+
export { PipeableStream } from '../_tsup-dts-rollup.mjs';
296+
export { ServerOptions } from '../_tsup-dts-rollup.mjs';
297+
export { RenderToReadableStreamOptions } from '../_tsup-dts-rollup.mjs';
298+
export { ReactDOMServerReadableStream } from '../_tsup-dts-rollup.mjs';
299+
export { version } from '../_tsup-dts-rollup.mjs';
300300
301301
302302
//////////////////////////////////////////////////////////////////////
303303
// dist/server/index.d.ts
304304
//////////////////////////////////////////////////////////////////////
305305
306-
export { render_alias_2 as render } from '../_tsup-dts-rollup';
307-
export { default_alias as default } from '../_tsup-dts-rollup';
308-
export { ServerRenderOptions } from '../_tsup-dts-rollup';
309-
export { serverConstant } from '../_tsup-dts-rollup';
310-
export { serverConstantAlias } from '../_tsup-dts-rollup';
311-
export { ServerClass } from '../_tsup-dts-rollup';
312-
export { ServerThirdPartyNamespace } from '../_tsup-dts-rollup';
313-
export { sharedFunction_alias_2 as sharedFunction } from '../_tsup-dts-rollup';
314-
export { sharedType_alias_2 as sharedType } from '../_tsup-dts-rollup';
315-
export { renderToPipeableStream } from '../_tsup-dts-rollup';
316-
export { renderToString } from '../_tsup-dts-rollup';
317-
export { renderToNodeStream } from '../_tsup-dts-rollup';
318-
export { renderToStaticMarkup } from '../_tsup-dts-rollup';
319-
export { renderToStaticNodeStream } from '../_tsup-dts-rollup';
320-
export { renderToReadableStream } from '../_tsup-dts-rollup';
321-
export { RenderToPipeableStreamOptions } from '../_tsup-dts-rollup';
322-
export { PipeableStream } from '../_tsup-dts-rollup';
323-
export { ServerOptions } from '../_tsup-dts-rollup';
324-
export { RenderToReadableStreamOptions } from '../_tsup-dts-rollup';
325-
export { ReactDOMServerReadableStream } from '../_tsup-dts-rollup';
326-
export { version } from '../_tsup-dts-rollup';
306+
export { render_alias_2 as render } from '../_tsup-dts-rollup.js';
307+
export { default_alias as default } from '../_tsup-dts-rollup.js';
308+
export { ServerRenderOptions } from '../_tsup-dts-rollup.js';
309+
export { serverConstant } from '../_tsup-dts-rollup.js';
310+
export { serverConstantAlias } from '../_tsup-dts-rollup.js';
311+
export { ServerClass } from '../_tsup-dts-rollup.js';
312+
export { ServerThirdPartyNamespace } from '../_tsup-dts-rollup.js';
313+
export { sharedFunction_alias_2 as sharedFunction } from '../_tsup-dts-rollup.js';
314+
export { sharedType_alias_2 as sharedType } from '../_tsup-dts-rollup.js';
315+
export { renderToPipeableStream } from '../_tsup-dts-rollup.js';
316+
export { renderToString } from '../_tsup-dts-rollup.js';
317+
export { renderToNodeStream } from '../_tsup-dts-rollup.js';
318+
export { renderToStaticMarkup } from '../_tsup-dts-rollup.js';
319+
export { renderToStaticNodeStream } from '../_tsup-dts-rollup.js';
320+
export { renderToReadableStream } from '../_tsup-dts-rollup.js';
321+
export { RenderToPipeableStreamOptions } from '../_tsup-dts-rollup.js';
322+
export { PipeableStream } from '../_tsup-dts-rollup.js';
323+
export { ServerOptions } from '../_tsup-dts-rollup.js';
324+
export { RenderToReadableStreamOptions } from '../_tsup-dts-rollup.js';
325+
export { ReactDOMServerReadableStream } from '../_tsup-dts-rollup.js';
326+
export { version } from '../_tsup-dts-rollup.js';
327327
"
328328
`;

test/dts.test.ts

+77-8
Original file line numberDiff line numberDiff line change
@@ -258,29 +258,29 @@ test('should emit declaration files with experimentalDts', async () => {
258258
export function sharedFunction<T>(value: T): T | null {
259259
return value || null
260260
}
261-
261+
262262
type sharedType = {
263263
shared: boolean
264264
}
265-
265+
266266
export type { sharedType }
267267
`,
268268
'src/server.ts': `
269269
export * from './shared'
270270
271271
/**
272-
* Comment for server render function
272+
* Comment for server render function
273273
*/
274274
export function render(options: ServerRenderOptions): string {
275275
return JSON.stringify(options)
276276
}
277-
277+
278278
export interface ServerRenderOptions {
279279
/**
280280
* Comment for ServerRenderOptions.stream
281-
*
281+
*
282282
* @public
283-
*
283+
*
284284
* @my_custom_tag
285285
*/
286286
stream: boolean
@@ -298,7 +298,7 @@ test('should emit declaration files with experimentalDts', async () => {
298298
import * as ServerThirdPartyNamespace from 'react-dom';
299299
export { ServerThirdPartyNamespace }
300300
301-
// Export a third party module
301+
// Export a third party module
302302
export * from 'react-dom/server';
303303
304304
`,
@@ -308,7 +308,7 @@ test('should emit declaration files with experimentalDts', async () => {
308308
export function render(options: ClientRenderOptions): string {
309309
return JSON.stringify(options)
310310
}
311-
311+
312312
export interface ClientRenderOptions {
313313
document: boolean
314314
}
@@ -473,3 +473,72 @@ test('declaration files with multiple entrypoints #316', async () => {
473473
'dist/bar/index.d.ts',
474474
).toMatchSnapshot()
475475
})
476+
477+
test.for([
478+
{ moduleResolution: 'NodeNext', module: 'NodeNext' },
479+
{ moduleResolution: 'Node16', module: 'Node16' },
480+
{ moduleResolution: 'Bundler', module: 'ESNext' },
481+
{ moduleResolution: 'Bundler', module: 'Preserve' },
482+
{ moduleResolution: 'Node10', module: 'ESNext' },
483+
{ moduleResolution: 'Node10', module: 'CommonJS' },
484+
{ moduleResolution: 'Node', module: 'ESNext' },
485+
{ moduleResolution: 'Node', module: 'CommonJS' },
486+
])(
487+
"experimentalDts works with TypeScript's $moduleResolution module resolution and module set to $module",
488+
async ({ moduleResolution, module }, { expect }) => {
489+
const { getFileContent, outFiles } = await run(
490+
getTestName(),
491+
{
492+
'src/index.ts': `export const foo = [1, 2, 3]`,
493+
'tsup.config.ts': `export default {
494+
entry: { index: 'src/index.ts' },
495+
format: ['esm', 'cjs'],
496+
experimentalDts: true,
497+
}`,
498+
'package.json': JSON.stringify({
499+
name: 'testing-experimental-dts',
500+
type: 'module',
501+
}),
502+
'tsconfig.json': JSON.stringify({
503+
compilerOptions: {
504+
module,
505+
moduleResolution,
506+
outDir: './dist',
507+
rootDir: './src',
508+
skipLibCheck: true,
509+
strict: true,
510+
},
511+
include: ['src'],
512+
}),
513+
},
514+
{
515+
entry: [],
516+
},
517+
)
518+
519+
expect(outFiles).toStrictEqual([
520+
'_tsup-dts-rollup.d.cts',
521+
'_tsup-dts-rollup.d.ts',
522+
'index.cjs',
523+
'index.d.cts',
524+
'index.d.ts',
525+
'index.js',
526+
])
527+
528+
expect(await getFileContent('dist/index.d.ts')).toStrictEqual(
529+
`export { foo } from './_tsup-dts-rollup.js';\n`,
530+
)
531+
532+
expect(await getFileContent('dist/index.d.cts')).toStrictEqual(
533+
`export { foo } from './_tsup-dts-rollup.cjs';\n`,
534+
)
535+
536+
expect(await getFileContent('dist/_tsup-dts-rollup.d.cts')).toStrictEqual(
537+
`export declare const foo: number[];\r\n\r\nexport { }\r\n`,
538+
)
539+
540+
expect(await getFileContent('dist/_tsup-dts-rollup.d.ts')).toStrictEqual(
541+
`export declare const foo: number[];\r\n\r\nexport { }\r\n`,
542+
)
543+
},
544+
)

0 commit comments

Comments
 (0)