diff --git a/admin/scripts/copyUntypedFiles.js b/admin/scripts/copyUntypedFiles.js index 59178146452a..a74652dddf84 100644 --- a/admin/scripts/copyUntypedFiles.js +++ b/admin/scripts/copyUntypedFiles.js @@ -7,7 +7,7 @@ import fs from 'fs-extra'; import path from 'path'; -import chokidar from 'chokidar'; +import * as chokidar from 'chokidar'; const srcDir = path.join(process.cwd(), 'src'); const libDir = path.join(process.cwd(), 'lib'); diff --git a/packages/docusaurus/package.json b/packages/docusaurus/package.json index f5cc128c914d..1001c0aca2b6 100644 --- a/packages/docusaurus/package.json +++ b/packages/docusaurus/package.json @@ -41,7 +41,7 @@ "@docusaurus/utils-common": "3.10.1", "@docusaurus/utils-validation": "3.10.1", "boxen": "^6.2.1", - "chokidar": "^3.5.3", + "chokidar": "^5.0.0", "cli-table3": "^0.6.3", "combine-promises": "^1.1.0", "commander": "^5.1.0", diff --git a/packages/docusaurus/src/commands/start/start.ts b/packages/docusaurus/src/commands/start/start.ts index e98579d63283..6419f11a258f 100644 --- a/packages/docusaurus/src/commands/start/start.ts +++ b/packages/docusaurus/src/commands/start/start.ts @@ -36,7 +36,7 @@ async function doStart( const reloadableSite = await createReloadableSite({siteDirParam, cliOptions}); - setupSiteFileWatchers( + await setupSiteFileWatchers( {props: reloadableSite.get().props, cliOptions}, ({plugin}) => { if (plugin) { diff --git a/packages/docusaurus/src/commands/start/watcher.ts b/packages/docusaurus/src/commands/start/watcher.ts index db74726bb272..3721586a37ab 100644 --- a/packages/docusaurus/src/commands/start/watcher.ts +++ b/packages/docusaurus/src/commands/start/watcher.ts @@ -6,8 +6,10 @@ */ import path from 'path'; -import chokidar from 'chokidar'; -import {posixPath} from '@docusaurus/utils'; +import * as chokidar from 'chokidar'; +import {Globby, posixPath} from '@docusaurus/utils'; +import picomatch from 'picomatch'; + import type {StartCLIOptions} from './start'; import type {LoadedPlugin, Props} from '@docusaurus/types'; @@ -27,12 +29,18 @@ export function createPollingOptions( }; } -export type FileWatchEventName = - | 'add' - | 'addDir' - | 'change' - | 'unlink' - | 'unlinkDir'; +type ChokidarEventNames = keyof chokidar.FSWatcherEventMap; + +// We only subscribe to a subset of Chokidar events we care about +const FileWatchEvents = [ + 'add', + 'change', + 'unlink', + 'addDir', + 'unlinkDir', +] as const satisfies ChokidarEventNames[]; + +export type FileWatchEventName = (typeof FileWatchEvents)[number]; export type FileWatchEvent = { name: FileWatchEventName; @@ -48,10 +56,10 @@ type WatchParams = { * Watch file system paths for changes and emit events * Returns an async handle to stop watching */ -export function watch( +async function watch( params: WatchParams, callback: (event: FileWatchEvent) => void, -): () => Promise { +): Promise<() => Promise> { const {pathsToWatch, siteDir, ...options} = params; const fsWatcher = chokidar.watch(pathsToWatch, { @@ -60,12 +68,22 @@ export function watch( ...options, }); - fsWatcher.on('all', (name, eventPath) => callback({name, path: eventPath})); + console.log('watch glob', { + patterns: pathsToWatch, + scans: pathsToWatch.map((pattern) => picomatch.scan(pattern).base), + result: await Globby(pathsToWatch), + }); + + FileWatchEvents.forEach((eventName) => + fsWatcher.on(eventName, (eventPath) => { + callback({name: eventName, path: eventPath}); + }), + ); return () => fsWatcher.close(); } -export function getSitePathsToWatch({props}: {props: Props}): string[] { +function getSitePathsToWatch({props}: {props: Props}): string[] { return [ // TODO we should also watch all imported modules! // Use https://github.com/vercel/nft ? @@ -74,7 +92,7 @@ export function getSitePathsToWatch({props}: {props: Props}): string[] { ]; } -export function getPluginPathsToWatch({ +function getPluginPathsToWatch({ siteDir, plugin, }: { @@ -93,7 +111,7 @@ export function getPluginPathsToWatch({ .map(normalizeToSiteDir); } -export function setupSiteFileWatchers( +export async function setupSiteFileWatchers( { props, cliOptions, @@ -105,7 +123,7 @@ export function setupSiteFileWatchers( plugin: LoadedPlugin | null; event: FileWatchEvent; }) => void, -): void { +): Promise { const {siteDir} = props; const pollingOptions = createPollingOptions(cliOptions); @@ -113,7 +131,7 @@ export function setupSiteFileWatchers( // the getFilePathsToWatch lifecycle code might get updated // so we should probably reset the watchers? - watch( + const siteWatcher = watch( { pathsToWatch: getSitePathsToWatch({props}), siteDir: props.siteDir, @@ -122,8 +140,8 @@ export function setupSiteFileWatchers( (event) => callback({plugin: null, event}), ); - props.plugins.forEach((plugin) => { - watch( + const pluginWatchers = props.plugins.map((plugin) => { + return watch( { pathsToWatch: getPluginPathsToWatch({plugin, siteDir}), siteDir, @@ -132,4 +150,6 @@ export function setupSiteFileWatchers( (event) => callback({plugin, event}), ); }); + + await Promise.all([siteWatcher, ...pluginWatchers]); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0a6468064a25..12b00dd47f09 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -362,8 +362,8 @@ importers: specifier: ^6.2.1 version: 6.2.1 chokidar: - specifier: ^3.5.3 - version: 3.6.0 + specifier: ^5.0.0 + version: 5.0.0 cli-table3: specifier: ^0.6.3 version: 0.6.5 @@ -6772,10 +6772,6 @@ packages: resolution: {integrity: sha512-sdleLVfCjBtgO5cNjA2HVRvWBJAHs4zwenaCPMNJAJU0yNxpzj80IpjOIimkpkr+mhlA+how5poQtt53PygbHA==} engines: {node: ^18.17.0 || >=20.5.0} - binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} - bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} @@ -6985,10 +6981,6 @@ packages: resolution: {integrity: sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==} engines: {node: '>=20.18.1'} - chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} - engines: {node: '>= 8.10.0'} - chokidar@5.0.0: resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} engines: {node: '>= 20.19.0'} @@ -9147,10 +9139,6 @@ packages: resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} engines: {node: '>= 0.4'} - is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} - is-boolean-object@1.2.2: resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} engines: {node: '>= 0.4'} @@ -11596,10 +11584,6 @@ packages: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} - readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} - readdirp@5.0.0: resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} engines: {node: '>= 20.19.0'} @@ -18545,8 +18529,6 @@ snapshots: read-cmd-shim: 5.0.0 write-file-atomic: 6.0.0 - binary-extensions@2.3.0: {} - bl@4.1.0: dependencies: buffer: 5.7.1 @@ -18828,18 +18810,6 @@ snapshots: undici: 7.26.0 whatwg-mimetype: 4.0.0 - chokidar@3.6.0: - dependencies: - anymatch: 3.1.3 - braces: 3.0.3 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 - chokidar@5.0.0: dependencies: readdirp: 5.0.0 @@ -21372,10 +21342,6 @@ snapshots: dependencies: has-bigints: 1.1.0 - is-binary-path@2.1.0: - dependencies: - binary-extensions: 2.3.0 - is-boolean-object@1.2.2: dependencies: call-bound: 1.0.4 @@ -24472,10 +24438,6 @@ snapshots: string_decoder: 1.3.0 util-deprecate: 1.0.2 - readdirp@3.6.0: - dependencies: - picomatch: 2.3.2 - readdirp@5.0.0: {} recma-build-jsx@1.0.0: