Skip to content

Commit e44af73

Browse files
committed
fix: pass some hmr invalidate tests
1 parent e8eae41 commit e44af73

File tree

6 files changed

+107
-70
lines changed

6 files changed

+107
-70
lines changed

packages/vite/src/client/client.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ export function removeStyle(id: string): void {
455455
}
456456

457457
export function createHotContext(ownerPath: string): ViteHotContext {
458-
return new HMRContext(hmrClient, ownerPath)
458+
return new HMRContext(hmrClient, ownerPath, __FULL_BUNDLE_MODE__)
459459
}
460460

461461
/**

packages/vite/src/module-runner/runner.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ export class ModuleRunner {
7777
resolvedHmrLogger,
7878
this.transport,
7979
({ acceptedPath }) => this.import(acceptedPath),
80+
false,
8081
)
8182
if (!this.transport.connect) {
8283
throw new Error(
@@ -391,7 +392,7 @@ export class ModuleRunner {
391392
throw new Error(`[module runner] HMR client was closed.`)
392393
}
393394
this.debug?.('[module runner] creating hmr context for', mod.url)
394-
hotContext ||= new HMRContext(this.hmrClient, mod.url)
395+
hotContext ||= new HMRContext(this.hmrClient, mod.url, false)
395396
return hotContext
396397
},
397398
set: (value) => {

packages/vite/src/node/build.ts

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -925,24 +925,24 @@ async function buildEnvironment(
925925
}
926926

927927
if (server) {
928-
server.watcher.on('change', async (file) => {
929-
const startTime = Date.now()
930-
const hmrOutput = (await bundle!.generateHmrPatch([file]))!
928+
async function handleHmrOutput(hmrOutput: any, file: string) {
931929
// @ts-expect-error Need to upgrade rolldown
932930
if (hmrOutput.fullReload) {
933-
await build()
934-
server.ws.send({
931+
if (!hmrOutput.firstInvalidatedBy) {
932+
await build()
933+
}
934+
server!.ws.send({
935935
type: 'full-reload',
936936
})
937937
logger.info(colors.green(`page reload `) + colors.dim(file), {
938-
clear: true,
938+
clear: !hmrOutput.firstInvalidatedBy,
939939
timestamp: true,
940940
})
941941
}
942942

943943
if (hmrOutput.patch) {
944944
const url = `${Date.now()}.js`
945-
server.memoryFiles[url] = hmrOutput.patch
945+
server!.memoryFiles[url] = hmrOutput.patch
946946
const updates = hmrOutput.hmrBoundaries.map((boundary) => {
947947
return {
948948
type: 'js-update',
@@ -952,22 +952,53 @@ async function buildEnvironment(
952952
timestamp: 0,
953953
}
954954
}) as Update[]
955-
server.ws.send({
955+
server!.ws.send({
956956
type: 'update',
957957
updates,
958958
})
959959
logger.info(
960960
colors.green(`hmr update `) +
961961
colors.dim([...new Set(updates.map((u) => u.path))].join(', ')),
962-
{ clear: true, timestamp: true },
962+
{ clear: !hmrOutput.firstInvalidatedBy, timestamp: true },
963963
)
964+
}
965+
}
964966

967+
server.watcher.on('change', async (file) => {
968+
const startTime = Date.now()
969+
const hmrOutput = (await bundle!.generateHmrPatch([file]))!
970+
// TODO(underfin): rebuild at first could be work.
971+
if (hmrOutput.patch) {
965972
await build()
966973
logger.info(
967974
`${colors.green(`✓ rebuilt in ${displayTime(Date.now() - startTime)}`)}`,
968975
)
969976
}
977+
await handleHmrOutput(hmrOutput, file)
978+
979+
// TODO(underfin): The invalidate case is failed because the hmrInvalidate is hang after rebuild at here .
970980
})
981+
server.hot.on(
982+
'vite:invalidate',
983+
async ({ path: file, message, firstInvalidatedBy }) => {
984+
file = path.join(root, file)
985+
const hmrOutput = (await bundle!.hmrInvalidate(
986+
file,
987+
firstInvalidatedBy,
988+
))!
989+
if (hmrOutput) {
990+
if (hmrOutput.isSelfAccepting) {
991+
logger.info(
992+
colors.yellow(`hmr invalidate `) +
993+
colors.dim(file) +
994+
(message ? ` ${message}` : ''),
995+
{ timestamp: true },
996+
)
997+
await handleHmrOutput(hmrOutput, file)
998+
}
999+
}
1000+
},
1001+
)
9711002
}
9721003

9731004
return Array.isArray(outputs) ? res : res[0]

packages/vite/src/node/server/environment.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -134,18 +134,21 @@ export class DevEnvironment extends BaseEnvironment {
134134
},
135135
})
136136

137-
this.hot.on(
138-
'vite:invalidate',
139-
async ({ path, message, firstInvalidatedBy }) => {
140-
invalidateModule(this, {
141-
path,
142-
message,
143-
firstInvalidatedBy,
144-
})
145-
},
146-
)
147-
148137
const { optimizeDeps, experimental } = this.config
138+
139+
if (!experimental.fullBundleMode) {
140+
this.hot.on(
141+
'vite:invalidate',
142+
async ({ path, message, firstInvalidatedBy }) => {
143+
invalidateModule(this, {
144+
path,
145+
message,
146+
firstInvalidatedBy,
147+
})
148+
},
149+
)
150+
}
151+
149152
if (context.depsOptimizer && !experimental.fullBundleMode) {
150153
this.depsOptimizer = context.depsOptimizer
151154
} else if (isDepOptimizationDisabled(optimizeDeps)) {

packages/vite/src/shared/hmr.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export class HMRContext implements ViteHotContext {
2727
constructor(
2828
private hmrClient: HMRClient,
2929
private ownerPath: string,
30+
private fullBundleMode: boolean,
3031
) {
3132
if (!hmrClient.dataMap.has(ownerPath)) {
3233
hmrClient.dataMap.set(ownerPath, {})
@@ -99,18 +100,21 @@ export class HMRContext implements ViteHotContext {
99100
invalidate(message: string): void {
100101
const firstInvalidatedBy =
101102
this.hmrClient.currentFirstInvalidatedBy ?? this.ownerPath
103+
const ownerPath = this.fullBundleMode
104+
? `/${this.ownerPath}`
105+
: this.ownerPath
102106
this.hmrClient.notifyListeners('vite:invalidate', {
103-
path: this.ownerPath,
107+
path: ownerPath,
104108
message,
105109
firstInvalidatedBy,
106110
})
107111
this.send('vite:invalidate', {
108-
path: this.ownerPath,
112+
path: ownerPath,
109113
message,
110114
firstInvalidatedBy,
111115
})
112116
this.hmrClient.logger.debug(
113-
`invalidate ${this.ownerPath}${message ? `: ${message}` : ''}`,
117+
`invalidate ${ownerPath}${message ? `: ${message}` : ''}`,
114118
)
115119
}
116120

playground/hmr/__tests__/hmr.spec.ts

Lines changed: 43 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,35 @@ if (!isBuild) {
153153
await untilUpdated(() => el.textContent(), '3')
154154
})
155155

156-
if (!process.env.VITE_TEST_FULL_BUNDLE_MODE) {
157-
test('invalidate', async () => {
156+
test('invalidate', async () => {
157+
const el = await page.$('.invalidation-parent')
158+
await untilBrowserLogAfter(
159+
() =>
160+
editFile('invalidation/child.js', (code) =>
161+
code.replace('child', 'child updated'),
162+
),
163+
[
164+
'>>> vite:beforeUpdate -- update',
165+
'>>> vite:invalidate -- /invalidation/child.js',
166+
'[vite] invalidate /invalidation/child.js',
167+
'[vite] hot updated: /invalidation/child.js',
168+
'>>> vite:afterUpdate -- update',
169+
'>>> vite:beforeUpdate -- update',
170+
'(invalidation) parent is executing',
171+
'[vite] hot updated: /invalidation/parent.js',
172+
'>>> vite:afterUpdate -- update',
173+
],
174+
true,
175+
)
176+
await untilUpdated(() => el.textContent(), 'child updated')
177+
})
178+
179+
test('invalidate works with multiple tabs', async () => {
180+
let page2: Page
181+
try {
182+
page2 = await browser.newPage()
183+
await page2.goto(viteTestUrl)
184+
158185
const el = await page.$('.invalidation-parent')
159186
await untilBrowserLogAfter(
160187
() =>
@@ -167,6 +194,7 @@ if (!isBuild) {
167194
'[vite] invalidate /invalidation/child.js',
168195
'[vite] hot updated: /invalidation/child.js',
169196
'>>> vite:afterUpdate -- update',
197+
// if invalidate dedupe doesn't work correctly, this beforeUpdate will be called twice
170198
'>>> vite:beforeUpdate -- update',
171199
'(invalidation) parent is executing',
172200
'[vite] hot updated: /invalidation/parent.js',
@@ -175,51 +203,21 @@ if (!isBuild) {
175203
true,
176204
)
177205
await untilUpdated(() => el.textContent(), 'child updated')
178-
})
179-
180-
test('invalidate works with multiple tabs', async () => {
181-
let page2: Page
182-
try {
183-
page2 = await browser.newPage()
184-
await page2.goto(viteTestUrl)
185-
186-
const el = await page.$('.invalidation-parent')
187-
await untilBrowserLogAfter(
188-
() =>
189-
editFile('invalidation/child.js', (code) =>
190-
code.replace('child', 'child updated'),
191-
),
192-
[
193-
'>>> vite:beforeUpdate -- update',
194-
'>>> vite:invalidate -- /invalidation/child.js',
195-
'[vite] invalidate /invalidation/child.js',
196-
'[vite] hot updated: /invalidation/child.js',
197-
'>>> vite:afterUpdate -- update',
198-
// if invalidate dedupe doesn't work correctly, this beforeUpdate will be called twice
199-
'>>> vite:beforeUpdate -- update',
200-
'(invalidation) parent is executing',
201-
'[vite] hot updated: /invalidation/parent.js',
202-
'>>> vite:afterUpdate -- update',
203-
],
204-
true,
205-
)
206-
await untilUpdated(() => el.textContent(), 'child updated')
207-
} finally {
208-
await page2.close()
209-
}
210-
})
206+
} finally {
207+
await page2.close()
208+
}
209+
})
211210

212-
test('invalidate on root triggers page reload', async () => {
213-
editFile('invalidation/root.js', (code) =>
214-
code.replace('Init', 'Updated'),
215-
)
216-
await page.waitForEvent('load')
217-
await untilUpdated(
218-
async () => (await page.$('.invalidation-root')).textContent(),
219-
'Updated',
220-
)
221-
})
211+
test('invalidate on root triggers page reload', async () => {
212+
editFile('invalidation/root.js', (code) => code.replace('Init', 'Updated'))
213+
await page.waitForEvent('load')
214+
await untilUpdated(
215+
async () => (await page.$('.invalidation-root')).textContent(),
216+
'Updated',
217+
)
218+
})
222219

220+
if (!process.env.VITE_TEST_FULL_BUNDLE_MODE) {
223221
test('soft invalidate', async () => {
224222
const el = await page.$('.soft-invalidation')
225223
expect(await el.textContent()).toBe(

0 commit comments

Comments
 (0)