Skip to content
This repository was archived by the owner on Jan 18, 2022. It is now read-only.

Commit facf4c6

Browse files
committed
refactor: handle script compilation separately
1 parent 746acc3 commit facf4c6

File tree

6 files changed

+100
-71
lines changed

6 files changed

+100
-71
lines changed

Diff for: src/index.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { createCustomBlockFilter } from './utils/customBlockFilter'
2222
import { getDescriptor, setDescriptor } from './utils/descriptorCache'
2323
import { parseVuePartRequest } from './utils/query'
2424
import { normalizeSourceMap } from './utils/sourceMap'
25+
import { getResolvedScript } from './script'
2526

2627
const debug = createDebugger('rollup-plugin-vue')
2728

@@ -113,7 +114,7 @@ export default function PluginVue(userOptions: Partial<Options> = {}): Plugin {
113114
query.type === 'template'
114115
? descriptor.template!
115116
: query.type === 'script'
116-
? descriptor.scriptCompiled || descriptor.script
117+
? getResolvedScript(descriptor, isServer)
117118
: query.type === 'style'
118119
? descriptor.styles[query.index]
119120
: typeof query.index === 'number'

Diff for: src/script.ts

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { compileScript, SFCDescriptor, SFCScriptBlock } from '@vue/compiler-sfc'
2+
import { Options } from '.'
3+
import { getTemplateCompilerOptions } from './template'
4+
5+
// since we generate different output based on whether the template is inlined
6+
// or not, we need to cache the results separately
7+
const inlinedCache = new WeakMap<SFCDescriptor, SFCScriptBlock | null>()
8+
const normalCache = new WeakMap<SFCDescriptor, SFCScriptBlock | null>()
9+
10+
export function getResolvedScript(
11+
descriptor: SFCDescriptor,
12+
isServer: boolean
13+
): SFCScriptBlock | null | undefined {
14+
const cacheToUse = isServer ? normalCache : inlinedCache
15+
return cacheToUse.get(descriptor)
16+
}
17+
18+
export function resolveScript(
19+
descriptor: SFCDescriptor,
20+
scopeId: string,
21+
isProd: boolean,
22+
isServer: boolean,
23+
options: Options
24+
) {
25+
if (!descriptor.script && !descriptor.scriptSetup) {
26+
return null
27+
}
28+
29+
const cached = getResolvedScript(descriptor, isServer)
30+
if (cached) {
31+
return cached
32+
}
33+
34+
let resolved: SFCScriptBlock | null
35+
36+
if (compileScript) {
37+
resolved = compileScript(descriptor, {
38+
id: scopeId,
39+
isProd,
40+
inlineTemplate: !isServer,
41+
templateOptions: getTemplateCompilerOptions(options, descriptor, scopeId),
42+
})
43+
} else if (descriptor.scriptSetup) {
44+
throw new Error(
45+
`<script setup> is not supported by the installed version of ` +
46+
`@vue/compiler-sfc - please upgrade.`
47+
)
48+
} else {
49+
resolved = descriptor.script
50+
}
51+
52+
if (isServer) {
53+
normalCache.set(descriptor, resolved)
54+
} else {
55+
inlinedCache.set(descriptor, resolved)
56+
}
57+
58+
return resolved
59+
}

Diff for: src/sfc.ts

+28-59
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,16 @@
11
import hash from 'hash-sum'
22
import path from 'path'
33
import qs from 'querystring'
4-
import {
5-
compileScript,
6-
parse,
7-
SFCBlock,
8-
SFCDescriptor,
9-
SFCTemplateCompileOptions,
10-
} from '@vue/compiler-sfc'
4+
import { parse, SFCBlock, SFCDescriptor } from '@vue/compiler-sfc'
115
import { Options } from '.'
12-
import { getTemplateCompilerOptions } from './template'
136
import { setDescriptor } from './utils/descriptorCache'
147
import { TransformPluginContext } from 'rollup'
158
import { createRollupError } from './utils/error'
9+
import { resolveScript } from './script'
1610

1711
export function transformSFCEntry(
1812
code: string,
19-
resourcePath: string,
13+
filename: string,
2014
options: Options,
2115
sourceRoot: string,
2216
isProduction: boolean,
@@ -26,20 +20,20 @@ export function transformSFCEntry(
2620
) {
2721
const { descriptor, errors } = parse(code, {
2822
sourceMap: true,
29-
filename: resourcePath,
23+
filename,
3024
sourceRoot,
3125
})
32-
setDescriptor(resourcePath, descriptor)
26+
setDescriptor(filename, descriptor)
3327

3428
if (errors.length) {
3529
errors.forEach((error) =>
36-
pluginContext.error(createRollupError(resourcePath, error))
30+
pluginContext.error(createRollupError(filename, error))
3731
)
3832
return null
3933
}
4034

4135
const shortFilePath = path
42-
.relative(sourceRoot, resourcePath)
36+
.relative(sourceRoot, filename)
4337
.replace(/^(\.\.[\/\\])+/, '')
4438
.replace(/\\/g, '/')
4539
const scopeId = hash(
@@ -54,7 +48,7 @@ export function transformSFCEntry(
5448
(isServer || !descriptor.scriptSetup)
5549

5650
const templateImport = hasTemplateImport
57-
? genTemplateCode(descriptor, resourcePath, scopeId, isServer)
51+
? genTemplateCode(descriptor, scopeId, isServer)
5852
: ''
5953

6054
const renderReplace = hasTemplateImport
@@ -65,23 +59,13 @@ export function transformSFCEntry(
6559

6660
const scriptImport = genScriptCode(
6761
descriptor,
68-
resourcePath,
6962
scopeId,
7063
isProduction,
7164
isServer,
72-
getTemplateCompilerOptions(options, descriptor, scopeId)
73-
)
74-
const stylesCode = genStyleCode(
75-
descriptor,
76-
resourcePath,
77-
scopeId,
78-
options.preprocessStyles
79-
)
80-
const customBlocksCode = getCustomBlock(
81-
descriptor,
82-
resourcePath,
83-
filterCustomBlock
65+
options
8466
)
67+
const stylesCode = genStyleCode(descriptor, scopeId, options.preprocessStyles)
68+
const customBlocksCode = getCustomBlock(descriptor, filterCustomBlock)
8569
const output = [
8670
scriptImport,
8771
templateImport,
@@ -110,15 +94,14 @@ export function transformSFCEntry(
11094

11195
function genTemplateCode(
11296
descriptor: SFCDescriptor,
113-
resourcePath: string,
11497
id: string,
11598
isServer: boolean
11699
) {
117100
const renderFnName = isServer ? 'ssrRender' : 'render'
118101
let templateImport = `const ${renderFnName} = () => {}`
119102
let templateRequest
120103
if (descriptor.template) {
121-
const src = descriptor.template.src || resourcePath
104+
const src = descriptor.template.src || descriptor.filename
122105
const idQuery = `&id=${id}`
123106
const srcQuery = descriptor.template.src ? `&src` : ``
124107
const attrsQuery = attrsToQuery(descriptor.template.attrs, 'js', true)
@@ -132,48 +115,35 @@ function genTemplateCode(
132115

133116
function genScriptCode(
134117
descriptor: SFCDescriptor,
135-
resourcePath: string,
136-
id: string,
118+
scopeId: string,
137119
isProd: boolean,
138120
isServer: boolean,
139-
templateOptions?: Partial<SFCTemplateCompileOptions>
121+
options: Options
140122
) {
141123
let scriptImport = `const script = {}`
142-
if (descriptor.script || descriptor.scriptSetup) {
143-
if (compileScript) {
144-
descriptor.scriptCompiled = compileScript(descriptor, {
145-
id,
146-
isProd,
147-
inlineTemplate: !isServer,
148-
templateOptions,
149-
})
150-
}
151-
const script = descriptor.scriptCompiled || descriptor.script
152-
if (script) {
153-
const src = script.src || resourcePath
154-
const attrsQuery = attrsToQuery(script.attrs, 'js')
155-
const srcQuery = script.src ? `&src` : ``
156-
const query = `?vue&type=script${srcQuery}${attrsQuery}`
157-
const scriptRequest = JSON.stringify(src + query)
158-
scriptImport =
159-
`import script from ${scriptRequest}\n` +
160-
`export * from ${scriptRequest}` // support named exports
161-
}
124+
const script = resolveScript(descriptor, scopeId, isProd, isServer, options)
125+
if (script) {
126+
const src = script.src || descriptor.filename
127+
const attrsQuery = attrsToQuery(script.attrs, 'js')
128+
const srcQuery = script.src ? `&src` : ``
129+
const query = `?vue&type=script${srcQuery}${attrsQuery}`
130+
const scriptRequest = JSON.stringify(src + query)
131+
scriptImport =
132+
`import script from ${scriptRequest}\n` + `export * from ${scriptRequest}` // support named exports
162133
}
163134
return scriptImport
164135
}
165136

166137
function genStyleCode(
167138
descriptor: SFCDescriptor,
168-
resourcePath: string,
169-
id: string,
139+
scopeId: string,
170140
preprocessStyles?: boolean
171141
) {
172142
let stylesCode = ``
173143
let hasCSSModules = false
174144
if (descriptor.styles.length) {
175145
descriptor.styles.forEach((style, i) => {
176-
const src = style.src || resourcePath
146+
const src = style.src || descriptor.filename
177147
// do not include module in default query, since we use it to indicate
178148
// that the module needs to export the modules json
179149
const attrsQuery = attrsToQuery(style.attrs, 'css', preprocessStyles)
@@ -183,7 +153,7 @@ function genStyleCode(
183153
)
184154
// make sure to only pass id when necessary so that we don't inject
185155
// duplicate tags when multiple components import the same css file
186-
const idQuery = `&id=${id}`
156+
const idQuery = `&id=${scopeId}`
187157
const srcQuery = style.src ? `&src` : ``
188158
const query = `?vue&type=style&index=${i}${srcQuery}${idQuery}`
189159
const styleRequest = src + query + attrsQuery
@@ -194,7 +164,7 @@ function genStyleCode(
194164
hasCSSModules = true
195165
}
196166
stylesCode += genCSSModulesCode(
197-
id,
167+
scopeId,
198168
i,
199169
styleRequest,
200170
styleRequestWithoutModule,
@@ -211,14 +181,13 @@ function genStyleCode(
211181

212182
function getCustomBlock(
213183
descriptor: SFCDescriptor,
214-
resourcePath: string,
215184
filter: (type: string) => boolean
216185
) {
217186
let code = ''
218187

219188
descriptor.customBlocks.forEach((block, index) => {
220189
if (filter(block.type)) {
221-
const src = block.src || resourcePath
190+
const src = block.src || descriptor.filename
222191
const attrsQuery = attrsToQuery(block.attrs, block.type)
223192
const srcQuery = block.src ? `&src` : ``
224193
const query = `?vue&type=${block.type}&index=${index}${srcQuery}${attrsQuery}`

Diff for: src/style.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { normalizeSourceMap } from './utils/sourceMap'
1010

1111
export async function transformStyle(
1212
code: string,
13-
resourcePath: string,
13+
request: string,
1414
options: Options,
1515
query: StyleBlockQuery,
1616
isProduction: boolean,
@@ -79,7 +79,7 @@ export async function transformStyle(
7979
} else {
8080
return {
8181
code: result.code,
82-
map: normalizeSourceMap(result.map!, resourcePath),
82+
map: normalizeSourceMap(result.map!, request),
8383
}
8484
}
8585
}

Diff for: src/template.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@ import {
66
} from '@vue/compiler-sfc'
77
import { TransformPluginContext } from 'rollup'
88
import { Options } from '.'
9+
import { getResolvedScript } from './script'
910
import { getDescriptor } from './utils/descriptorCache'
1011
import { createRollupError } from './utils/error'
1112
import { TemplateBlockQuery } from './utils/query'
1213
import { normalizeSourceMap } from './utils/sourceMap'
1314

1415
export function transformTemplate(
1516
code: string,
16-
resourcePath: string,
17+
request: string,
1718
options: Options,
1819
query: TemplateBlockQuery,
1920
pluginContext: TransformPluginContext
@@ -47,7 +48,7 @@ export function transformTemplate(
4748

4849
return {
4950
code: result.code,
50-
map: normalizeSourceMap(result.map!, resourcePath),
51+
map: normalizeSourceMap(result.map!, request),
5152
}
5253
}
5354

@@ -70,6 +71,7 @@ export function getTemplateCompilerOptions(
7071
preprocessLang &&
7172
options.templatePreprocessOptions &&
7273
options.templatePreprocessOptions[preprocessLang]
74+
const resolvedScript = getResolvedScript(descriptor, isServer)
7375
return {
7476
filename: descriptor.filename,
7577
inMap: block.src ? undefined : block.map,
@@ -81,9 +83,7 @@ export function getTemplateCompilerOptions(
8183
compilerOptions: {
8284
...options.compilerOptions,
8385
scopeId: hasScoped ? `data-v-${scopeId}` : undefined,
84-
bindingMetadata: descriptor.scriptCompiled
85-
? descriptor.scriptCompiled.bindings
86-
: undefined,
86+
bindingMetadata: resolvedScript ? resolvedScript.bindings : undefined,
8787
ssrCssVars: isServer
8888
? generateCssVars(descriptor, scopeId, isProduction)
8989
: undefined,

Diff for: src/utils/sourceMap.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ import { SFCTemplateCompileResults } from '@vue/compiler-sfc'
22

33
export function normalizeSourceMap(
44
map: SFCTemplateCompileResults['map'],
5-
id: string
5+
request: string
66
): any {
77
if (!map) return null as any
88

9-
if (!id.includes('type=script')) {
10-
map.file = id
11-
map.sources[0] = id
9+
if (!request.includes('type=script')) {
10+
map.file = request
11+
map.sources[0] = request
1212
}
1313

1414
return {

0 commit comments

Comments
 (0)