Skip to content

Commit c97f0a9

Browse files
perf(core): avoid to compile SFC script twice
1 parent 9e16d58 commit c97f0a9

File tree

1 file changed

+34
-23
lines changed

1 file changed

+34
-23
lines changed

src/createVue3SFCModule.ts

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ import {
2121
} from '@babel/parser';
2222

2323
import {
24-
transformFromAstAsync as babel_transformFromAstAsync
24+
transformFromAstAsync as babel_transformFromAstAsync,
25+
types as t,
2526
} from '@babel/core';
2627

2728
// @ts-ignore (Could not find a declaration file for module '@babel/plugin-transform-modules-commonjs')
@@ -114,41 +115,51 @@ export async function createSFCModule(source : string, filename : string, option
114115
const babelParserPlugins : babel_ParserPlugin[] = [];
115116

116117
// src: https://github.com/vuejs/vue-next/blob/15baaf14f025f6b1d46174c9713a2ec517741d0d/packages/compiler-sfc/src/compileScript.ts#L43
117-
const script = sfc_compileScript(descriptor, {
118+
const scriptBlock = sfc_compileScript(descriptor, {
118119
isProd,
119120
id: scopeId,
120121
babelParserPlugins,
121122
templateOptions: compileTemplateOptions,
122123
});
123124

124125
let ast;
125-
try {
126-
127-
ast = babel_parse(script.content, {
128-
// doc: https://babeljs.io/docs/en/babel-parser#options
129-
// if: https://github.com/babel/babel/blob/main/packages/babel-parser/typings/babel-parser.d.ts#L24
130-
plugins: [
131-
// see https://github.com/vuejs/vue-next/blob/15baaf14f025f6b1d46174c9713a2ec517741d0d/packages/compiler-sfc/src/compileScript.ts#L63
132-
...vue_babelParserDefaultPlugins,
133-
'jsx',
134-
...babelParserPlugins
135-
],
136-
sourceType: 'module',
137-
sourceFilename: filename,
138-
startLine: script.loc.start.line,
139-
});
140-
141-
} catch(ex) {
142-
143-
log?.('error', 'SFC script', formatError(ex.message, filename, source, ex.loc.line, ex.loc.column + 1) );
144-
throw ex;
126+
if ( !scriptBlock.scriptAst ) {
127+
128+
// need to re-parse because script compilation errors are not reported by sfc_compileScript
129+
try {
130+
131+
ast = babel_parse(scriptBlock.content, {
132+
// doc: https://babeljs.io/docs/en/babel-parser#options
133+
// if: https://github.com/babel/babel/blob/main/packages/babel-parser/typings/babel-parser.d.ts#L24
134+
plugins: [
135+
// see https://github.com/vuejs/vue-next/blob/15baaf14f025f6b1d46174c9713a2ec517741d0d/packages/compiler-sfc/src/compileScript.ts#L63
136+
...vue_babelParserDefaultPlugins,
137+
'jsx',
138+
...babelParserPlugins
139+
],
140+
sourceType: 'module',
141+
sourceFilename: filename,
142+
startLine: scriptBlock.loc.start.line,
143+
});
144+
145+
} catch(ex) {
146+
147+
log?.('error', 'SFC script', formatError(ex.message, filename, source, ex.loc.line, ex.loc.column + 1) );
148+
throw ex;
149+
}
150+
} else {
151+
152+
// scriptBlock.scriptAst is not type:Program, need to construct one
153+
// see t.file: https://babeljs.io/docs/en/babel-types#file
154+
// see t.program: https://babeljs.io/docs/en/babel-types#program
155+
ast = t.file(t.program(scriptBlock.scriptAst, [], 'module'));
145156
}
146157

147158

148159
renameDynamicImport(ast);
149160
const depsList = parseDeps(ast);
150161

151-
const transformedScript = await babel_transformFromAstAsync(ast, script.content, {
162+
const transformedScript = await babel_transformFromAstAsync(ast, scriptBlock.content, {
152163
sourceMaps: genSourcemap, // https://babeljs.io/docs/en/options#sourcemaps
153164
plugins: [ // https://babeljs.io/docs/en/options#plugins
154165
babelPluginTransformModulesCommonjs, // https://babeljs.io/docs/en/babel-plugin-transform-modules-commonjs#options

0 commit comments

Comments
 (0)