Skip to content

Commit 9d26977

Browse files
committed
fix: pass some hmr invalidate tests
1 parent ccb67c4 commit 9d26977

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
@@ -929,24 +929,24 @@ async function buildEnvironment(
929929
}
930930

931931
if (server) {
932-
server.watcher.on('change', async (file) => {
933-
const startTime = Date.now()
934-
const hmrOutput = (await bundle!.generateHmrPatch([file]))!
932+
async function handleHmrOutput(hmrOutput: any, file: string) {
935933
// @ts-expect-error Need to upgrade rolldown
936934
if (hmrOutput.fullReload) {
937-
await build()
938-
server.ws.send({
935+
if (!hmrOutput.firstInvalidatedBy) {
936+
await build()
937+
}
938+
server!.ws.send({
939939
type: 'full-reload',
940940
})
941941
logger.info(colors.green(`page reload `) + colors.dim(file), {
942-
clear: true,
942+
clear: !hmrOutput.firstInvalidatedBy,
943943
timestamp: true,
944944
})
945945
}
946946

947947
if (hmrOutput.patch) {
948948
const url = `${Date.now()}.js`
949-
server.memoryFiles[url] = hmrOutput.patch
949+
server!.memoryFiles[url] = hmrOutput.patch
950950
const updates = hmrOutput.hmrBoundaries.map((boundary) => {
951951
return {
952952
type: 'js-update',
@@ -956,22 +956,53 @@ async function buildEnvironment(
956956
timestamp: 0,
957957
}
958958
}) as Update[]
959-
server.ws.send({
959+
server!.ws.send({
960960
type: 'update',
961961
updates,
962962
})
963963
logger.info(
964964
colors.green(`hmr update `) +
965965
colors.dim([...new Set(updates.map((u) => u.path))].join(', ')),
966-
{ clear: true, timestamp: true },
966+
{ clear: !hmrOutput.firstInvalidatedBy, timestamp: true },
967967
)
968+
}
969+
}
968970

971+
server.watcher.on('change', async (file) => {
972+
const startTime = Date.now()
973+
const hmrOutput = (await bundle!.generateHmrPatch([file]))!
974+
// TODO(underfin): rebuild at first could be work.
975+
if (hmrOutput.patch) {
969976
await build()
970977
logger.info(
971978
`${colors.green(`✓ rebuilt in ${displayTime(Date.now() - startTime)}`)}`,
972979
)
973980
}
981+
await handleHmrOutput(hmrOutput, file)
982+
983+
// TODO(underfin): The invalidate case is failed because the hmrInvalidate is hang after rebuild at here .
974984
})
985+
server.hot.on(
986+
'vite:invalidate',
987+
async ({ path: file, message, firstInvalidatedBy }) => {
988+
file = path.join(root, file)
989+
const hmrOutput = (await bundle!.hmrInvalidate(
990+
file,
991+
firstInvalidatedBy,
992+
))!
993+
if (hmrOutput) {
994+
if (hmrOutput.isSelfAccepting) {
995+
logger.info(
996+
colors.yellow(`hmr invalidate `) +
997+
colors.dim(file) +
998+
(message ? ` ${message}` : ''),
999+
{ timestamp: true },
1000+
)
1001+
await handleHmrOutput(hmrOutput, file)
1002+
}
1003+
}
1004+
},
1005+
)
9751006
}
9761007

9771008
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)