--- /dev/null
+import { rewriteDefault } from '../src'
+
+describe('compiler sfc: rewriteDefault', () => {
+ test('without export default', () => {
+ expect(rewriteDefault(`export a = {}`, 'script')).toMatchInlineSnapshot(`
+ "export a = {}
+ const script = {}"
+ `)
+ })
+
+ test('rewrite export default', () => {
+ expect(
+ rewriteDefault(`export default {}`, 'script')
+ ).toMatchInlineSnapshot(`"const script = {}"`)
+ })
+
+ test('rewrite export named default', () => {
+ expect(
+ rewriteDefault(
+ `const a = 1 \n export { a as b, a as default, a as c}`,
+ 'script'
+ )
+ ).toMatchInlineSnapshot(`
+ "const a = 1
+ export { a as b, a as c}
+ const script = a"
+ `)
+ })
+})
import { parse, ParserPlugin } from '@babel/parser'
import MagicString from 'magic-string'
-const defaultExportRE = /((?:^|\n|;)\s*)export default/
+const defaultExportRE = /((?:^|\n|;)\s*)export(\s*)default/
+const namedDefaultExportRE = /((?:^|\n|;)\s*)export(.+)as(\s*)default/
/**
* Utility for rewriting `export default` in a script block into a varaible
as: string,
parserPlugins?: ParserPlugin[]
): string {
- if (!defaultExportRE.test(input)) {
+ if (!hasDefaultExport(input)) {
return input + `\nconst ${as} = {}`
}
const replaced = input.replace(defaultExportRE, `$1const ${as} =`)
- if (!defaultExportRE.test(replaced)) {
+ if (!hasDefaultExport(replaced)) {
return replaced
}
// multi-line comments or template strings. fallback to a full parse.
const s = new MagicString(input)
const ast = parse(input, {
+ sourceType: 'module',
plugins: parserPlugins
}).program.body
ast.forEach(node => {
if (node.type === 'ExportDefaultDeclaration') {
s.overwrite(node.start!, node.declaration.start!, `const ${as} = `)
}
+ if (node.type === 'ExportNamedDeclaration') {
+ node.specifiers.forEach(specifier => {
+ if (
+ specifier.type === 'ExportSpecifier' &&
+ specifier.exported.name === 'default'
+ ) {
+ const end = specifier.end!
+ s.overwrite(
+ specifier.start!,
+ input.charAt(end) === ',' ? end + 1 : end,
+ ``
+ )
+ s.append(`\nconst ${as} = ${specifier.local.name}`)
+ }
+ })
+ }
})
return s.toString()
}
+
+export function hasDefaultExport(input: string): boolean {
+ return defaultExportRE.test(input) || namedDefaultExportRE.test(input)
+}