@@ -16,21 +16,21 @@ import hash = require('hash-sum')
1616
1717import {
1818 parse ,
19- compileScript ,
2019 TemplateCompiler ,
2120 CompilerOptions ,
2221 SFCBlock ,
2322 SFCTemplateCompileOptions ,
2423 SFCScriptCompileOptions ,
2524 SFCStyleBlock ,
26- SFCScriptBlock ,
2725} from '@vue/compiler-sfc'
2826import { selectBlock } from './select'
2927import { genHotReloadCode } from './hotReload'
3028import { genCSSModulesCode } from './cssModules'
3129import { formatError } from './formatError'
3230
3331import VueLoaderPlugin from './plugin'
32+ import { resolveScript } from './resolveScript'
33+ import { setDescriptor } from './descriptorCache'
3434
3535export { VueLoaderPlugin }
3636
@@ -93,6 +93,9 @@ export default function loader(
9393 sourceMap,
9494 } )
9595
96+ // cache descriptor
97+ setDescriptor ( resourcePath , descriptor )
98+
9699 if ( errors . length ) {
97100 errors . forEach ( ( err ) => {
98101 formatError ( err , source , resourcePath )
@@ -101,73 +104,72 @@ export default function loader(
101104 return ``
102105 }
103106
107+ // module id for scoped CSS & hot-reload
108+ const rawShortFilePath = path
109+ . relative ( rootContext || process . cwd ( ) , resourcePath )
110+ . replace ( / ^ ( \. \. [ \/ \\ ] ) + / , '' )
111+ const shortFilePath = rawShortFilePath . replace ( / \\ / g, '/' ) + resourceQuery
112+ const id = hash (
113+ isProduction
114+ ? shortFilePath + '\n' + source . replace ( / \r \n / g, '\n' )
115+ : shortFilePath
116+ )
117+
104118 // if the query has a type field, this is a language block request
105119 // e.g. foo.vue?type=template&id=xxxxx
106120 // and we will return early
107121 if ( incomingQuery . type ) {
108122 return selectBlock (
109123 descriptor ,
124+ id ,
125+ options ,
110126 loaderContext ,
111127 incomingQuery ,
112128 ! ! options . appendExtension
113129 )
114130 }
115131
116- // module id for scoped CSS & hot-reload
117- const rawShortFilePath = path
118- . relative ( rootContext || process . cwd ( ) , resourcePath )
119- . replace ( / ^ ( \. \. [ \/ \\ ] ) + / , '' )
120- const shortFilePath = rawShortFilePath . replace ( / \\ / g, '/' ) + resourceQuery
121- const id = hash (
122- isProduction
123- ? shortFilePath + '\n' + source . replace ( / \r \n / g, '\n' )
124- : shortFilePath
125- )
126-
127132 // feature information
128133 const hasScoped = descriptor . styles . some ( ( s ) => s . scoped )
129134 const needsHotReload =
130135 ! isServer &&
131136 ! isProduction &&
132- ! ! ( descriptor . script || descriptor . template ) &&
137+ ! ! ( descriptor . script || descriptor . scriptSetup || descriptor . template ) &&
133138 options . hotReload !== false
134139
135140 // script
136- let script : SFCScriptBlock | undefined
137141 let scriptImport = `const script = {}`
138- if ( descriptor . script || descriptor . scriptSetup ) {
139- try {
140- script = ( descriptor as any ) . scriptCompiled = compileScript ( descriptor , {
141- babelParserPlugins : options . babelParserPlugins ,
142- } )
143- } catch ( e ) {
144- loaderContext . emitError ( e )
145- }
146- if ( script ) {
147- const src = script . src || resourcePath
148- const attrsQuery = attrsToQuery ( script . attrs , 'js' )
149- const query = `?vue&type=script${ attrsQuery } ${ resourceQuery } `
150- const scriptRequest = stringifyRequest ( src + query )
151- scriptImport =
152- `import script from ${ scriptRequest } \n` +
153- // support named exports
154- `export * from ${ scriptRequest } `
155- }
142+ const script = resolveScript ( descriptor , id , options , loaderContext )
143+ if ( script ) {
144+ const src = script . src || resourcePath
145+ const attrsQuery = attrsToQuery ( script . attrs , 'js' )
146+ const query = `?vue&type=script${ attrsQuery } ${ resourceQuery } `
147+ const scriptRequest = stringifyRequest ( src + query )
148+ scriptImport =
149+ `import script from ${ scriptRequest } \n` +
150+ // support named exports
151+ `export * from ${ scriptRequest } `
156152 }
157153
158154 // template
159155 let templateImport = ``
160156 let templateRequest
161157 const renderFnName = isServer ? `ssrRender` : `render`
162- if ( descriptor . template ) {
158+ const templateLang = descriptor . template && descriptor . template . lang
159+ const useInlineTemplate =
160+ descriptor . scriptSetup && isProduction && ! isServer && ! templateLang
161+ if ( descriptor . template && ! useInlineTemplate ) {
163162 const src = descriptor . template . src || resourcePath
164163 const idQuery = `&id=${ id } `
165164 const scopedQuery = hasScoped ? `&scoped=true` : ``
166165 const attrsQuery = attrsToQuery ( descriptor . template . attrs )
167- const bindingsQuery = script
168- ? `&bindings=${ JSON . stringify ( script . bindings ?? { } ) } `
169- : ``
170- const query = `?vue&type=template${ idQuery } ${ scopedQuery } ${ attrsQuery } ${ bindingsQuery } ${ resourceQuery } `
166+ // const bindingsQuery = script
167+ // ? `&bindings=${JSON.stringify(script.bindings ?? {})}`
168+ // : ``
169+ // const varsQuery = descriptor.cssVars
170+ // ? `&vars=${qs.escape(generateCssVars(descriptor, id, isProduction))}`
171+ // : ``
172+ const query = `?vue&type=template${ idQuery } ${ scopedQuery } ${ attrsQuery } ${ resourceQuery } `
171173 templateRequest = stringifyRequest ( src + query )
172174 templateImport = `import { ${ renderFnName } } from ${ templateRequest } `
173175 }
@@ -184,7 +186,7 @@ export default function loader(
184186 const attrsQuery = attrsToQuery ( style . attrs , 'css' )
185187 // make sure to only pass id when necessary so that we don't inject
186188 // duplicate tags when multiple components import the same css file
187- const idQuery = style . scoped ? `&id=${ id } ` : ``
189+ const idQuery = ! style . src || style . scoped ? `&id=${ id } ` : ``
188190 const query = `?vue&type=style&index=${ i } ${ idQuery } ${ attrsQuery } ${ resourceQuery } `
189191 const styleRequest = stringifyRequest ( src + query )
190192 if ( style . module ) {
0 commit comments