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

Commit dce3427

Browse files
fix(compiler): inject code location error when having multiple components in one file (#168)
1 parent bbf94f4 commit dce3427

File tree

6 files changed

+88
-19
lines changed

6 files changed

+88
-19
lines changed

packages/core/src/compiler/__test__/__snapshots__/analyze.test.ts.snap

+45
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,51 @@ return () => <div></div>
5454
"
5555
`;
5656
57+
exports[`analyzeCode - rerender - [jt]sx? > multiple component in one file 1`] = `
58+
"
59+
;import { getCurrentInstance as __VUE_DEVTOOLS_$getCurrentInstance__, onRenderTracked as __VUE_DEVTOOLS_$onRenderTracked__, onRenderTriggered as __VUE_DEVTOOLS_$onRenderTriggered__ } from 'vue'
60+
;
61+
62+
import { ref, h } from 'vue'
63+
const comp = defineComponent({
64+
setup() {
65+
const a = ref<number>(1)
66+
67+
68+
;__VUE_DEVTOOLS_$onRenderTriggered__((e) => {
69+
const instance = __VUE_DEVTOOLS_$getCurrentInstance__()
70+
window.__VUE_DEVTOOLS_GLOBAL_HOOK__?.emit?.('render:triggered', e, instance)
71+
});
72+
73+
74+
;__VUE_DEVTOOLS_$onRenderTracked__((e) => {
75+
const instance = __VUE_DEVTOOLS_$getCurrentInstance__()
76+
window.__VUE_DEVTOOLS_GLOBAL_HOOK__?.emit?.('render:tracked', e, instance)
77+
});
78+
return () => h('div', '1')
79+
}
80+
})
81+
const comp2 = defineComponent({
82+
setup() {
83+
const a = ref<number>(1)
84+
85+
86+
;__VUE_DEVTOOLS_$onRenderTriggered__((e) => {
87+
const instance = __VUE_DEVTOOLS_$getCurrentInstance__()
88+
window.__VUE_DEVTOOLS_GLOBAL_HOOK__?.emit?.('render:triggered', e, instance)
89+
});
90+
91+
92+
;__VUE_DEVTOOLS_$onRenderTracked__((e) => {
93+
const instance = __VUE_DEVTOOLS_$getCurrentInstance__()
94+
window.__VUE_DEVTOOLS_GLOBAL_HOOK__?.emit?.('render:tracked', e, instance)
95+
});
96+
return () => h('div', '1')
97+
}
98+
})
99+
"
100+
`;
101+
57102
exports[`analyzeCode - rerender - [jt]sx? > ts 1`] = `
58103
"
59104
;import { getCurrentInstance as __VUE_DEVTOOLS_$getCurrentInstance__, onRenderTracked as __VUE_DEVTOOLS_$onRenderTracked__, onRenderTriggered as __VUE_DEVTOOLS_$onRenderTriggered__ } from 'vue'

packages/core/src/compiler/__test__/analyze.test.ts

+19
Original file line numberDiff line numberDiff line change
@@ -137,4 +137,23 @@ describe('analyzeCode - rerender - [jt]sx?', () => {
137137
const result = analyzeCode(code, 'test.ts', baseConfig)
138138
expect(result?.code).toMatchSnapshot()
139139
})
140+
test('multiple component in one file', () => {
141+
const code = `
142+
import { ref, h } from 'vue'
143+
const comp = defineComponent({
144+
setup() {
145+
const a = ref<number>(1)
146+
return () => h('div', '1')
147+
}
148+
})
149+
const comp2 = defineComponent({
150+
setup() {
151+
const a = ref<number>(1)
152+
return () => h('div', '1')
153+
}
154+
})
155+
`
156+
const result = analyzeCode(code, 'test.ts', baseConfig)
157+
expect(result?.code).toMatchSnapshot()
158+
})
140159
})

packages/core/src/compiler/__test__/index.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import MagicString from 'magic-string'
22
import { analyzeByTraceRerender } from '../trace-rerender'
33

