Skip to content

Commit 281cade

Browse files
ocavuesxzz
andauthored
feat!: remove inputAlias option, enforce use of input option (#12)
Co-authored-by: 三咲智子 Kevin Deng <sxzz@sxzz.moe>
1 parent 7c8b361 commit 281cade

8 files changed

Lines changed: 149 additions & 70 deletions

File tree

README.md

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ You can find a real demo in [here](./rolldown.config.ts).
2929

3030
## Options
3131

32-
````ts
32+
```ts
3333
interface Options {
3434
/**
3535
* When entries are `.d.ts` files (instead of `.ts` files), this option should be set to `true`.
@@ -58,21 +58,11 @@ interface Options {
5858
* This option is enabled when `isolatedDeclaration` in `tsconfig.json` is set to `true`.
5959
*/
6060
isolatedDeclaration?: boolean | Omit<IsolatedDeclarationsOptions, 'sourcemap'>
61-
/**
62-
* dts file name alias `{ [filename]: path }`
63-
*
64-
* @example
65-
* ```ts
66-
* inputAlias: {
67-
* 'foo.d.ts': 'foo/index.d.ts',
68-
* }
69-
*/
70-
inputAlias?: Record<string, string>
7161

7262
/** Resolve external types used in dts files from `node_modules` */
7363
resolve?: boolean | (string | RegExp)[]
7464
}
75-
````
65+
```
7666

7767
## Differences from `rollup-plugin-dts`
7868

src/generate.ts

Lines changed: 23 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { basename, extname } from 'node:path'
1+
import path from 'node:path'
2+
import process from 'node:process'
23
import { createResolver } from 'dts-resolver'
34
import { getTsconfig } from 'get-tsconfig'
45
import { isolatedDeclaration as oxcIsolatedDeclaration } from 'oxc-transform'
@@ -25,25 +26,27 @@ const meta = { dtsFile: true } as const
2526
export function createGeneratePlugin({
2627
compilerOptions,
2728
isolatedDeclaration,
28-
inputAlias,
2929
resolve = false,
3030
emitDtsOnly = false,
3131
}: Pick<
3232
Options,
33-
| 'isolatedDeclaration'
34-
| 'inputAlias'
35-
| 'resolve'
36-
| 'emitDtsOnly'
37-
| 'compilerOptions'
33+
'isolatedDeclaration' | 'resolve' | 'emitDtsOnly' | 'compilerOptions'
3834
>): Plugin {
3935
const dtsMap = new Map<string, { code: string; src: string }>()
40-
const inputAliasMap = new Map<string, string>(
41-
inputAlias && Object.entries(inputAlias),
42-
)
36+
37+
/**
38+
* A map of input id to output file name
39+
*
40+
* @example
41+
*
42+
* inputAlias = new Map([
43+
* ['/absolute/path/to/src/source_file.ts', 'dist/foo/index'],
44+
* ])
45+
*/
46+
const inputAliasMap = new Map<string, string>()
4347
const resolver = createResolver()
4448
let programs: TsProgram[] = []
4549

46-
let inputOption: Record<string, string> | undefined
4750
return {
4851
name: 'rolldown-plugin-dts:generate',
4952

@@ -60,11 +63,13 @@ export function createGeneratePlugin({
6063
if (!isolatedDeclaration) {
6164
initTs()
6265
}
63-
},
6466

65-
options({ input }) {
66-
if (isPlainObject(input)) {
67-
inputOption = { ...input }
67+
if (!Array.isArray(options.input)) {
68+
const cwd = options.cwd || process.cwd()
69+
for (const [fileName, inputFilePath] of Object.entries(options.input)) {
70+
const id = path.resolve(cwd, inputFilePath)
71+
inputAliasMap.set(id, fileName)
72+
}
6873
}
6974
},
7075

@@ -138,16 +143,11 @@ export function createGeneratePlugin({
138143
})
139144

140145
if (isEntry) {
141-
let name: string | undefined = basename(dtsId, extname(dtsId))
142-
if (inputAliasMap.has(name)) {
143-
name = inputAliasMap.get(name)!
144-
} else if (inputAliasMap.has(dtsId)) {
145-
name = inputAliasMap.get(dtsId)!
146-
}
146+
const name = inputAliasMap.get(id)
147147
this.emitFile({
148148
type: 'chunk',
149149
id: dtsId,
150-
name,
150+
name: name ? `${name}.d` : undefined,
151151
})
152152

153153
if (emitDtsOnly) {
@@ -157,7 +157,7 @@ export function createGeneratePlugin({
157157
},
158158
},
159159

160-
async resolveId(id, importer, extraOptions) {
160+
async resolveId(id, importer) {
161161
// must be entry
162162
if (dtsMap.has(id)) {
163163
return { id, meta }
@@ -201,22 +201,6 @@ export function createGeneratePlugin({
201201
if (dtsMap.has(dtsId)) {
202202
return { id: dtsId, meta }
203203
}
204-
} else if (extraOptions.isEntry && inputOption) {
205-
// mapping entry point to dts filename
206-
const resolution = await this.resolve(id, importer, extraOptions)
207-
if (!resolution) return
208-
209-
const dtsId = filename_ts_to_dts(resolution.id)
210-
if (inputAliasMap.has(dtsId)) return resolution
211-
212-
for (const [name, entry] of Object.entries(inputOption)) {
213-
if (entry === id) {
214-
inputAliasMap.set(dtsId, `${name}.d.ts`)
215-
break
216-
}
217-
}
218-
219-
return resolution
220204
}
221205
},
222206

@@ -252,12 +236,3 @@ export function createGeneratePlugin({
252236
},
253237
}
254238
}
255-
256-
function isPlainObject(data: unknown): data is Record<PropertyKey, unknown> {
257-
if (typeof data !== 'object' || data === null) {
258-
return false
259-
}
260-
261-
const proto = Object.getPrototypeOf(data)
262-
return proto === null || proto === Object.prototype
263-
}

src/index.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,6 @@ export interface Options {
3131
* This option is enabled when `isolatedDeclaration` in `tsconfig.json` is set to `true`.
3232
*/
3333
isolatedDeclaration?: boolean | Omit<IsolatedDeclarationsOptions, 'sourcemap'>
34-
/**
35-
* dts file name alias `{ [filename]: path }`
36-
*
37-
* @example
38-
* ```ts
39-
* inputAlias: {
40-
* 'foo.d.ts': 'foo/index.d.ts',
41-
* }
42-
*/
43-
inputAlias?: Record<string, string>
4434

