Skip to content

Commit 9e66ee1

Browse files
committed
fix: partially support re-export
relate #121
1 parent 4a4369d commit 9e66ee1

File tree

5 files changed

+113
-0
lines changed

5 files changed

+113
-0
lines changed

src/fake-js.ts

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ export function createFakeJsPlugin({
279279
const { program } = file
280280

281281
program.body = patchTsNamespace(program.body)
282+
program.body = patchReExport(program.body)
282283

283284
program.body = program.body
284285
.map((node) => {
@@ -725,6 +726,9 @@ function patchImportExport(
725726
}
726727
}
727728

729+
/**
730+
* Handle `__export` call
731+
*/
728732
function patchTsNamespace(nodes: t.Statement[]) {
729733
const removed = new Set<t.Node>()
730734

@@ -784,6 +788,90 @@ function patchTsNamespace(nodes: t.Statement[]) {
784788
}
785789
}
786790

791+
/**
792+
* Handle `__reExport` call
793+
*/
794+
function patchReExport(nodes: t.Statement[]) {
795+
const exportsNames = new Map<string, string>()
796+
797+
for (const [i, node] of nodes.entries()) {
798+
if (
799+
node.type === 'ImportDeclaration' &&
800+
node.specifiers.length === 1 &&
801+
node.specifiers[0].type === 'ImportSpecifier' &&
802+
node.specifiers[0].local.type === 'Identifier' &&
803+
node.specifiers[0].local.name.endsWith('_exports')
804+
) {
805+
// record: import { t as a_exports } from "..."
806+
exportsNames.set(
807+
node.specifiers[0].local.name,
808+
node.specifiers[0].local.name,
809+
)
810+
} else if (
811+
node.type === 'ExpressionStatement' &&
812+
node.expression.type === 'CallExpression' &&
813+
node.expression.callee.type === 'Identifier' &&
814+
node.expression.callee.name === '__reExport'
815+
) {
816+
// record: __reExport(a_exports, import_lib)
817+
818+
const args = node.expression.arguments
819+
exportsNames.set(
820+
(args[0] as t.Identifier).name,
821+
(args[1] as t.Identifier).name,
822+
)
823+
} else if (
824+
node.type === 'VariableDeclaration' &&
825+
node.declarations.length === 1 &&
826+
node.declarations[0].init?.type === 'MemberExpression' &&
827+
node.declarations[0].init.object.type === 'Identifier' &&
828+
exportsNames.has(node.declarations[0].init.object.name)
829+
) {
830+
// var B = a_exports.A
831+
// to
832+
// type B = [mapping].A
833+
// TODO how to support value import? currently only type import is supported
834+
835+
nodes[i] = {
836+
type: 'TSTypeAliasDeclaration',
837+
id: {
838+
type: 'Identifier',
839+
name: (node.declarations[0].id as t.Identifier).name,
840+
},
841+
typeAnnotation: {
842+
type: 'TSTypeReference',
843+
typeName: {
844+
type: 'TSQualifiedName',
845+
left: {
846+
type: 'Identifier',
847+
name: exportsNames.get(node.declarations[0].init.object.name)!,
848+
},
849+
right: {
850+
type: 'Identifier',
851+
name: (node.declarations[0].init.property as t.Identifier).name,
852+
},
853+
},
854+
},
855+
}
856+
} else if (
857+
node.type === 'ExportNamedDeclaration' &&
858+
node.specifiers.length === 1 &&
859+
node.specifiers[0].type === 'ExportSpecifier' &&
860+
node.specifiers[0].local.type === 'Identifier' &&
861+
exportsNames.has(node.specifiers[0].local.name)
862+
) {
863+
// export { a_exports as t }
864+
// to
865+
// export { [mapping] as t }
866+
node.specifiers[0].local.name = exportsNames.get(
867+
node.specifiers[0].local.name,
868+
)!
869+
}
870+
}
871+
872+
return nodes
873+
}
874+
787875
// fix:
788876
// - import type { ... } from '...'
789877
// - import { type ... } from '...'

tests/__snapshots__/index.test.ts.snap

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,20 @@ import { Input2, input2 } from "./input2-CzdQ8V-e.js";
222222
export { Input2, input2 };"
223223
`;
224224
225+
exports[`external namespace 1`] = `
226+
"// index.d.ts
227+
import { t as mod_d_exports } from "./mod-3KblRJ7v.js";
228+
type A = mod_d_exports.A;
229+
export { A };
230+
// mod-3KblRJ7v.d.ts
231+
import * as import_lib from "lib";
232+
//#endregion
233+
export { import_lib as t };
234+
// mod.d.ts
235+
import "./mod-3KblRJ7v.js";
236+
export * from "lib";"
237+
`;
238+
225239
exports[`input alias 1`] = `
226240
"// input2-CcmD5Ns-.d.ts
227241
//#region shared.d.ts
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { A } from './mod'
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from 'lib'

tests/index.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,3 +502,12 @@ test('advancedChunks', async () => {
502502
expect(snapshot).toMatchSnapshot()
503503
expect(chunks).toHaveLength(2)
504504
})
505+
506+
test('external namespace', async () => {
507+
const root = path.resolve(dirname, 'fixtures/external-namespace')
508+
const { snapshot } = await rolldownBuild(
509+
[path.resolve(root, 'index.ts'), path.resolve(root, 'mod.ts')],
510+
[dts({ emitDtsOnly: true })],
511+
)
512+
expect(snapshot).toMatchSnapshot()
513+
})

0 commit comments

Comments
 (0)