Skip to content

Commit

Permalink
fix(hmr): better fix for #610
Browse files Browse the repository at this point in the history
Previous fix introduced a 100ms minimum delay for all HMR updates which
is very inefficient.
  • Loading branch information
yyx990803 committed Dec 6, 2020
1 parent 4f7f518 commit 3634042
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 7 deletions.
6 changes: 1 addition & 5 deletions src/node/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,7 @@ export function createServer(config: ServerConfig): Server {
const server = resolveServer(config, app.callback())
const watcher = chokidar.watch(root, {
ignored: ['**/node_modules/**', '**/.git/**'],
// #610
awaitWriteFinish: {
stabilityThreshold: 100,
pollInterval: 10
},
ignoreInitial: true,
...chokidarWatchOptions
}) as HMRWatcher
const resolver = createResolver(root, resolvers, alias, assetsInclude)
Expand Down
2 changes: 1 addition & 1 deletion src/node/server/serverPluginVue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ async function parseSFC(

if (!content) {
try {
content = await cachedRead(null, filePath)
content = await cachedRead(null, filePath, true /* poll */)
} catch (e) {
return
}
Expand Down
27 changes: 26 additions & 1 deletion src/node/utils/fsUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ const fsReadCache = new LRUCache<string, CacheEntry>({
*/
export async function cachedRead(
ctx: Context | null,
file: string
file: string,
poll = false
): Promise<Buffer> {
const lastModified = fs.statSync(file).mtimeMs
const cached = fsReadCache.get(file)
Expand All @@ -53,6 +54,10 @@ export async function cachedRead(
}
// #395 some file is an binary file, eg. font
let content = await fs.readFile(file)
if (poll && !content.length) {
await untilModified(file)
content = await fs.readFile(file)
}
// Populate the "sourcesContent" array and resolve relative paths in the
// "sources" array, so the debugger can trace back to the original source.
if (file.endsWith('.map')) {
Expand Down Expand Up @@ -106,6 +111,26 @@ export async function cachedRead(
return content
}

// #610 when hot-reloading Vue files, we read immediately on file change event
// and sometimes this can be too early and get an empty buffer. Poll until the
// file's modified time has changed before reading again.
async function untilModified(file: string) {
const mtime = (await fs.stat(file)).mtimeMs
return new Promise((r) => {
let n = 0
const poll = async () => {
n++
const newMtime = (await fs.stat(file)).mtimeMs
if (newMtime !== mtime || n > 10) {
r(0)
} else {
setTimeout(poll, 10)
}
}
setTimeout(poll, 10)
})
}

/**
* Read already set body on a Koa context and normalize it into a string.
* Useful in post-processing middlewares.
Expand Down

0 comments on commit 3634042

Please sign in to comment.