core icon indicating copy to clipboard operation
core copied to clipboard

use decorator before export default may cause compilation problems

Open linshuohao opened this issue 3 years ago • 1 comments

Version

3.2.37

Reproduction link

stackblitz.com

Steps to reproduce

After open the above reproduction, you will see the console shows the error: [vite] Internal server error: Cannot overwrite across a split point

What is expected?

rewriteDefault can transform

@Component
export default class App extends Vue {
  a = ';export default';
}

into

@Component
class App extends Vue {
  a = ';export default';
}
const ${as} = App

so that vite can work correctly

What is actually happening?

export function rewriteDefault(
  input: string,
  as: string,
  parserPlugins?: ParserPlugin[]
): string {
 ...

  // if the script somehow still contains `default export`, it probably has
  // 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} = `)
    }

   ...
}

when the script still contains default export, and fallback to a full parse.

"@babel/parser" parse

@Component
export default class xxx {}

to

{
    "type": "ExportDefaultDeclaration",
    "start": 11,
    "end": 38,
    "loc": {
        "start": {
            "line": 2,
            "column": 0,
            "index": 11
        },
        "end": {
            "line": 2,
            "column": 27,
            "index": 38
        }
    },
    "exportKind": "value",
    "declaration": {
        "type": "ClassDeclaration",
        "start": 0,
        "end": 38,
        "loc": {
            "start": {
                "line": 1,
                "column": 0,
                "index": 0
            },
            "end": {
                "line": 2,
                "column": 27,
                "index": 38
            }
        },
        "decorators": [
            {
                "type": "Decorator",
                "start": 0,
                "end": 10,
                "loc": {
                    "start": {
                        "line": 1,
                        "column": 0,
                        "index": 0
                    },
                    "end": {
                        "line": 1,
                        "column": 10,
                        "index": 10
                    }
                },
                "expression": {
                    "type": "Identifier",
                    "start": 1,
                    "end": 10,
                    "loc": {
                        "start": {
                            "line": 1,
                            "column": 1,
                            "index": 1
                        },
                        "end": {
                            "line": 1,
                            "column": 10,
                            "index": 10
                        },
                        "identifierName": "Component"
                    },
                    "name": "Component"
                }
            }
        ],
        "id": {
            "type": "Identifier",
            "start": 32,
            "end": 35,
            "loc": {
                "start": {
                    "line": 2,
                    "column": 21,
                    "index": 32
                },
                "end": {
                    "line": 2,
                    "column": 24,
                    "index": 35
                },
                "identifierName": "xxx"
            },
            "name": "xxx"
        },
        "superClass": null,
        "body": {
            "type": "ClassBody",
            "start": 36,
            "end": 38,
            "loc": {
                "start": {
                    "line": 2,
                    "column": 25,
                    "index": 36
                },
                "end": {
                    "line": 2,
                    "column": 27,
                    "index": 38
                }
            },
            "body": []
        }
    }
}

node.start is larger than node.declaration.start , that cause compilation problem

linshuohao avatar Jul 20 '22 09:07 linshuohao

I can both confirm this issue, as well as that the fix in https://github.com/vuejs/core/pull/6320 works.

See also this StackOverflow question for more context: https://stackoverflow.com/questions/72743336/vite-vue3-throws-internal-server-error-experimental-syntax-missing-parser-plu

Dids avatar Jul 21 '22 13:07 Dids