Skip to content

Commit fe1848c

Browse files
committed
fix(plugin-vue): ensure id on descriptor
1 parent 7680773 commit fe1848c

File tree

4 files changed

+59
-42
lines changed

4 files changed

+59
-42
lines changed

packages/plugin-vue/src/handleHotUpdate.ts

+11-9
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import fs from 'fs'
22
import _debug from 'debug'
3-
import { parse, SFCBlock, SFCDescriptor } from '@vue/compiler-sfc'
3+
import { SFCBlock, SFCDescriptor } from '@vue/compiler-sfc'
44
import {
5+
createDescriptor,
56
getDescriptor,
6-
setDescriptor,
77
setPrevDescriptor
88
} from './utils/descriptorCache'
99
import { getResolvedScript, setResolvedScript } from './script'
10-
import { ModuleNode } from 'vite'
10+
import { ModuleNode, ViteDevServer } from 'vite'
1111

1212
const debug = _debug('vite:hmr')
1313

@@ -16,7 +16,8 @@ const debug = _debug('vite:hmr')
1616
*/
1717
export async function handleHotUpdate(
1818
file: string,
19-
modules: ModuleNode[]
19+
modules: ModuleNode[],
20+
server: ViteDevServer
2021
): Promise<ModuleNode[] | void> {
2122
if (!file.endsWith('.vue')) {
2223
return
@@ -34,12 +35,13 @@ export async function handleHotUpdate(
3435
content = fs.readFileSync(file, 'utf-8')
3536
}
3637

37-
const { descriptor } = parse(content, {
38-
filename: file,
39-
sourceMap: true
40-
})
41-
setDescriptor(file, descriptor)
4238
setPrevDescriptor(file, prevDescriptor)
39+
const { descriptor } = createDescriptor(
40+
file,
41+
content,
42+
server.config.root,
43+
false
44+
)
4345

4446
let needRerender = false
4547
const affectedModules = new Set<ModuleNode | undefined>()

packages/plugin-vue/src/main.ts

+9-30
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,7 @@
1-
import hash from 'hash-sum'
2-
import path from 'path'
31
import qs from 'querystring'
4-
import {
5-
parse,
6-
rewriteDefault,
7-
SFCBlock,
8-
SFCDescriptor
9-
} from '@vue/compiler-sfc'
2+
import { rewriteDefault, SFCBlock, SFCDescriptor } from '@vue/compiler-sfc'
103
import { ResolvedOptions } from '.'
11-
import { getPrevDescriptor, setDescriptor } from './utils/descriptorCache'
4+
import { createDescriptor, getPrevDescriptor } from './utils/descriptorCache'
125
import { PluginContext, TransformPluginContext } from 'rollup'
136
import { resolveScript } from './script'
147
import { transformTemplateInMain } from './template'
@@ -26,23 +19,13 @@ export async function transformMain(
2619

2720
// prev descriptor is only set and used for hmr
2821
const prevDescriptor = getPrevDescriptor(filename)
29-
const { descriptor, errors } = parse(code, {
30-
sourceMap: true,
31-
filename
32-
})
33-
34-
// set the id on the descriptor
35-
const shortFilePath = path
36-
.relative(root, filename)
37-
.replace(/^(\.\.[\/\\])+/, '')
38-
.replace(/\\/g, '/')
39-
40-
descriptor.id = hash(
41-
isProduction ? shortFilePath + '\n' + code : shortFilePath
22+
const { descriptor, errors } = createDescriptor(
23+
filename,
24+
code,
25+
root,
26+
isProduction
4227
)
4328

44-
setDescriptor(filename, descriptor)
45-
4629
if (errors.length) {
4730
errors.forEach((error) =>
4831
pluginContext.error(createRollupError(filename, error))
@@ -100,13 +83,9 @@ export async function transformMain(
10083
`_sfc_main.__scopeId = ${JSON.stringify(`data-v-${descriptor.id}`)}`
10184
)
10285
}
103-
if (!isProduction) {
104-
output.push(`_sfc_main.__file = ${JSON.stringify(shortFilePath)}`)
105-
} else if (devServer) {
86+
if (devServer) {
10687
// expose filename during serve for devtools to pickup
107-
output.push(
108-
`_sfc_main.__file = ${JSON.stringify(path.basename(shortFilePath))}`
109-
)
88+
output.push(`_sfc_main.__file = ${JSON.stringify(filename)}`)
11089
}
11190
output.push('export default _sfc_main')
11291

packages/plugin-vue/src/utils/descriptorCache.ts

+22-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,29 @@
1-
import { SFCDescriptor } from '@vue/compiler-sfc'
1+
import path from 'path'
2+
import slash from 'slash'
3+
import hash from 'hash-sum'
4+
import { parse, SFCDescriptor } from '@vue/compiler-sfc'
25

36
const cache = new Map<string, SFCDescriptor>()
47
const prevCache = new Map<string, SFCDescriptor | undefined>()
58

6-
export function setDescriptor(filename: string, entry: SFCDescriptor) {
7-
cache.set(filename, entry)
9+
export function createDescriptor(
10+
filename: string,
11+
source: string,
12+
root: string,
13+
isProduction: boolean | undefined
14+
) {
15+
const { descriptor, errors } = parse(source, {
16+
filename,
17+
sourceMap: true
18+
})
19+
20+
// ensure the path is normalized in a way that is consistent inside
21+
// project (relative to root) and on different systems.
22+
const normalizedPath = slash(path.normalize(path.relative(root, filename)))
23+
descriptor.id = hash(normalizedPath + (isProduction ? source : ''))
24+
25+
cache.set(filename, descriptor)
26+
return { descriptor, errors }
827
}
928

1029
export function getPrevDescriptor(filename: string) {
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import path from 'path'
2+
import slash from 'slash'
3+
import hash from 'hash-sum'
4+
import { SFCDescriptor } from '@vue/compiler-sfc'
5+
6+
export function genScopeId(
7+
descriptor: SFCDescriptor,
8+
root: string,
9+
isProduction = false
10+
) {
11+
// ensure the path is normalized in a way that is consistent inside
12+
// project (relative to root) and on different systems.
13+
const normalizedPath = slash(
14+
path.normalize(path.relative(root, descriptor.filename))
15+
)
16+
return hash(normalizedPath + (isProduction ? descriptor.source : ''))
17+
}

0 commit comments

Comments
 (0)