Skip to content

Commit 4d83eb5

Browse files
fix(dev): watch publicDir explicitly to include it outside the root (#16502)
1 parent 7171837 commit 4d83eb5

File tree

2 files changed

+68
-5
lines changed

2 files changed

+68
-5
lines changed

packages/vite/src/node/server/__tests__/watcher.spec.ts

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,47 @@
1-
import { describe, expect, it } from 'vitest'
1+
import { resolve } from 'node:path'
2+
import {
3+
type MockInstance,
4+
afterEach,
5+
beforeEach,
6+
describe,
7+
expect,
8+
it,
9+
vi,
10+
} from 'vitest'
11+
import chokidar from 'chokidar'
212
import { createServer } from '../index'
313

414
const stubGetWatchedCode = /getWatched\(\) \{.+?return \{\};.+?\}/s
515

16+
let watchSpy: MockInstance<
17+
Parameters<typeof chokidar.watch>,
18+
ReturnType<typeof chokidar.watch>
19+
>
20+
21+
vi.mock('../../config', async () => {
22+
const config: typeof import('../../config') =
23+
await vi.importActual('../../config')
24+
const resolveConfig = config.resolveConfig
25+
vi.spyOn(config, 'resolveConfig').mockImplementation(async (...args) => {
26+
const resolved: Awaited<ReturnType<typeof resolveConfig>> =
27+
await resolveConfig.call(config, ...args)
28+
resolved.configFileDependencies.push(
29+
resolve('fake/config/dependency.js').replace(/\\/g, '/'),
30+
)
31+
return resolved
32+
})
33+
return config
34+
})
35+
636
describe('watcher configuration', () => {
37+
beforeEach(() => {
38+
watchSpy = vi.spyOn(chokidar, 'watch')
39+
})
40+
41+
afterEach(() => {
42+
watchSpy.mockRestore()
43+
})
44+
745
it('when watcher is disabled, return noop watcher', async () => {
846
const server = await createServer({
947
server: {
@@ -21,4 +59,27 @@ describe('watcher configuration', () => {
2159
})
2260
expect(server.watcher.getWatched.toString()).not.toMatch(stubGetWatchedCode)
2361
})
62+
63+
it('should watch the root directory, config file dependencies, dotenv files, and the public directory', async () => {
64+
await createServer({
65+
server: {
66+
watch: {},
67+
},
68+
publicDir: '__test_public__',
69+
})
70+
expect(watchSpy).toHaveBeenLastCalledWith(
71+
expect.arrayContaining(
72+
[
73+
process.cwd(),
74+
resolve('fake/config/dependency.js'),
75+
resolve('.env'),
76+
resolve('.env.local'),
77+
resolve('.env.development'),
78+
resolve('.env.development.local'),
79+
resolve('__test_public__'),
80+
].map((file) => file.replace(/\\/g, '/')),
81+
),
82+
expect.anything(),
83+
)
84+
})
2485
})

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,9 @@ export async function _createServer(
466466
config.server.hmr.channels.forEach((channel) => hot.addChannel(channel))
467467
}
468468

469+
const publicFiles = await initPublicFilesPromise
470+
const { publicDir } = config
471+
469472
if (httpServer) {
470473
setClientErrorHandler(httpServer, config.logger)
471474
}
@@ -479,6 +482,9 @@ export async function _createServer(
479482
root,
480483
...config.configFileDependencies,
481484
...getEnvFilesForMode(config.mode, config.envDir),
485+
// Watch the public directory explicitly because it might be outside
486+
// of the root directory.
487+
...(publicDir && publicFiles ? [publicDir] : []),
482488
],
483489
resolvedWatchOptions,
484490
) as FSWatcher)
@@ -745,8 +751,6 @@ export async function _createServer(
745751
}
746752
}
747753

748-
const publicFiles = await initPublicFilesPromise
749-
750754
const onHMRUpdate = async (
751755
type: 'create' | 'delete' | 'update',
752756
file: string,
@@ -763,8 +767,6 @@ export async function _createServer(
763767
}
764768
}
765769

766-
const { publicDir } = config
767-
768770
const onFileAddUnlink = async (file: string, isUnlink: boolean) => {
769771
file = normalizePath(file)
770772
await container.watchChange(file, { event: isUnlink ? 'delete' : 'create' })

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy