22import {
33 compileStyleAsync as sfc_compileStyleAsync ,
44 compileTemplate as sfc_compileTemplate ,
5- parse as sfc_parse ,
5+ parse as sfc_parse , StyleCompileOptions ,
66} from '@vue/component-compiler-utils'
77
88import * as vueTemplateCompiler from 'vue-template-compiler'
@@ -24,9 +24,26 @@ import {
2424import babelPluginTransformModulesCommonjs from '@babel/plugin-transform-modules-commonjs'
2525
2626
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'
2840
29- import { Options , LoadModule , ModuleExport , CustomBlockCallback } from './types.ts'
41+ import {
42+ Options ,
43+ LoadModule ,
44+ ModuleExport ,
45+ CustomBlockCallback
46+ } from './types'
3047
3148/**
3249 * 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
5168 const component = { } ;
5269
5370
54- const { compiledCache, addStyle, log, additionalBabelPlugins = [ ] , customBlockHandler } = options ;
71+ const { moduleCache , compiledCache, addStyle, log, additionalBabelPlugins = [ ] , customBlockHandler } = options ;
5572
5673 // vue-loader next: https://github.com/vuejs/vue-loader/blob/next/src/index.ts#L91
5774 const descriptor = sfc_parse ( {
@@ -73,17 +90,31 @@ export async function createSFCModule(source : string, filename : string, option
7390
7491 const hasScoped = descriptor . styles . some ( e => e . scoped ) ;
7592
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+
7698 const compileTemplateOptions : TemplateCompileOptions = descriptor . template ? {
7799 // hack, since sourceMap is not configurable an we want to get rid of source-map dependency. see genSourcemap
78100 source : descriptor . template . content ,
79101 filename,
80102 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 ,
83108 isProduction : isProd ,
84109 prettify : false
85110 } : null ;
86111
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+
87118 if ( descriptor . script ) {
88119
89120 // 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
105136 } ) ;
106137
107138 } 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 ) ) ;
109140 throw ex ;
110141 }
111142
@@ -139,20 +170,36 @@ export async function createSFCModule(source : string, filename : string, option
139170
140171 const template = sfc_compileTemplate ( compileTemplateOptions ) ;
141172 // "@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 }`
143174
144175 if ( template . errors . length ) {
145176
146177 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+ }
148186
149187 // @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 ) ) ;
151189 }
152190 }
153191
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+ }
156203
157204 return await transformJSCode ( template . code , true , filename , options ) ;
158205 } ) ;
@@ -169,24 +216,30 @@ export async function createSFCModule(source : string, filename : string, option
169216 await loadModule ( descStyle . lang , options ) ;
170217
171218 const style = await withCache ( compiledCache , [ componentHash , descStyle . content ] , async ( { preventCache } ) => {
172-
173219 // 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 = {
175222 source : descStyle . content ,
176223 filename,
177224 id : scopeId ,
178225 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+ }
182234
235+ const compiledStyle = await sfc_compileStyleAsync ( compileStyleOptions ) ;
183236 if ( compiledStyle . errors . length ) {
184237
185238 preventCache ( ) ;
186239 for ( const err of compiledStyle . errors ) {
187240
188241 // @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 ) ) ;
190243 }
191244 }
192245
0 commit comments