Skip to content

Commit 7c3319b

Browse files
committed
build: improve dts generation
1 parent 71635be commit 7c3319b

File tree

1 file changed

+72
-46
lines changed

1 file changed

+72
-46
lines changed

rollup.dts.config.js

Lines changed: 72 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,50 @@ export default readdirSync('temp/packages').map(pkg => {
4646
function patchTypes(pkg) {
4747
return {
4848
name: 'patch-types',
49-
renderChunk(code) {
49+
renderChunk(code, chunk) {
5050
const s = new MagicString(code)
5151
const ast = parse(code, {
5252
plugins: ['typescript'],
5353
sourceType: 'module'
5454
})
5555

56+
/**
57+
* @param {import('@babel/types').VariableDeclarator | import('@babel/types').TSTypeAliasDeclaration | import('@babel/types').TSInterfaceDeclaration | import('@babel/types').TSDeclareFunction | import('@babel/types').TSInterfaceDeclaration | import('@babel/types').TSEnumDeclaration | import('@babel/types').ClassDeclaration} node
58+
* @param {import('@babel/types').VariableDeclaration} [parentDecl]
59+
*/
60+
function processDeclaration(node, parentDecl) {
61+
if (!node.id) {
62+
return
63+
}
64+
// @ts-ignore
65+
const name = node.id.name
66+
if (name.startsWith('_')) {
67+
return
68+
}
69+
shouldRemoveExport.add(name)
70+
if (!removeInternal(parentDecl || node)) {
71+
if (isExported.has(name)) {
72+
// @ts-ignore
73+
s.prependLeft((parentDecl || node).start, `export `)
74+
}
75+
// traverse further for internal properties
76+
if (
77+
node.type === 'TSInterfaceDeclaration' ||
78+
node.type === 'ClassDeclaration'
79+
) {
80+
node.body.body.forEach(removeInternal)
81+
} else if (node.type === 'TSTypeAliasDeclaration') {
82+
// @ts-ignore
83+
walk(node.typeAnnotation, {
84+
enter(node) {
85+
// @ts-ignore
86+
if (removeInternal(node)) this.skip()
87+
}
88+
})
89+
}
90+
}
91+
}
92+
5693
/**
5794
* @param {import('@babel/types').Node} node
5895
* @returns {boolean}
@@ -105,55 +142,36 @@ function patchTypes(pkg) {
105142

106143
// pass 1: remove internals + add exports
107144
for (const node of ast.program.body) {
108-
if (
109-
(node.type === 'TSTypeAliasDeclaration' ||
110-
node.type === 'TSInterfaceDeclaration') &&
111-
!node.id.name.startsWith(`_`)
112-
) {
113-
const name = node.id.name
114-
shouldRemoveExport.add(name)
115-
if (!removeInternal(node)) {
116-
if (isExported.has(name)) {
117-
// @ts-ignore
118-
s.prependLeft(node.start, `export `)
119-
}
120-
// traverse further for internal properties
121-
if (node.type === 'TSInterfaceDeclaration') {
122-
node.body.body.forEach(removeInternal)
123-
} else if (node.type === 'TSTypeAliasDeclaration') {
124-
// @ts-ignore
125-
walk(node.typeAnnotation, {
126-
enter(node) {
127-
// @ts-ignore
128-
if (removeInternal(node)) this.skip()
129-
}
130-
})
131-
}
132-
}
133-
} else if (removeInternal(node)) {
134-
if (node.type === 'VariableDeclaration') {
135-
// declare const x
136-
for (const decl of node.declarations) {
137-
// @ts-ignore
138-
shouldRemoveExport.add(decl.id.name)
139-
}
140-
} else if (
141-
node.type === 'TSDeclareFunction' ||
142-
node.type === 'TSEnumDeclaration'
143-
) {
144-
// declare function
145-
// @ts-ignore
146-
shouldRemoveExport.add(node.id.name)
147-
} else {
145+
if (node.type === 'VariableDeclaration') {
146+
processDeclaration(node.declarations[0], node)
147+
if (node.declarations.length > 1) {
148148
throw new Error(
149-
`unhandled export type marked as @internal: ${node.type}`
149+
`unhandled declare const with more than one declarators:\n${code.slice(
150+
// @ts-ignore
151+
node.start,
152+
node.end
153+
)}`
150154
)
151155
}
156+
} else if (
157+
node.type === 'TSTypeAliasDeclaration' ||
158+
node.type === 'TSInterfaceDeclaration' ||
159+
node.type === 'TSDeclareFunction' ||
160+
node.type === 'TSEnumDeclaration' ||
161+
node.type === 'ClassDeclaration'
162+
) {
163+
processDeclaration(node)
164+
} else if (removeInternal(node)) {
165+
throw new Error(
166+
`unhandled export type marked as @internal: ${node.type}`
167+
)
152168
}
153169
}
170+
154171
// pass 2: remove exports
155172
for (const node of ast.program.body) {
156173
if (node.type === 'ExportNamedDeclaration' && !node.source) {
174+
let removed = 0
157175
for (let i = 0; i < node.specifiers.length; i++) {
158176
const spec = node.specifiers[i]
159177
if (
@@ -166,10 +184,7 @@ function patchTypes(pkg) {
166184
// this only happens if we have something like
167185
// type Foo
168186
// export { Foo as Bar }
169-
// there are no such cases atm, so it is unhandled for now.
170-
throw new Error(
171-
`removed export ${exported} has different local name: ${spec.local.name}`
172-
)
187+
continue
173188
}
174189
const next = node.specifiers[i + 1]
175190
if (next) {
@@ -181,12 +196,23 @@ function patchTypes(pkg) {
181196
// @ts-ignore
182197
s.remove(prev ? prev.end : spec.start, spec.end)
183198
}
199+
removed++
184200
}
185201
}
202+
if (removed === node.specifiers.length) {
203+
// @ts-ignore
204+
s.remove(node.start, node.end)
205+
}
186206
}
187207
}
188208
code = s.toString()
189209

210+
if (/@internal/.test(code)) {
211+
throw new Error(
212+
`unhandled @internal declarations detected in ${chunk.fileName}.`
213+
)
214+
}
215+
190216
// append pkg specific types
191217
const additionalTypeDir = `packages/${pkg}/types`
192218
if (existsSync(additionalTypeDir)) {

0 commit comments

Comments
 (0)