44
test('trace-rerender', () => {
5-
const ms = analyzeByTraceRerender(new MagicString(''), { start: 0, end: 0 })
5+
const ms = analyzeByTraceRerender(new MagicString(''), [{ start: 0, end: 0 }])
66
expect(ms.toString()).toMatchInlineSnapshot(`
77
"
88
;import { getCurrentInstance as __VUE_DEVTOOLS_$getCurrentInstance__, onRenderTracked as __VUE_DEVTOOLS_$onRenderTracked__, onRenderTriggered as __VUE_DEVTOOLS_$onRenderTriggered__ } from 'vue'

packages/core/src/compiler/common/analyze.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -55,25 +55,25 @@ export function analyzeVueSFC(code: string, filename: string) {
5555
export function analyzeScriptFile(code: string, lang: string) {
5656
if (!code.trim().length || !code.includes(DEFINE_COMPONENT))
5757
return null
58-
let location: InsertLocation | null = null
58+
const location: (InsertLocation | null)[] = []
5959
const ast = babelParse(code, lang)
6060
walkAST(ast, {
6161
enter(node) {
6262
if (isCallOf(node, DEFINE_COMPONENT) && node.arguments[0] && node.arguments[0].type === 'ObjectExpression') {
6363
for (const stmt of node.arguments[0].properties) {
6464
if (isSetupFn(stmt)) {
6565
const loc = getObjectFnBodyLocation(stmt)
66-
location = loc
66+
location.push(loc
6767
? {
6868
start: ast.start ?? 0,
6969
end: loc.end,
7070
}
71-
: null
71+
: null)
7272
this.skip()
7373
}
7474
}
7575
}
7676
},
7777
})
78-
return location
78+
return location.filter(Boolean) as InsertLocation[]
7979
}

packages/core/src/compiler/index.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -39,23 +39,25 @@ export function analyzeCode(code: string, filename: string, options: AnalyzeOpti
3939
if (!isAcceptableLang(filename) || !enableAnalyze(options) || hitPaths(filename, excludePaths))
4040
return null
4141

42-
let location: InsertLocation | null = null
42+
let locations: InsertLocation[] | null = null
4343

4444
if (isVUE(filename)) {
45-
location = analyzeVueSFC(code, filename)
45+
const location = analyzeVueSFC(code, filename)
46+
if (location)
47+
locations = [location]
4648
}
4749
else {
4850
const lang = filename.split('.').pop()!
49-
location = analyzeScriptFile(code, lang)
51+
locations = analyzeScriptFile(code, lang)
5052
}
5153

52-
if (!location)
54+
if (!locations || !locations.length)
5355
return null
5456

5557
let ms = new MagicString(code)
5658

5759
if (options.rerenderTrace)
58-
ms = analyzeByTraceRerender(ms, location)
60+
ms = analyzeByTraceRerender(ms, locations as InsertLocation[])
5961

6062
return {
6163
code: ms.toString(),

packages/core/src/compiler/trace-rerender.ts

+12-9
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type MS from 'magic-string'
22
import { entries } from './common/utils'
33
import { type InsertLocation, ensureImport } from './common'
44

5-
export function analyzeByTraceRerender(code: MS, location: InsertLocation) {
5+
export function analyzeByTraceRerender(code: MS, locations: InsertLocation[]) {
66
const apiNames = {
77
getCurrentInstance: '__VUE_DEVTOOLS_$getCurrentInstance__',
88
onRenderTracked: '__VUE_DEVTOOLS_$onRenderTracked__',
@@ -22,14 +22,17 @@ export function analyzeByTraceRerender(code: MS, location: InsertLocation) {
2222
});\n`,
2323
}
2424

25-
code = ensureImport(code, {
26-
vue: entries(apiNames).map(([id, alias]) => ({
27-
id, alias,
28-
})),
29-
}, location.start)
30-
31-
entries(injectedCodes).forEach(([, appendCode]) => {
32-
code.prependLeft(location.end, appendCode)
25+
locations.forEach(({ start, end }, idx) => {
26+
if (idx === 0) {
27+
code = ensureImport(code, {
28+
vue: entries(apiNames).map(([id, alias]) => ({
29+
id, alias,
30+
})),
31+
}, start)
32+
}
33+
entries(injectedCodes).forEach(([, appendCode]) => {
34+
code.prependLeft(end, appendCode)
35+
})
3336
})
3437

3538
return code

0 commit comments

Comments
 (0)