diff --git a/packages/vite/src/node/build.ts b/packages/vite/src/node/build.ts index 181fcf7d199e1c..2dd78e0741f348 100644 --- a/packages/vite/src/node/build.ts +++ b/packages/vite/src/node/build.ts @@ -21,13 +21,12 @@ import commonjsPlugin from '@rollup/plugin-commonjs' import type { RollupCommonJSOptions } from 'types/commonjs' import type { RollupDynamicImportVarsOptions } from 'types/dynamicImportVars' import type { TransformOptions } from 'esbuild' -import { detectWhetherChokidarWithDefaultOptionWorks, isWSL2 } from './watcher' import type { InlineConfig, ResolvedConfig } from './config' import { isDepsOptimizerEnabled, resolveConfig } from './config' import { buildReporterPlugin } from './plugins/reporter' import { buildEsbuildPlugin } from './plugins/esbuild' import { terserPlugin } from './plugins/terser' -import { copyDir, emptyDir, lookupFile, normalizePath } from './utils' +import { copyDir, emptyDir, isWSL2, lookupFile, normalizePath } from './utils' import { manifestPlugin } from './plugins/manifest' import type { Logger } from './logger' import { dataURIPlugin } from './plugins/dataUri' @@ -515,22 +514,14 @@ async function doBuild( } if (isWSL2 && resolvedChokidarOptions.usePolling === undefined) { - detectWhetherChokidarWithDefaultOptionWorks(config.root).then( - ({ result, warning }) => { - if (result === false) { - config.logger.warn( - colors.yellow( - colors.bold(`(!) `) + - 'Default file system watching is not working with your setup due to the limitation of WSL2. ' + - 'Rebuild will not happen.' + - 'More information: https://vitejs.dev/config/server-options.html#server-watch' - ) - ) - } - if (warning) { - config.logger.warn(colors.yellow(warning)) - } - } + config.logger.warn( + colors.yellow( + colors.bold(`(!) `) + + 'Default file system watching might not work with your setup due to the limitation of WSL2. ' + + 'Rebuild will not happen when file system watching is not working. ' + + 'To suppress this warning, set true or false to "build.watch.usePolling". ' + + 'More information: https://vitejs.dev/config/server-options.html#server-watch' + ) ) } diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts index 5385c3643c48a1..4fae784f479c5a 100644 --- a/packages/vite/src/node/server/index.ts +++ b/packages/vite/src/node/server/index.ts @@ -17,6 +17,7 @@ import type { InlineConfig, ResolvedConfig } from '../config' import { isDepsOptimizerEnabled, resolveConfig } from '../config' import { isParentDirectory, + isWSL2, mergeConfig, normalizePath, resolveHostname @@ -37,7 +38,6 @@ import { CLIENT_DIR } from '../constants' import type { Logger } from '../logger' import { printCommonServerUrls } from '../logger' import { invalidatePackageData } from '../packages' -import { detectWhetherChokidarWithDefaultOptionWorks, isWSL2 } from '../watcher' import type { PluginContainer } from './pluginContainer' import { createPluginContainer } from './pluginContainer' import type { WebSocketServer } from './ws' @@ -298,22 +298,14 @@ export async function createServer( } if (isWSL2 && resolvedWatchOptions.usePolling === undefined) { - detectWhetherChokidarWithDefaultOptionWorks(root).then( - ({ result, warning }) => { - if (result === false) { - config.logger.warn( - colors.yellow( - colors.bold(`(!) `) + - 'Default file system watching is not working with your setup due to the limitation of WSL2. ' + - 'HMR and other features will not work. ' + - 'More information: https://vitejs.dev/config/server-options.html#server-watch' - ) - ) - } - if (warning) { - config.logger.warn(colors.yellow(warning)) - } - } + config.logger.warn( + colors.yellow( + colors.bold(`(!) `) + + 'Default file system watching might not work with your setup due to the limitation of WSL2. ' + + 'HMR and other features will not work when file system watching is not working. ' + + 'To suppress this warning, set true or false to "server.watch.usePolling". ' + + 'More information: https://vitejs.dev/config/server-options.html#server-watch' + ) ) } diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index 0b0c205d80b9e4..fc9c1d59d1ab6e 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -1087,3 +1087,22 @@ export const isNonDriveRelativeAbsolutePath = (p: string): boolean => { if (!isWindows) return p.startsWith('/') return windowsDrivePathPrefixRE.test(p) } + +/** + * returns `true` for WSL2 including docker running on WSL2 + * + * https://github.com/microsoft/WSL/issues/423#issuecomment-844418910 + */ +export const isWSL2 = (() => { + const release = os.release() + // Example: `5.10.102.1-microsoft-standard-WSL2` + if (release.includes('WSL2')) { + // "Docker Desktop for Windows with WSL2 backend" and "Docker installed in WSL" comes here too + return true + } + + // Windows Example: `10.0.19044` + // WSL1 Example: `4.4.0-19041-Microsoft` + // Docker Desktop for Windows with WSL2 backend Example: `5.10.76-linuxkit` + return false +})() diff --git a/packages/vite/src/node/watcher.ts b/packages/vite/src/node/watcher.ts deleted file mode 100644 index 0baecd9383bb0d..00000000000000 --- a/packages/vite/src/node/watcher.ts +++ /dev/null @@ -1,90 +0,0 @@ -import fs from 'node:fs' -import os from 'node:os' -import path from 'node:path' -import chokidar from 'chokidar' - -/** - * returns `true` for WSL2 including docker running on WSL2 - * - * https://github.com/microsoft/WSL/issues/423#issuecomment-844418910 - */ -export const isWSL2 = (() => { - const release = os.release() - // Example: `5.10.102.1-microsoft-standard-WSL2` - if (release.includes('WSL2')) { - // "Docker Desktop for Windows with WSL2 backend" and "Docker installed in WSL" comes here too - return true - } - - // Windows Example: `10.0.19044` - // WSL1 Example: `4.4.0-19041-Microsoft` - // Docker Desktop for Windows with WSL2 backend Example: `5.10.76-linuxkit` - return false -})() - -/** - * returns `true` when it works, `false` when it doesn't, `undefined` when it failed to detect - */ -export const detectWhetherChokidarWithDefaultOptionWorks = ( - root: string -): Promise<{ result: boolean | undefined; warning: string | undefined }> => - new Promise((resolve) => { - const editWait = 100 - const detectWaitTimeout = 500 - - const id = ('' + performance.now()).replace(/\./g, '') - const tempFileShort = `.chokidardetector.${id}.txt` - const tempFile = path.resolve(root, tempFileShort) - - let wroteFile = false - - let timeoutId: NodeJS.Timeout - const w = chokidar.watch(root, { - depth: 1, - disableGlobbing: true, - ignoreInitial: true - }) - // add works with WSL2, but change does not work - w.on('change', () => { - resolveWithCleanup(true) - }) - w.on('error', () => { - resolveWithCleanup(undefined) - }) - w.on('ready', () => { - ;(async () => { - try { - await fs.promises.writeFile(tempFile, 'detector', 'utf-8') - wroteFile = true - await new Promise((resolve) => setTimeout(resolve, editWait)) - // edit file - await fs.promises.writeFile(tempFile, 'detector2', 'utf-8') - } catch { - resolveWithCleanup(undefined) - } - })() - - timeoutId = setTimeout(() => { - resolveWithCleanup(false) - }, detectWaitTimeout) - }) - - let resolved = false - const resolveWithCleanup = async (result: boolean | undefined) => { - if (resolved) return - resolved = true - - clearTimeout(timeoutId) - await w.close() - - let warning: string | undefined - if (wroteFile) { - try { - await fs.promises.unlink(tempFile) - } catch { - warning = `Failed to remove temp file (${tempFileShort}). This file can be removed.` - } - } - resolve({ result, warning }) - } - })