4535
/** Resolve external types used in dts files from `node_modules` */
4636
resolve?: boolean | (string | RegExp)[]

tests/__snapshots__/index.test.ts.snap

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,69 @@
11
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
22

3+
exports[`input alias 1`] = `
4+
"// input2-eM-jH71Q.js
5+
6+
//#region shared.ts
7+
const shared = { shared: "shared" };
8+
9+
//#endregion
10+
//#region input2.ts
11+
const input2 = {
12+
...shared,
13+
input2: "input2"
14+
};
15+
16+
//#endregion
17+
export { input2 };
18+
// input2.d-D6mB_nrs.d.ts
19+
20+
//#region shared.d.ts
21+
interface Shared {
22+
shared: string;
23+
}
24+
declare const shared: Shared;
25+
26+
//#endregion
27+
//#region input2.d.ts
28+
interface Input2 extends Shared {
29+
input2: string;
30+
}
31+
declare const input2: Input2;
32+
33+
//#endregion
34+
export { Input2, input2 as input2$1 };
35+
// output1.d.ts
36+
import { Input2 } from "./input2.d-D6mB_nrs.js";
37+
38+
//#region input1.d.ts
39+
interface Input1 extends Input2 {
40+
input1: string;
41+
}
42+
declare const input1: Input1;
43+
44+
//#endregion
45+
export { Input1, input1 };
46+
// output1.js
47+
import { input2 } from "./input2-eM-jH71Q.js";
48+
49+
//#region input1.ts
50+
const input1 = {
51+
...input2,
52+
input1: "input1"
53+
};
54+
55+
//#endregion
56+
export { input1 };
57+
// output2/index.d.ts
58+
import { Input2, input2$1 as input2 } from "../input2.d-D6mB_nrs.js";
59+
60+
export { Input2, input2 };
61+
// output2/index.js
62+
import { input2 } from "../input2-eM-jH71Q.js";
63+
64+
export { input2 };"
65+
`;
66+
367
exports[`resolve dependencies 1`] = `
468
"// resolve-dep.d.ts
569
import MagicString, { MagicStringOptions, OverwriteOptions } from "magic-string";

tests/fixtures/alias/input1.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Input2, input2 } from './input2'
2+
3+
export interface Input1 extends Input2 {
4+
input1: string
5+
}
6+
7+
export const input1: Input1 = {
8+
...input2,
9+
input1: 'input1',
10+
}

tests/fixtures/alias/input2.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Shared, shared } from './shared'
2+
3+
export interface Input2 extends Shared {
4+
input2: string
5+
}
6+
7+
export const input2: Input2 = {
8+
...shared,
9+
input2: 'input2',
10+
}

tests/fixtures/alias/shared.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export interface Shared {
2+
shared: string
3+
}
4+
5+
export const shared: Shared = {
6+
shared: 'shared',
7+
}

tests/index.test.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,39 @@ test('resolve dependencies', async () => {
3838
expect(snapshot).toMatchSnapshot()
3939
})
4040

41+
// Test alias mapping based on rolldown input option
42+
test('input alias', async () => {
43+
const root = path.resolve(dirname, 'fixtures/alias')
44+
const { snapshot, chunks } = await rolldownBuild(
45+
null!,
46+
[
47+
dts({
48+
emitDtsOnly: false, // Generate both JS and DTS files
49+
compilerOptions: {},
50+
isolatedDeclaration: false,
51+
}),
52+
],
53+
{
54+
cwd: root,
55+
// A mapping from output chunk names to input files. This mapping should
56+
// be used in both JS and DTS outputs.
57+
input: {
58+
output1: 'input1.ts',
59+
'output2/index': 'input2.ts',
60+
},
61+
},
62+
)
63+
const fileNames = chunks.map((chunk) => chunk.fileName).sort()
64+
65+
// The JS output and DTS output should have the same structure
66+
expect(fileNames).toContain('output1.d.ts')
67+
expect(fileNames).toContain('output1.js')
68+
expect(fileNames).toContain('output2/index.d.ts')
69+
expect(fileNames).toContain('output2/index.js')
70+
71+
expect(snapshot).toMatchSnapshot()
72+
})
73+
4174
test('isolated declaration error', async () => {
4275
const error = await rolldownBuild(
4376
path.resolve(dirname, 'fixtures/isolated-decl-error.ts'),

0 commit comments

Comments
 (0)