2
2
import {
3
3
compileStyleAsync as sfc_compileStyleAsync ,
4
4
compileTemplate as sfc_compileTemplate ,
5
- parse as sfc_parse ,
5
+ parse as sfc_parse , StyleCompileOptions ,
6
6
} from '@vue/component-compiler-utils'
7
7
8
8
import * as vueTemplateCompiler from 'vue-template-compiler'
@@ -24,9 +24,26 @@ import {
24
24
import babelPluginTransformModulesCommonjs from '@babel/plugin-transform-modules-commonjs'
25
25
26
26
27
- import { formatError , withCache , hash , renameDynamicImport , parseDeps , interopRequireDefault , transformJSCode , loadDeps , createModule } from './tools.ts'
27
+ import {
28
+ formatError ,
29
+ formatErrorStartEnd ,
30
+ withCache ,
31
+ hash ,
32
+ renameDynamicImport ,
33
+ parseDeps ,
34
+ interopRequireDefault ,
35
+ transformJSCode ,
36
+ loadDeps ,
37
+ createModule ,
38
+ formatErrorLineColumn
39
+ } from './tools'
28
40
29
- import { Options , LoadModule , ModuleExport , CustomBlockCallback } from './types.ts'
41
+ import {
42
+ Options ,
43
+ LoadModule ,
44
+ ModuleExport ,
45
+ CustomBlockCallback
46
+ } from './types'
30
47
31
48
/**
32
49
* the version of the library (process.env.VERSION is set by webpack, at compile-time)
@@ -51,7 +68,7 @@ export async function createSFCModule(source : string, filename : string, option
51
68
const component = { } ;
52
69
53
70
54
- const { compiledCache, addStyle, log, additionalBabelPlugins = [ ] , customBlockHandler } = options ;
71
+ const { moduleCache , compiledCache, addStyle, log, additionalBabelPlugins = [ ] , customBlockHandler } = options ;
55
72
56
73
// vue-loader next: https://github.com/vuejs/vue-loader/blob/next/src/index.ts#L91
57
74
const descriptor = sfc_parse ( {
@@ -73,17 +90,31 @@ export async function createSFCModule(source : string, filename : string, option
73
90
74
91
const hasScoped = descriptor . styles . some ( e => e . scoped ) ;
75
92
93
+ // https://github.com/vuejs/vue-loader/blob/b53ae44e4b9958db290f5918248071e9d2445d38/lib/runtime/componentNormalizer.js#L36
94
+ if ( hasScoped ) {
95
+ Object . assign ( component , { _scopeId : scopeId } ) ;
96
+ }
97
+
76
98
const compileTemplateOptions : TemplateCompileOptions = descriptor . template ? {
77
99
// hack, since sourceMap is not configurable an we want to get rid of source-map dependency. see genSourcemap
78
100
source : descriptor . template . content ,
79
101
filename,
80
102
compiler : vueTemplateCompiler as VueTemplateCompiler ,
81
- compilerOptions : undefined ,
82
- preprocessLang : descriptor . template . lang ,
103
+ compilerOptions : {
104
+ outputSourceRange : true ,
105
+ scopeId : hasScoped ? scopeId : null ,
106
+ comments : true
107
+ } as any ,
83
108
isProduction : isProd ,
84
109
prettify : false
85
110
} : null ;
86
111
112
+ // Vue2 doesn't support preprocessCustomRequire, so we have to preprocess manually
113
+ if ( descriptor . template ?. lang ) {
114
+ const preprocess = moduleCache [ descriptor . template . lang ] as any
115
+ compileTemplateOptions . source = preprocess . render ( compileTemplateOptions . source , compileTemplateOptions . preprocessOptions )
116
+ }
117
+
87
118
if ( descriptor . script ) {
88
119
89
120
// eg: https://github.com/vuejs/vue-loader/blob/v15.9.6/lib/index.js
@@ -105,7 +136,7 @@ export async function createSFCModule(source : string, filename : string, option
105
136
} ) ;
106
137
107
138
} catch ( ex ) {
108
- log ?.( 'error' , 'SFC script' , formatError ( ex . message , filename , source , ex . loc . line , ex . loc . column + 1 ) ) ;
139
+ log ?.( 'error' , 'SFC script' , formatErrorLineColumn ( ex . message , filename , source , ex . loc . line , ex . loc . column + 1 ) ) ;
109
140
throw ex ;
110
141
}
111
142
@@ -139,20 +170,36 @@ export async function createSFCModule(source : string, filename : string, option
139
170
140
171
const template = sfc_compileTemplate ( compileTemplateOptions ) ;
141
172
// "@vue/component-compiler-utils" does NOT assume any module system, and expose render in global scope.
142
- template . code += " \nmodule.exports = {render: render, staticRenderFns: staticRenderFns}"
173
+ template . code += ` \nmodule.exports = { render, staticRenderFns }`
143
174
144
175
if ( template . errors . length ) {
145
176
146
177
preventCache ( ) ;
147
- for ( const err of template . errors ) {
178
+ for ( let err of template . errors ) {
179
+ if ( typeof err !== 'object' ) {
180
+ err = {
181
+ msg : err ,
182
+ start : undefined ,
183
+ end : undefined
184
+ }
185
+ }
148
186
149
187
// @ts -ignore (Property 'message' does not exist on type 'string | CompilerError')
150
- log ?.( 'error' , 'SFC template' , err ) ;
188
+ log ?.( 'error' , 'SFC template' , formatErrorStartEnd ( err . msg , filename , compileTemplateOptions . source . trim ( ) , err . start , err . end ) ) ;
151
189
}
152
190
}
153
191
154
- for ( const err of template . tips )
155
- log ?.( 'info' , 'SFC template' , err ) ;
192
+ for ( let err of template . tips ) {
193
+ if ( typeof err !== 'object' ) {
194
+ err = {
195
+ msg : err ,
196
+ start : undefined ,
197
+ end : undefined
198
+ }
199
+ }
200
+
201
+ log ?.( 'info' , 'SFC template' , formatErrorStartEnd ( err . msg , filename , source , err . start , err . end ) ) ;
202
+ }
156
203
157
204
return await transformJSCode ( template . code , true , filename , options ) ;
158
205
} ) ;
@@ -169,24 +216,30 @@ export async function createSFCModule(source : string, filename : string, option
169
216
await loadModule ( descStyle . lang , options ) ;
170
217
171
218
const style = await withCache ( compiledCache , [ componentHash , descStyle . content ] , async ( { preventCache } ) => {
172
-
173
219
// src: https://github.com/vuejs/vue-next/blob/15baaf14f025f6b1d46174c9713a2ec517741d0d/packages/compiler-sfc/src/compileStyle.ts#L70
174
- const compiledStyle = await sfc_compileStyleAsync ( {
220
+
221
+ const compileStyleOptions : StyleCompileOptions = {
175
222
source : descStyle . content ,
176
223
filename,
177
224
id : scopeId ,
178
225
scoped : descStyle . scoped ,
179
- trim : false , // Should we enable it, as it requires postcss trimPlugin ?
180
- preprocessLang : descStyle . lang
181
- } ) ;
226
+ trim : false ,
227
+ preprocessLang : descStyle . lang ,
228
+ preprocessOptions : {
229
+ preprocessOptions : {
230
+ customRequire : ( id : string ) => moduleCache [ id ]
231
+ }
232
+ }
233
+ }
182
234
235
+ const compiledStyle = await sfc_compileStyleAsync ( compileStyleOptions ) ;
183
236
if ( compiledStyle . errors . length ) {
184
237
185
238
preventCache ( ) ;
186
239
for ( const err of compiledStyle . errors ) {
187
240
188
241
// @ts -ignore (Property 'line' does not exist on type 'Error' and Property 'column' does not exist on type 'Error')
189
- log ?.( 'error' , 'SFC style' , formatError ( err . message , filename , source , err . line , err . column ) ) ;
242
+ log ?.( 'error' , 'SFC style' , formatError ( err , filename , descStyle . content ) ) ;
190
243
}
191
244
}
192
245
0 commit comments