Skip to content

Commit 452edb7

Browse files
authored
fix(compiler-sfc): fix rewrite named export default (#1675)
1 parent ee6828a commit 452edb7

File tree

2 files changed

+54
-3
lines changed

2 files changed

+54
-3
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { rewriteDefault } from '../src'
2+
3+
describe('compiler sfc: rewriteDefault', () => {
4+
test('without export default', () => {
5+
expect(rewriteDefault(`export a = {}`, 'script')).toMatchInlineSnapshot(`
6+
"export a = {}
7+
const script = {}"
8+
`)
9+
})
10+
11+
test('rewrite export default', () => {
12+
expect(
13+
rewriteDefault(`export default {}`, 'script')
14+
).toMatchInlineSnapshot(`"const script = {}"`)
15+
})
16+
17+
test('rewrite export named default', () => {
18+
expect(
19+
rewriteDefault(
20+
`const a = 1 \n export { a as b, a as default, a as c}`,
21+
'script'
22+
)
23+
).toMatchInlineSnapshot(`
24+
"const a = 1
25+
export { a as b, a as c}
26+
const script = a"
27+
`)
28+
})
29+
})
+25-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { parse, ParserPlugin } from '@babel/parser'
22
import MagicString from 'magic-string'
33

4-
const defaultExportRE = /((?:^|\n|;)\s*)export default/
4+
const defaultExportRE = /((?:^|\n|;)\s*)export(\s*)default/
5+
const namedDefaultExportRE = /((?:^|\n|;)\s*)export(.+)as(\s*)default/
56

67
/**
78
* Utility for rewriting `export default` in a script block into a varaible
@@ -12,25 +13,46 @@ export function rewriteDefault(
1213
as: string,
1314
parserPlugins?: ParserPlugin[]
1415
): string {
15-
if (!defaultExportRE.test(input)) {
16+
if (!hasDefaultExport(input)) {
1617
return input + `\nconst ${as} = {}`
1718
}
1819

1920
const replaced = input.replace(defaultExportRE, `$1const ${as} =`)
20-
if (!defaultExportRE.test(replaced)) {
21+
if (!hasDefaultExport(replaced)) {
2122
return replaced
2223
}
2324

2425
// if the script somehow still contains `default export`, it probably has
2526
// multi-line comments or template strings. fallback to a full parse.
2627
const s = new MagicString(input)
2728
const ast = parse(input, {
29+
sourceType: 'module',
2830
plugins: parserPlugins
2931
}).program.body
3032
ast.forEach(node => {
3133
if (node.type === 'ExportDefaultDeclaration') {
3234
s.overwrite(node.start!, node.declaration.start!, `const ${as} = `)
3335
}
36+
if (node.type === 'ExportNamedDeclaration') {
37+
node.specifiers.forEach(specifier => {
38+
if (
39+
specifier.type === 'ExportSpecifier' &&
40+
specifier.exported.name === 'default'
41+
) {
42+
const end = specifier.end!
43+
s.overwrite(
44+
specifier.start!,
45+
input.charAt(end) === ',' ? end + 1 : end,
46+
``
47+
)
48+
s.append(`\nconst ${as} = ${specifier.local.name}`)
49+
}
50+
})
51+
}
3452
})
3553
return s.toString()
3654
}
55+
56+
export function hasDefaultExport(input: string): boolean {
57+
return defaultExportRE.test(input) || namedDefaultExportRE.test(input)
58+
}

0 commit comments

Comments
 (0)