From d6c0b14914bede9407af9b7c2b6b3948d738cb75 Mon Sep 17 00:00:00 2001 From: mag123c Date: Thu, 27 Nov 2025 10:24:27 +0900 Subject: [PATCH] doc: document glob pattern syntax and behavior The `fs.glob()` family documented its options but never described which pattern syntax the matcher accepts, what the returned values look like, or how matching differs across platforms. Describe the supported wildcards, globstar, brace expansion, and extended patterns on `fsPromises.glob()`, add common usage examples and a platform behavior section, and point `fs.glob()` and `fs.globSync()` at that reference. Also spell out the type and shape of the values the callback and synchronous forms produce. Signed-off-by: mag123c --- doc/api/fs.md | 105 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 98 insertions(+), 7 deletions(-) diff --git a/doc/api/fs.md b/doc/api/fs.md index d3421a0ff01bc9..ec349d0146c413 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -1430,7 +1430,7 @@ changes: description: Add support for `withFileTypes` as an option. --> -* `pattern` {string|string\[]} +* `pattern` {string|string\[]} The glob pattern(s) to match against. * `options` {Object} * `cwd` {string|URL} current working directory. **Default:** `process.cwd()` * `exclude` {Function|string\[]} Function to filter out files/directories or a @@ -1446,9 +1446,52 @@ changes: * Returns: {AsyncIterator} An AsyncIterator that yields the paths of files that match the pattern. +Retrieves the file paths matching the specified pattern(s). + When `followSymlinks` is enabled, detected symbolic link cycles are not traversed recursively. +#### Pattern Syntax + +The glob implementation supports the following pattern syntax: + +**Basic Wildcards:** + +| Pattern | Description | +| -------------------- | -------------------------------------------------------------- | +| `*` | Matches any number of characters within a single path segment. | +| `?` | Matches exactly one character. | +| `[abc]` | Matches any character in the brackets. | +| `[a-z]` | Matches any character in the range. | +| `[!abc]` or `[^abc]` | Matches any character not in the brackets. | +| `[!a-z]` or `[^a-z]` | Matches any character not in the range. | + +**Globstar:** + +| Pattern | Description | +| --------- | --------------------------------------------- | +| `**` | Matches zero or more directories recursively. | +| `**/*.js` | Matches all `.js` files in any subdirectory. | + +**Brace Expansion:** + +| Pattern | Description | +| ----------- | ------------------------------------------------ | +| `{a,b,c}` | Matches any of the comma-separated patterns. | +| `{1..5}` | Matches any number in the range (1, 2, 3, 4, 5). | +| `*.{js,ts}` | Matches files with `.js` or `.ts` extensions. | + +**Extended Glob Patterns:** + +| Pattern | Description | +| ------------ | ------------------------------------------------ | +| `+(pattern)` | Matches one or more occurrences of the pattern. | +| `*(pattern)` | Matches zero or more occurrences of the pattern. | +| `?(pattern)` | Matches zero or one occurrence of the pattern. | +| `!(pattern)` | Matches anything except the pattern. | + +#### Examples + ```mjs import { glob } from 'node:fs/promises'; @@ -1465,6 +1508,40 @@ const { glob } = require('node:fs/promises'); })(); ``` +To collect all results into an array, use `Array.fromAsync`: + +```mjs +const files = await Array.fromAsync(glob('src/**/*.js')); +``` + +**Common patterns:** + +| Pattern | Description | +| --------------------------------------------------- | ------------------------------------------------ | +| `glob('*.js')` | All `.js` files in the current directory. | +| `glob('**/*.{js,ts}')` | All `.js` and `.ts` files recursively. | +| `glob('src/{components,utils}/**/*.js')` | `.js` files in `src/components` or `src/utils`. | +| `glob('test/**/*.{spec,test}.js')` | Test files ending with `.spec.js` or `.test.js`. | +| `glob('**/*.js', { exclude: ['node_modules/**'] })` | All `.js` files except those in `node_modules`. | +| `glob(['src/**/*.js', 'lib/**/*.js'])` | `.js` files in both `src` and `lib` directories. | + +#### Platform Considerations + +* **Case sensitivity**: Glob patterns are case-insensitive on Windows and macOS, + case-sensitive on other platforms. +* **Path separators**: Forward slashes (`/`) are used in patterns regardless of + platform; they are automatically converted to the appropriate separator. +* **Returned paths**: Results use platform-specific path separators (`\` on Windows, + `/` on POSIX). Paths are relative to `options.cwd` if provided, otherwise + relative to the current working directory. +* **Symlinks**: Symbolic links to directories are not traversed while expanding + `**` patterns unless `followSymlinks` is `true`. +* **Hidden files**: Files starting with `.` are included in results when explicitly + matched, but not when using `*` or `**` patterns. + +[`path.matchesGlob()`][] supports the same basic glob pattern syntax for +in-memory path matching, but does not include the `exclude` option. + ### `fsPromises.lchmod(path, mode)` -* `pattern` {string|string\[]} - +* `pattern` {string|string\[]} The glob pattern(s) to match against. * `options` {Object} * `cwd` {string|URL} current working directory. **Default:** `process.cwd()` * `exclude` {Function|string\[]} Function to filter out files/directories or a @@ -3597,11 +3673,17 @@ changes: followed while expanding `**` patterns. **Default:** `false`. * `withFileTypes` {boolean} `true` if the glob should return paths as Dirents, `false` otherwise. **Default:** `false`. - * `callback` {Function} * `err` {Error} + * `matches` {string\[]|fs.Dirent\[]} An array of paths or Dirent objects that + match the pattern. String paths use platform-specific separators (`\` on + Windows, `/` on POSIX) and are relative to `options.cwd` if provided, + otherwise relative to the current working directory. + +Retrieves the file paths matching the specified pattern(s). -* Retrieves the files matching the specified pattern. +See `fsPromises.glob()` for detailed information about pattern syntax, +examples, and behavior. When `followSymlinks` is enabled, detected symbolic link cycles are not traversed recursively. @@ -6217,7 +6299,7 @@ changes: description: Add support for `withFileTypes` as an option. --> -* `pattern` {string|string\[]} +* `pattern` {string|string\[]} The glob pattern(s) to match against. * `options` {Object} * `cwd` {string|URL} current working directory. **Default:** `process.cwd()` * `exclude` {Function|string\[]} Function to filter out files/directories or a @@ -6227,7 +6309,15 @@ changes: followed while expanding `**` patterns. **Default:** `false`. * `withFileTypes` {boolean} `true` if the glob should return paths as Dirents, `false` otherwise. **Default:** `false`. -* Returns: {string\[]} paths of files that match the pattern. +* Returns: {string\[]|fs.Dirent\[]} An array of paths or Dirent objects that + match the pattern. String paths use platform-specific separators (`\` on + Windows, `/` on POSIX) and are relative to `options.cwd` if provided, + otherwise relative to the current working directory. + +Retrieves the file paths matching the specified pattern(s). + +See `fsPromises.glob()` for detailed information about pattern syntax, +examples, and behavior. When `followSymlinks` is enabled, detected symbolic link cycles are not traversed recursively. @@ -9329,6 +9419,7 @@ the file contents. [`kqueue(2)`]: https://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2 [`minimatch`]: https://github.com/isaacs/minimatch [`node:stream/iter`]: stream_iter.md +[`path.matchesGlob()`]: path.md#pathmatchesglobpath-pattern [`statfs.bsize`]: #statfsbsize [`stream/iter pipeTo()`]: stream_iter.md#pipetosource-transforms-writer-options [`stream/iter pull()`]: stream_iter.md#pullsource-transforms-options