From 9366d815c3daf1eef5d5039985e7e0ef8b11ac81 Mon Sep 17 00:00:00 2001 From: patak Date: Sat, 25 Mar 2023 15:58:29 +0100 Subject: [PATCH 1/3] perf: try using realpathSync.native in Windows --- packages/vite/src/node/utils.ts | 42 +++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index d1b3eb14cae7c8..5a8d51479bb950 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -1,6 +1,7 @@ import fs from 'node:fs' import os from 'node:os' import path from 'node:path' +import { exec } from 'node:child_process' import { createHash } from 'node:crypto' import { promisify } from 'node:util' import { URL, URLSearchParams } from 'node:url' @@ -597,10 +598,47 @@ export const renameDir = isWindows ? promisify(gracefulRename) : fs.renameSync // `fs.realpathSync.native` resolves differently in Windows network drive, // causing file read errors. skip for now. // https://github.com/nodejs/node/issues/37737 -export const safeRealpathSync = isWindows - ? fs.realpathSync +export let safeRealpathSync = isWindows + ? windowsSafeRealPathSync : fs.realpathSync.native +// Based on https://github.com/larrybahr/windows-network-drive +// MIT License, Copyright (c) 2017 Larry Bahr +const windowsNetworkMap = new Map() +function windowsMappedRealpathSync(path: string) { + const realPath = fs.realpathSync.native(path) + if (realPath.startsWith('\\\\')) { + for (const [network, volume] of windowsNetworkMap) { + if (realPath.startsWith(network)) return realPath.replace(network, volume) + } + } + return realPath +} +const parseNetUseRE = /^(\w+) +(\w:) +([^ ]+)\s/ +let firstSafeRealPathSyncRun = false + +function windowsSafeRealPathSync(path: string): string { + if (!firstSafeRealPathSyncRun) { + optimizeSafeRealPathSync() + firstSafeRealPathSyncRun = false + } + return fs.realpathSync(path) +} + +function optimizeSafeRealPathSync() { + exec('net use', (error, stdout) => { + if (error) return + const lines = stdout.split('\n') + // OK Y: \\NETWORKA\Foo Microsoft Windows Network + // OK Z: \\NETWORKA\Bar Microsoft Windows Network + for (const line of lines) { + const m = line.match(parseNetUseRE) + if (m) windowsNetworkMap.set(m[3], m[2]) + } + safeRealpathSync = windowsMappedRealpathSync + }) +} + export function ensureWatchedFile( watcher: FSWatcher, file: string | null, From 9a6af8ee21ae6c8b6917c602c48902781ca54b0a Mon Sep 17 00:00:00 2001 From: sapphi-red Date: Sun, 26 Mar 2023 17:18:28 +0900 Subject: [PATCH 2/3] fix: set `firstSafeRealPathSyncRun` correctly Co-Authored-By: Bjorn Lu --- packages/vite/src/node/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index 5a8d51479bb950..e719278a10dfaf 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -620,7 +620,7 @@ let firstSafeRealPathSyncRun = false function windowsSafeRealPathSync(path: string): string { if (!firstSafeRealPathSyncRun) { optimizeSafeRealPathSync() - firstSafeRealPathSyncRun = false + firstSafeRealPathSyncRun = true } return fs.realpathSync(path) } From 63217529154dc6dc53d5861a068e80a1aec0fdb3 Mon Sep 17 00:00:00 2001 From: sapphi-red Date: Sun, 26 Mar 2023 17:19:20 +0900 Subject: [PATCH 3/3] perf: use `fs.realpath.native` directly when `windowsNetworkMap` is empty Co-Authored-By: patak <583075+patak-dev@users.noreply.github.com> --- packages/vite/src/node/utils.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index e719278a10dfaf..81d7e22bad6cf8 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -635,7 +635,11 @@ function optimizeSafeRealPathSync() { const m = line.match(parseNetUseRE) if (m) windowsNetworkMap.set(m[3], m[2]) } - safeRealpathSync = windowsMappedRealpathSync + if (windowsNetworkMap.size === 0) { + safeRealpathSync = fs.realpathSync.native + } else { + safeRealpathSync = windowsMappedRealpathSync + } }) }