Skip to content

Commit b85244b

Browse files
committed
feat: support for experimental sfc features
- new `<script setup>` vuejs/rfcs#227 - new `<style>` variable injection vuejs/rfcs#231 Requires a version of `@vue/compiler-sfc` that supports the above features. Also should fix #1723
1 parent fd33cad commit b85244b

File tree

4 files changed

+31
-23
lines changed

4 files changed

+31
-23
lines changed

example/ScriptSetup.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ function inc() {
1717
count.value++
1818
}
1919
20-
const hello = 'hi from script'
20+
const hello = 'hi from scriptttt'
2121
22-
const color = ref('cyan')
22+
const color = ref('red')
2323
const changeColor = () => {
2424
color.value = color.value === 'red' ? 'green' : 'red'
2525
}

src/index.ts

+2-4
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import { genCSSModulesCode } from './cssModules'
2929
import { formatError } from './formatError'
3030

3131
import VueLoaderPlugin from './plugin'
32-
import { resolveScript } from './resolveScript'
32+
import { canInlineTemplate, resolveScript } from './resolveScript'
3333
import { setDescriptor } from './descriptorCache'
3434

3535
export { VueLoaderPlugin }
@@ -155,9 +155,7 @@ export default function loader(
155155
let templateImport = ``
156156
let templateRequest
157157
const renderFnName = isServer ? `ssrRender` : `render`
158-
const templateLang = descriptor.template && descriptor.template.lang
159-
const useInlineTemplate =
160-
descriptor.scriptSetup && isProduction && !isServer && !templateLang
158+
const useInlineTemplate = canInlineTemplate(descriptor, isProduction)
161159
if (descriptor.template && !useInlineTemplate) {
162160
const src = descriptor.template.src || resourcePath
163161
const idQuery = `&id=${id}`

src/resolveScript.ts

+19-9
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,20 @@ import {
77
} from '@vue/compiler-sfc'
88
import { VueLoaderOptions } from 'src'
99

10-
// since we generate different output based on whether the template is inlined
11-
// or not, we need to cache the results separately
12-
const inlinedCache = new WeakMap<SFCDescriptor, SFCScriptBlock | null>()
13-
const normalCache = new WeakMap<SFCDescriptor, SFCScriptBlock | null>()
10+
const clientCache = new WeakMap<SFCDescriptor, SFCScriptBlock | null>()
11+
const serverCache = new WeakMap<SFCDescriptor, SFCScriptBlock | null>()
12+
13+
/**
14+
* inline template mode can only be enabled if:
15+
* - is production (separate compilation needed for HMR during dev)
16+
* - template has no pre-processor (separate loader chain required)
17+
* - template is not using src
18+
*/
19+
export function canInlineTemplate(descriptor: SFCDescriptor, isProd: boolean) {
20+
const templateLang = descriptor.template && descriptor.template.lang
21+
const templateSrc = descriptor.template && descriptor.template.src
22+
return isProd && !!descriptor.scriptSetup && !templateLang && !templateSrc
23+
}
1424

1525
export function resolveScript(
1626
descriptor: SFCDescriptor,
@@ -24,10 +34,9 @@ export function resolveScript(
2434

2535
const isProd = loaderContext.mode === 'production'
2636
const isServer = loaderContext.target === 'node'
27-
const templateLang = descriptor.template && descriptor.template.lang
28-
const enableInline = isProd && !isServer && !templateLang
37+
const enableInline = canInlineTemplate(descriptor, isProd)
2938

30-
const cacheToUse = enableInline ? inlinedCache : normalCache
39+
const cacheToUse = isServer ? serverCache : clientCache
3140
const cached = cacheToUse.get(descriptor)
3241
if (cached) {
3342
return cached
@@ -45,13 +54,14 @@ export function resolveScript(
4554
if (compileScript) {
4655
try {
4756
resolved = compileScript(descriptor, {
48-
// @ts-ignore TODO remove when vue is upgraded
49-
scopeId,
57+
// @ts-ignore
58+
id: scopeId,
5059
isProd,
5160
inlineTemplate: enableInline,
5261
babelParserPlugins: options.babelParserPlugins,
5362
templateOptions: {
5463
compiler,
64+
ssr: isServer,
5565
transformAssetUrls: options.transformAssetUrls || true,
5666
},
5767
})

src/templateLoader.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,7 @@ import * as qs from 'querystring'
33
import * as loaderUtils from 'loader-utils'
44
import { VueLoaderOptions } from './'
55
import { formatError } from './formatError'
6-
import {
7-
compileTemplate,
8-
generateCssVars,
9-
TemplateCompiler,
10-
} from '@vue/compiler-sfc'
6+
import { compileTemplate, TemplateCompiler } from '@vue/compiler-sfc'
117
import { getDescriptor } from './descriptorCache'
128
import { resolveScript } from './resolveScript'
139

@@ -25,7 +21,7 @@ const TemplateLoader: webpack.loader.Loader = function (source, inMap) {
2521
{}) as VueLoaderOptions
2622

2723
const isServer = loaderContext.target === 'node'
28-
const isProduction = loaderContext.mode === 'production'
24+
const isProd = loaderContext.mode === 'production'
2925
const query = qs.parse(loaderContext.resourceQuery.slice(1))
3026
const scopeId = query.id as string
3127
const descriptor = getDescriptor(loaderContext.resourcePath)
@@ -45,13 +41,17 @@ const TemplateLoader: webpack.loader.Loader = function (source, inMap) {
4541

4642
const compiled = compileTemplate({
4743
source,
48-
inMap,
4944
filename: loaderContext.resourcePath,
45+
inMap,
46+
// @ts-ignore
47+
id: scopeId,
48+
isProd,
5049
ssr: isServer,
50+
// @ts-ignore
51+
ssrCssVars: descriptor.cssVars,
5152
compiler,
5253
compilerOptions: {
5354
...options.compilerOptions,
54-
ssrCssVars: generateCssVars(descriptor, scopeId, isProduction),
5555
scopeId: query.scoped ? `data-v-${scopeId}` : undefined,
5656
bindingMetadata: script ? script.bindings : undefined,
5757
},

0 commit comments

Comments
 (0)