diff --git a/packages/compiler-core/src/transforms/transformExpression.ts b/packages/compiler-core/src/transforms/transformExpression.ts
index 97e8fece..1e223067 100644
--- a/packages/compiler-core/src/transforms/transformExpression.ts
+++ b/packages/compiler-core/src/transforms/transformExpression.ts
@@ -30,7 +30,6 @@ import {
import { createCompilerError, ErrorCodes } from '../errors'
import { Node, Function, Identifier, ObjectProperty } from '@babel/types'
import { validateBrowserExpression } from '../validateExpression'
-import { ParserPlugin } from '@babel/parser'
const isLiteralWhitelisted = /*#__PURE__*/ makeMap('true,false,null,this')
@@ -130,10 +129,7 @@ export function processExpression(
: `(${rawExp})${asParams ? `=>{}` : ``}`
try {
ast = parseJS(source, {
- plugins: [
- ...context.expressionPlugins,
- ...(babelParserDefautPlugins as ParserPlugin[])
- ]
+ plugins: [...context.expressionPlugins, ...babelParserDefautPlugins]
}).program
} catch (e) {
context.onError(
diff --git a/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap b/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap
new file mode 100644
index 00000000..cf681ef1
--- /dev/null
+++ b/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap
@@ -0,0 +1,248 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`SFC compile `).code)
+ })
+
+ test('explicit setup signature', () => {
+ assertCode(
+ compile(``).code
+ )
+ })
+
+ test('import dedupe between
+
+ `).code
+ assertCode(code)
+ expect(code.indexOf(`import { x }`)).toEqual(
+ code.lastIndexOf(`import { x }`)
+ )
+ })
+
+ describe('exports', () => {
+ test('export const x = ...', () => {
+ const { code, bindings } = compile(
+ ``
+ )
+ assertCode(code)
+ expect(bindings).toStrictEqual({
+ x: 'setup'
+ })
+ })
+
+ test('export const { x } = ... (destructuring)', () => {
+ const { code, bindings } = compile(``)
+ assertCode(code)
+ expect(bindings).toStrictEqual({
+ a: 'setup',
+ b: 'setup',
+ c: 'setup',
+ d: 'setup',
+ e: 'setup',
+ f: 'setup'
+ })
+ })
+
+ test('export function x() {}', () => {
+ const { code, bindings } = compile(
+ ``
+ )
+ assertCode(code)
+ expect(bindings).toStrictEqual({
+ x: 'setup'
+ })
+ })
+
+ test('export class X() {}', () => {
+ const { code, bindings } = compile(
+ ``
+ )
+ assertCode(code)
+ expect(bindings).toStrictEqual({
+ X: 'setup'
+ })
+ })
+
+ test('export { x }', () => {
+ const { code, bindings } = compile(
+ ``
+ )
+ assertCode(code)
+ expect(bindings).toStrictEqual({
+ x: 'setup',
+ y: 'setup'
+ })
+ })
+
+ test(`export { x } from './x'`, () => {
+ const { code, bindings } = compile(
+ ``
+ )
+ assertCode(code)
+ expect(bindings).toStrictEqual({
+ x: 'setup',
+ y: 'setup'
+ })
+ })
+
+ test(`export default from './x'`, () => {
+ const { code, bindings } = compile(
+ ``,
+ {
+ parserPlugins: ['exportDefaultFrom']
+ }
+ )
+ assertCode(code)
+ expect(bindings).toStrictEqual({})
+ })
+
+ test(`export { x as default }`, () => {
+ const { code, bindings } = compile(
+ ``
+ )
+ assertCode(code)
+ expect(bindings).toStrictEqual({
+ y: 'setup'
+ })
+ })
+
+ test(`export { x as default } from './x'`, () => {
+ const { code, bindings } = compile(
+ ``
+ )
+ assertCode(code)
+ expect(bindings).toStrictEqual({
+ y: 'setup'
+ })
+ })
+
+ test(`export * from './x'`, () => {
+ const { code, bindings } = compile(
+ ``
+ )
+ assertCode(code)
+ expect(bindings).toStrictEqual({
+ y: 'setup'
+ // in this case we cannot extract bindings from ./x so it falls back
+ // to runtime proxy dispatching
+ })
+ })
+
+ test('export default in `
+ )
+ assertCode(code)
+ expect(bindings).toStrictEqual({
+ y: 'setup'
+ })
+ })
+ })
+
+ describe('`)
+ assertCode(code)
+ expect(bindings).toStrictEqual({ a: 'setup' })
+ })
+
+ test('extract props', () => {})
+
+ test('extract emits', () => {})
+ })
+
+ describe('errors', () => {
+ test('must have `)).toThrow(
+ `SFC has no `)
+ ).toThrow(``)
+ ).toThrow(`Cannot export locally defined variable as default`)
+ })
+
+ test('export default referencing local var', () => {
+ expect(() =>
+ compile(``)
+ ).toThrow(`cannot reference locally declared variables`)
+ })
+
+ test('export default referencing exports', () => {
+ expect(() =>
+ compile(``)
+ ).toThrow(`cannot reference locally declared variables`)
+ })
+
+ test('should allow export default referencing scope var', () => {
+ assertCode(
+ compile(``).code
+ )
+ })
+
+ test('should allow export default referencing imported binding', () => {
+ assertCode(
+ compile(``).code
+ )
+ })
+
+ test('should allow export default referencing re-exported binding', () => {
+ assertCode(
+ compile(``).code
+ )
+ })
+
+ test('error on duplicated defalut export', () => {
+ expect(() =>
+ compile(`
+
+
+ `)
+ ).toThrow(`Default export is already declared`)
+
+ expect(() =>
+ compile(`
+
+
+ `)
+ ).toThrow(`Default export is already declared`)
+
+ expect(() =>
+ compile(`
+
+
+ `)
+ ).toThrow(`Default export is already declared`)
+
+ expect(() =>
+ compile(`
+
+
+ `)
+ ).toThrow(`Default export is already declared`)
+
+ expect(() =>
+ compile(`
+
+
+ `)
+ ).toThrow(`Default export is already declared`)
+ })
+ })
+})
diff --git a/packages/compiler-sfc/src/compileScript.ts b/packages/compiler-sfc/src/compileScript.ts
index bc789e25..aabf4b3a 100644
--- a/packages/compiler-sfc/src/compileScript.ts
+++ b/packages/compiler-sfc/src/compileScript.ts
@@ -51,7 +51,21 @@ export function compileScriptSetup(
const setupExports: Record = {}
let exportAllIndex = 0
let defaultExport: Node | undefined
- let needDefaultExportCheck: boolean = false
+ let needDefaultExportRefCheck: boolean = false
+
+ const checkDuplicateDefaultExport = (node: Node) => {
+ if (defaultExport) {
+ //