Glob 中文网
使用 shell 使用的模式匹配文件。
¥Match files using the patterns the shell uses.
JavaScript 中最正确和第二快的 glob 实现。(请参阅本自述文件底部的与其他 JavaScript Glob 实现的比较。)
¥The most correct and second fastest glob implementation in JavaScript. (See Comparison to Other JavaScript Glob Implementations at the bottom of this readme.)
用法
¥Usage
使用 npm 安装
¥Install with npm
npm i glob
请注意,npm 包名称不是 node-glob
,这是几年前被废弃的不同名称。仅 glob
。
¥Note the npm package name is not node-glob
that's a
different thing that was abandoned years ago. Just glob
.
// load using import
import { glob, globSync, globStream, globStreamSync, Glob } from 'glob'
// or using commonjs, that's fine, too
const {
glob,
globSync,
globStream,
globStreamSync,
Glob,
} = require('glob')
// the main glob() and globSync() resolve/return array of filenames
// all js files, but don't look in node_modules
const jsfiles = await glob('**/*.js', { ignore: 'node_modules/**' })
// pass in a signal to cancel the glob walk
const stopAfter100ms = await glob('**/*.css', {
signal: AbortSignal.timeout(100),
})
// multiple patterns supported as well
const images = await glob(['css/*.{png,jpeg}', 'public/*.{png,jpeg}'])
// but of course you can do that with the glob pattern also
// the sync function is the same, just returns a string[] instead
// of Promise<string[]>
const imagesAlt = globSync('{css,public}/*.{png,jpeg}')
// you can also stream them, this is a Minipass stream
const filesStream = globStream(['**/*.dat', 'logs/**/*.log'])
// construct a Glob object if you wanna do it that way, which
// allows for much faster walks if you have to look in the same
// folder multiple times.
const g = new Glob('**/foo', {})
// glob objects are async iterators, can also do globIterate() or
// g.iterate(), same deal
for await (const file of g) {
console.log('found a foo file:', file)
}
// pass a glob as the glob options to reuse its settings and caches
const g2 = new Glob('**/bar', g)
// sync iteration works as well
for (const file of g2) {
console.log('found a bar file:', file)
}
// you can also pass withFileTypes: true to get Path objects
// these are like a Dirent, but with some more added powers
// check out http://npm.im/path-scurry for more info on their API
const g3 = new Glob('**/baz/**', { withFileTypes: true })
g3.stream().on('data', path => {
console.log(
'got a path object',
path.fullpath(),
path.isDirectory(),
path.readdirSync().map(e => e.name),
)
})
// if you use stat:true and withFileTypes, you can sort results
// by things like modified time, filter by permission mode, etc.
// All Stats fields will be available in that case. Slightly
// slower, though.
// For example:
const results = await glob('**', { stat: true, withFileTypes: true })
const timeSortedFiles = results
.sort((a, b) => a.mtimeMs - b.mtimeMs)
.map(path => path.fullpath())
const groupReadableFiles = results
.filter(path => path.mode & 0o040)
.map(path => path.fullpath())
// custom ignores can be done like this, for example by saying
// you'll ignore all markdown files, and all folders named 'docs'
const customIgnoreResults = await glob('**', {
ignore: {
ignored: p => /\.md$/.test(p.name),
childrenIgnored: p => p.isNamed('docs'),
},
})
// another fun use case, only return files with the same name as
// their parent folder, plus either `.ts` or `.js`
const folderNamedModules = await glob('**/*.{ts,js}', {
ignore: {
ignored: p => {
const pp = p.parent
return !(p.isNamed(pp.name + '.ts') || p.isNamed(pp.name + '.js'))
},
},
})
// find all files edited in the last hour, to do this, we ignore
// all of them that are more than an hour old
const newFiles = await glob('**', {
// need stat so we have mtime
stat: true,
// only want the files, not the dirs
nodir: true,
ignore: {
ignored: p => {
return new Date() - p.mtime > 60 * 60 * 1000
},
// could add similar childrenIgnored here as well, but
// directory mtime is inconsistent across platforms, so
// probably better not to, unless you know the system
// tracks this reliably.
},
})
注意 Glob 模式应始终使用 /
作为路径分隔符,即使在 Windows 系统上也是如此,因为 \
用于转义 glob 字符。如果你希望在 Windows 平台上使用 \
作为路径分隔符而不是将其用作转义符,你可以在选项中设置 windowsPathsNoEscape:true
。在此模式下,特殊的 glob 字符无法转义,因此无法在文件名中匹配字面量 *
?
等。
¥Note Glob patterns should always use /
as a path separator,
even on Windows systems, as \
is used to escape glob
characters. If you wish to use \
as a path separator instead
of using it as an escape character on Windows platforms, you may
set windowsPathsNoEscape:true
in the options. In this mode,
special glob characters cannot be escaped, making it impossible
to match a literal *
?
and so on in filenames.
命令行接口
¥Command Line Interface
$ glob -h
Usage:
glob [options] [<pattern> [<pattern> ...]]
Expand the positional glob expression arguments into any matching file system
paths found.
-c<command> --cmd=<command>
Run the command provided, passing the glob expression
matches as arguments.
-A --all By default, the glob cli command will not expand any
arguments that are an exact match to a file on disk.
This prevents double-expanding, in case the shell
expands an argument whose filename is a glob
expression.
For example, if 'app/*.ts' would match 'app/[id].ts',
then on Windows powershell or cmd.exe, 'glob app/*.ts'
will expand to 'app/[id].ts', as expected. However, in
posix shells such as bash or zsh, the shell will first
expand 'app/*.ts' to a list of filenames. Then glob
will look for a file matching 'app/[id].ts' (ie,
'app/i.ts' or 'app/d.ts'), which is unexpected.
Setting '--all' prevents this behavior, causing glob to
treat ALL patterns as glob expressions to be expanded,
even if they are an exact match to a file on disk.
When setting this option, be sure to enquote arguments
so that the shell will not expand them prior to passing
them to the glob command process.
-a --absolute Expand to absolute paths
-d --dot-relative Prepend './' on relative matches
-m --mark Append a / on any directories matched
-x --posix Always resolve to posix style paths, using '/' as the
directory separator, even on Windows. Drive letter
absolute matches on Windows will be expanded to their
full resolved UNC maths, eg instead of 'C:\foo\bar', it
will expand to '//?/C:/foo/bar'.
-f --follow Follow symlinked directories when expanding '**'
-R --realpath Call 'fs.realpath' on all of the results. In the case
of an entry that cannot be resolved, the entry is
omitted. This incurs a slight performance penalty, of
course, because of the added system calls.
-s --stat Call 'fs.lstat' on all entries, whether required or not
to determine if it's a valid match.
-b --match-base Perform a basename-only match if the pattern does not
contain any slash characters. That is, '*.js' would be
treated as equivalent to '**/*.js', matching js files
in all directories.
--dot Allow patterns to match files/directories that start
with '.', even if the pattern does not start with '.'
--nobrace Do not expand {...} patterns
--nocase Perform a case-insensitive match. This defaults to
'true' on macOS and Windows platforms, and false on all
others.
Note: 'nocase' should only be explicitly set when it is
known that the filesystem's case sensitivity differs
from the platform default. If set 'true' on
case-insensitive file systems, then the walk may return
more or less results than expected.
--nodir Do not match directories, only files.
Note: to *only* match directories, append a '/' at the
end of the pattern.
--noext Do not expand extglob patterns, such as '+(a|b)'
--noglobstar Do not expand '**' against multiple path portions. Ie,
treat it as a normal '*' instead.
--windows-path-no-escape
Use '\' as a path separator *only*, and *never* as an
escape character. If set, all '\' characters are
replaced with '/' in the pattern.
-D<n> --max-depth=<n> Maximum depth to traverse from the current working
directory
-C<cwd> --cwd=<cwd> Current working directory to execute/match in
-r<root> --root=<root> A string path resolved against the 'cwd', which is used
as the starting point for absolute patterns that start
with '/' (but not drive letters or UNC paths on
Windows).
Note that this *doesn't* necessarily limit the walk to
the 'root' directory, and doesn't affect the cwd
starting point for non-absolute patterns. A pattern
containing '..' will still be able to traverse out of
the root directory, if it is not an actual root
directory on the filesystem, and any non-absolute
patterns will still be matched in the 'cwd'.
To start absolute and non-absolute patterns in the same
path, you can use '--root=' to set it to the empty
string. However, be aware that on Windows systems, a
pattern like 'x:/*' or '//host/share/*' will *always*
start in the 'x:/' or '//host/share/' directory,
regardless of the --root setting.
--platform=<platform> Defaults to the value of 'process.platform' if
available, or 'linux' if not. Setting --platform=win32
on non-Windows systems may cause strange behavior!
-i<ignore> --ignore=<ignore>
Glob patterns to ignore Can be set multiple times
-v --debug Output a huge amount of noisy debug information about
patterns as they are parsed and used to match files.
-h --help Show this usage information
glob(pattern: string | string[], options?: GlobOptions) => Promise<string[] | Path[]>
对指定的模式执行异步 glob 搜索。如果 withFileTypes
选项设置为 true
,则返回 路径 对象。请参阅下文了解完整的选项字段描述。
¥Perform an asynchronous glob search for the pattern(s) specified.
Returns
Path
objects if the withFileTypes
option is set to true
. See below
for full options field desciptions.
globSync(pattern: string | string[], options?: GlobOptions) => string[] | Path[]
glob()
的同步形式。
¥Synchronous form of glob()
.
别名:glob.sync()
¥Alias: glob.sync()
globIterate(pattern: string | string[], options?: GlobOptions) => AsyncGenerator<string>
返回用于遍历 glob 模式匹配的异步迭代器。
¥Return an async iterator for walking glob pattern matches.
别名:glob.iterate()
¥Alias: glob.iterate()
globIterateSync(pattern: string | string[], options?: GlobOptions) => Generator<string>
返回用于遍历 glob 模式匹配的同步迭代器。
¥Return a sync iterator for walking glob pattern matches.
别名:glob.iterate.sync()
, glob.sync.iterate()
¥Alias: glob.iterate.sync()
, glob.sync.iterate()
globStream(pattern: string | string[], options?: GlobOptions) => Minipass<string | Path>
返回一个触发所有字符串或 Path
对象然后在完成时触发 end
的流。
¥Return a stream that emits all the strings or Path
objects and
then emits end
when completed.
别名:glob.stream()
¥Alias: glob.stream()
globStreamSync(pattern: string | string[], options?: GlobOptions) => Minipass<string | Path>
globStream()
的同步形式。将在你使用它们时尽可能快地读取所有匹配项,如果你立即使用它们,甚至会在单个刻度内读取所有匹配项,但如果它们没有立即使用,仍会响应背压。
¥Syncronous form of globStream()
. Will read all the matches as
fast as you consume them, even all in a single tick if you
consume them immediately, but will still respond to backpressure
if they're not consumed immediately.
别名:glob.stream.sync()
, glob.sync.stream()
¥Alias: glob.stream.sync()
, glob.sync.stream()
hasMagic(pattern: string | string[], options?: GlobOptions) => boolean
如果提供的模式包含任何 "magic" glob 字符(给定提供的选项),则返回 true
。
¥Returns true
if the provided pattern contains any "magic" glob
characters, given the options provided.
除非设置了 magicalBraces
选项,否则括号扩展不被视为 "magic",因为括号扩展只是将一个字符串转换为一个字符串数组。因此,像 'x{a,b}y'
这样的模式将返回 false
,因为 'xay'
和 'xby'
都不包含任何魔法通配符,并且它被视为与在 ['xay', 'xby']
上调用它一样。当 magicalBraces:true
位于选项中时,括号扩展将被视为具有魔法的模式。
¥Brace expansion is not considered "magic" unless the
magicalBraces
option is set, as brace expansion just turns one
string into an array of strings. So a pattern like 'x{a,b}y'
would return false
, because 'xay'
and 'xby'
both do not
contain any magic glob characters, and it's treated the same as
if you had called it on ['xay', 'xby']
. When
magicalBraces:true
is in the options, brace expansion is
treated as a pattern having magic.
escape(pattern: string, options?: GlobOptions) => string
转义 glob 模式中的所有魔法字符,以便它只匹配字面量字符串
¥Escape all magic characters in a glob pattern, so that it will only ever match literal strings
如果使用 windowsPathsNoEscape
选项,则字符将通过封装在 []
中转义,因为封装在字符类中的魔法字符只能由该精确字符满足。
¥If the windowsPathsNoEscape
option is used, then characters are
escaped by wrapping in []
, because a magic character wrapped in
a character class can only be satisfied by that exact character.
斜杠(和 windowsPathsNoEscape
模式中的反斜杠)不能转义或取消转义。
¥Slashes (and backslashes in windowsPathsNoEscape
mode) cannot
be escaped or unescaped.
unescape(pattern: string, options?: GlobOptions) => string
取消转义可能包含一些转义字符的 glob 字符串。
¥Un-escape a glob string that may contain some escaped characters.
如果使用 windowsPathsNoEscape
选项,则删除方括号转义,但不删除反斜杠转义。例如,它会将字符串 '[*]'
变成 *
,但不会将 '\\*'
变成 '*'
,因为 \
是 windowsPathsNoEscape
模式下的路径分隔符。
¥If the windowsPathsNoEscape
option is used, then square-brace
escapes are removed, but not backslash escapes. For example, it
will turn the string '[*]'
into *
, but it will not turn
'\\*'
into '*'
, because \
is a path separator in
windowsPathsNoEscape
mode.
当未设置 windowsPathsNoEscape
时,括号转义和反斜杠转义都将被删除。
¥When windowsPathsNoEscape
is not set, then both brace escapes
and backslash escapes are removed.
斜杠(和 windowsPathsNoEscape
模式中的反斜杠)不能转义或取消转义。
¥Slashes (and backslashes in windowsPathsNoEscape
mode) cannot
be escaped or unescaped.
Glob
类
¥Class Glob
可以执行 glob 模式遍历的对象。
¥An object that can perform glob pattern traversals.
const g = new Glob(pattern: string | string[], options: GlobOptions)
需要选项对象。
¥Options object is required.
请参阅下面的完整选项描述。
¥See full options descriptions below.
请注意,可以将先前的 Glob
对象作为 GlobOptions
传递给另一个 Glob
实例,以使用新模式重新使用设置和缓存。
¥Note that a previous Glob
object can be passed as the
GlobOptions
to another Glob
instantiation to re-use settings
and caches with a new pattern.
可以多次调用遍历函数以再次运行遍历。
¥Traversal functions can be called multiple times to run the walk again.
g.stream()
异步流式传输结果,
¥Stream results asynchronously,
g.streamSync()
同步流式传输结果。
¥Stream results synchronously.
g.iterate()
默认异步迭代函数。返回一个迭代结果的 AsyncGenerator。
¥Default async iteration function. Returns an AsyncGenerator that iterates over the results.
g.iterateSync()
默认同步迭代函数。返回一个迭代结果的生成器。
¥Default sync iteration function. Returns a Generator that iterates over the results.
g.walk()
返回一个解析为结果数组的 Promise。
¥Returns a Promise that resolves to the results array.
g.walkSync()
返回结果数组。
¥Returns a results array.
属性
¥Properties
所有选项都作为属性存储在 Glob
对象上。
¥All options are stored as properties on the Glob
object.
-
opts
提供给构造函数的选项。¥
opts
The options provided to the constructor. -
patterns
已解析的不可变Pattern
对象数组。¥
patterns
An array of parsed immutablePattern
objects.
选项
¥Options
导出为 GlobOptions
TypeScript 接口。GlobOptions
对象可提供给任何导出方法,并且必须提供给 Glob
构造函数。
¥Exported as GlobOptions
TypeScript interface. A GlobOptions
object may be provided to any of the exported methods, and must
be provided to the Glob
constructor.
除非另有说明,否则所有选项都是可选的、布尔的,默认情况下为 false。
¥All options are optional, boolean, and false by default, unless otherwise noted.
所有已解析的选项都作为属性添加到 Glob 对象中。
¥All resolved options are added to the Glob object as properties.
如果你正在运行许多 glob
操作,你可以将 Glob 对象作为 options
参数传递给后续操作以共享先前加载的缓存。
¥If you are running many glob
operations, you can pass a Glob
object as the options
argument to a subsequent operation to
share the previously loaded cache.
-
cwd
字符串路径或file://
字符串或 URL 对象。当前要搜索的工作目录。默认为process.cwd()
。另请参阅:"Windows、CWD、驱动器号和 UNC 路径",如下。¥
cwd
String path orfile://
string or URL object. The current working directory in which to search. Defaults toprocess.cwd()
. See also: "Windows, CWDs, Drive Letters, and UNC Paths", below.此选项可以是字符串路径或
file://
URL 对象或字符串。¥This option may be either a string path or a
file://
URL object or string. -
root
根据cwd
选项解析的字符串路径,用作以/
开头的绝对模式的起点(但不是 Windows 上的驱动器号或 UNC 路径)。¥
root
A string path resolved against thecwd
option, which is used as the starting point for absolute patterns that start with/
, (but not drive letters or UNC paths on Windows).请注意,这并不一定会将遍历限制在
root
目录,也不会影响非绝对模式的 cwd 起点。如果根目录不是文件系统上的实际根目录,则包含..
的模式仍将能够遍历根目录,并且任何非绝对模式都将在cwd
中匹配。例如,模式/../*
与{root:'/some/path'}
将返回/some
中的所有文件,而不是/some/path
中的所有文件。带有{root:'/some/path'}
的模式*
将返回 cwd 中的所有条目,而不是/some/path
中的条目。¥Note that this doesn't necessarily limit the walk to the
root
directory, and doesn't affect the cwd starting point for non-absolute patterns. A pattern containing..
will still be able to traverse out of the root directory, if it is not an actual root directory on the filesystem, and any non-absolute patterns will be matched in thecwd
. For example, the pattern/../*
with{root:'/some/path'}
will return all files in/some
, not all files in/some/path
. The pattern*
with{root:'/some/path'}
will return all the entries in the cwd, not the entries in/some/path
.要在同一路径中启动绝对和非绝对模式,可以使用
{root:''}
。但是,请注意,在 Windows 系统上,无论root
设置如何,像x:/*
或//host/share/*
这样的模式将始终从x:/
或//host/share
目录中开始。¥To start absolute and non-absolute patterns in the same path, you can use
{root:''}
. However, be aware that on Windows systems, a pattern likex:/*
or//host/share/*
will always start in thex:/
or//host/share
directory, regardless of theroot
setting. -
windowsPathsNoEscape
仅将\\
用作路径分隔符,切勿将其用作转义符。如果设置,则模式中的所有\\
字符都将替换为/
。¥
windowsPathsNoEscape
Use\\
as a path separator only, and never as an escape character. If set, all\\
characters are replaced with/
in the pattern.请注意,这使得无法匹配包含字面量 glob 模式字符的路径,但允许与在 Windows 平台上使用
path.join()
和path.resolve()
构建的模式进行匹配,模仿 Windows 上 Glob v7 及之前版本的(有缺陷的!)行为。请谨慎使用,并注意 以下关于 Windows 路径的警告。(由于历史原因,如果allowWindowsEscape
设置为精确值false
,也会设置此项。)¥Note that this makes it impossible to match against paths containing literal glob pattern characters, but allows matching with patterns constructed using
path.join()
andpath.resolve()
on Windows platforms, mimicking the (buggy!) behavior of Glob v7 and before on Windows. Please use with caution, and be mindful of the caveat below about Windows paths. (For legacy reasons, this is also set ifallowWindowsEscape
is set to the exact valuefalse
.) -
dot
在正常匹配和globstar
匹配中包含.dot
文件。请注意,模式部分中的显式点将始终匹配点文件。¥
dot
Include.dot
files in normal matches andglobstar
matches. Note that an explicit dot in a portion of the pattern will always match dot files. -
magicalBraces
将括号扩展(如{a,b}
)视为 "magic" 模式。如果设置了{@link nobrace}
,则无效。¥
magicalBraces
Treat brace expansion like{a,b}
as a "magic" pattern. Has no effect if{@link nobrace}
is set.仅对
{@link hasMagic}
函数有效,对 glob 模式匹配本身没有影响。¥Only has effect on the
{@link hasMagic}
function, no effect on glob pattern matching itself. -
dotRelative
在所有相对路径字符串前面加上./
(或 Windows 上的.\
)。¥
dotRelative
Prepend all relative path strings with./
(or.\
on Windows).如果没有此选项,返回的相对路径是 "bare",因此它们不是返回
'./foo/bar'
,而是返回'foo/bar'
。¥Without this option, returned relative paths are "bare", so instead of returning
'./foo/bar'
, they are returned as'foo/bar'
.即使设置了此选项,以
'../'
开头的相对模式也不会以./
开头。¥Relative patterns starting with
'../'
are not prepended with./
, even if this option is set. -
mark
将/
字符添加到目录匹配项。请注意,这需要额外的 stat 调用。¥
mark
Add a/
character to directory matches. Note that this requires additional stat calls. -
nobrace
不要扩展{a,b}
和{1..3}
括号集。¥
nobrace
Do not expand{a,b}
and{1..3}
brace sets. -
noglobstar
不要将**
与多个文件名匹配。(即,将其视为普通*
。)¥
noglobstar
Do not match**
against multiple filenames. (Ie, treat it as a normal*
instead.) -
noext
不要匹配 "extglob" 模式,例如+(a|b)
。¥
noext
Do not match "extglob" patterns such as+(a|b)
. -
nocase
执行不区分大小写的匹配。这在 macOS 和 Windows 系统上默认为true
,在所有其他系统上默认为false
。¥
nocase
Perform a case-insensitive match. This defaults totrue
on macOS and Windows systems, andfalse
on all others.注意
nocase
应仅在已知文件系统的大小写区分度与平台默认值不同时明确设置。如果在区分大小写的文件系统上设置true
,或在区分大小写的文件系统上设置false
,则遍历可能返回比预期多或少的结果。¥Note
nocase
should only be explicitly set when it is known that the filesystem's case sensitivity differs from the platform default. If settrue
on case-sensitive file systems, orfalse
on case-insensitive file systems, then the walk may return more or less results than expected. -
maxDepth
指定一个数字以将目录遍历的深度限制为cwd
以下的这么多级别。¥
maxDepth
Specify a number to limit the depth of the directory traversal to this many levels below thecwd
. -
matchBase
如果模式不包含任何斜杠字符,则执行仅基本名称匹配。也就是说,*.js
将被视为等同于**/*.js
,匹配所有目录中的所有 js 文件。¥
matchBase
Perform a basename-only match if the pattern does not contain any slash characters. That is,*.js
would be treated as equivalent to**/*.js
, matching all js files in all directories. -
nodir
不匹配目录,只匹配文件。(注意:若要仅匹配目录,请在模式末尾放置/
。)¥
nodir
Do not match directories, only files. (Note: to match only directories, put a/
at the end of the pattern.)注意:当
follow
和nodir
都设置时,目录的符号链接也会被省略。¥Note: when
follow
andnodir
are both set, then symbolic links to directories are also omitted. -
stat
在所有条目上调用lstat()
,无论是否需要确定它是否是有效匹配。与withFileTypes
一起使用时,这意味着匹配将包括修改时间、权限等数据。请注意,由于增加了系统调用,这将导致性能成本。¥
stat
Calllstat()
on all entries, whether required or not to determine whether it's a valid match. When used withwithFileTypes
, this means that matches will include data such as modified time, permissions, and so on. Note that this will incur a performance cost due to the added system calls. -
ignore
字符串或字符串[],或具有ignore
和ignoreChildren
方法的对象。¥
ignore
string or string[], or an object withignore
andignoreChildren
methods.如果提供了字符串或 string[],则将其视为 glob 模式或 glob 模式数组,以排除在匹配之外。要忽略目录中的所有子项以及条目本身,请将
'/**'
附加到忽略模式。¥If a string or string[] is provided, then this is treated as a glob pattern or array of glob patterns to exclude from matches. To ignore all children within a directory, as well as the entry itself, append
'/**'
to the ignore pattern.注意
ignore
模式始终处于dot:true
模式,无论其他设置如何。¥Note
ignore
patterns are always indot:true
mode, regardless of any other settings.如果提供的对象具有
ignored(path)
和/或childrenIgnored(path)
方法,则将调用这些方法来确定任何 Path 是否匹配或是否应遍历其子项。¥If an object is provided that has
ignored(path)
and/orchildrenIgnored(path)
methods, then these methods will be called to determine whether any Path is a match or if its children should be traversed, respectively. -
follow
扩展**
模式时遵循符号链接目录。这可能会导致在存在循环链接的情况下出现大量重复引用,并使性能非常糟糕。¥
follow
Follow symlinked directories when expanding**
patterns. This can result in a lot of duplicate references in the presence of cyclic links, and make performance quite bad.默认情况下,如果模式中的
**
不是模式中的第一个项,它将遵循 1 个符号链接,如果它是模式中的第一个项,则遵循无符号链接,遵循与 Bash 相同的行为。¥By default, a
**
in a pattern will follow 1 symbolic link if it is not the first item in the pattern, or none if it is the first item in the pattern, following the same behavior as Bash.注意:当
follow
和nodir
都设置时,目录的符号链接也会被省略。¥Note: when
follow
andnodir
are both set, then symbolic links to directories are also omitted. -
realpath
设置为 true 以在所有结果上调用fs.realpath
。如果无法解析条目,则省略该条目。当然,由于增加了系统调用,这会导致轻微的性能损失。¥
realpath
Set to true to callfs.realpath
on all of the results. In the case of an entry that cannot be resolved, the entry is omitted. This incurs a slight performance penalty, of course, because of the added system calls. -
absolute
设置为 true 以始终接收匹配文件的绝对路径。设置为false
以始终接收匹配文件的相对路径。¥
absolute
Set to true to always receive absolute paths for matched files. Set tofalse
to always receive relative paths for matched files.默认情况下,当未设置此选项时,对于绝对模式,将返回绝对路径,否则将返回相对于
cwd
设置的路径。¥By default, when this option is not set, absolute paths are returned for patterns that are absolute, and otherwise paths are returned that are relative to the
cwd
setting.这不会进行额外的系统调用来获取真实路径,它只进行字符串路径解析。
¥This does not make an extra system call to get the realpath, it only does string path resolution.
absolute
不能与withFileTypes
一起使用。¥
absolute
may not be used along withwithFileTypes
. -
posix
设置为 true 以在返回的结果中使用/
作为路径分隔符。在 posix 系统上,这没有效果。在 Windows 系统上,这将返回/
分隔路径结果,并且绝对路径将以其完整解析的 UNC 路径形式返回,例如,它将返回//?/C:/foo/bar
,而不是'C:\\foo\\bar'
。¥
posix
Set to true to use/
as the path separator in returned results. On posix systems, this has no effect. On Windows systems, this will return/
delimited path results, and absolute paths will be returned in their full resolved UNC path form, eg insted of'C:\\foo\\bar'
, it will return//?/C:/foo/bar
. -
platform
如果可用,则默认为process.platform
的值,如果不可用,则默认为'linux'
。在非 Windows 系统上设置platform:'win32'
可能会导致奇怪的行为。¥
platform
Defaults to value ofprocess.platform
if available, or'linux'
if not. Settingplatform:'win32'
on non-Windows systems may cause strange behavior. -
withFileTypes
返回 PathScurryPath
对象而不是字符串。这些类似于 NodeJSDirent
对象,但具有附加方法和属性。¥
withFileTypes
Return PathScurryPath
objects instead of strings. These are similar to a NodeJSDirent
object, but with additional methods and properties.withFileTypes
不能与absolute
一起使用。¥
withFileTypes
may not be used along withabsolute
. -
signal
AbortSignal 将在触发时取消 Glob 遍历。¥
signal
An AbortSignal which will cancel the Glob walk when triggered. -
fs
用于传入自定义文件系统方法的覆盖对象。请参阅 PathScurry 文档 了解可以覆盖的内容。¥
fs
An override object to pass in custom filesystem methods. See PathScurry docs for what can be overridden. -
scurry
用于遍历文件系统的 PathScurry 对象。如果明确设置了nocase
选项,则任何提供的scurry
对象都必须与此设置匹配。¥
scurry
A PathScurry object used to traverse the file system. If thenocase
option is set explicitly, then any providedscurry
object must match this setting. -
includeChildMatches
布尔值,默认为true
。不要匹配任何匹配的任何子项。例如,在此模式下,模式**\/foo
将匹配a/foo
,但不匹配a/foo/b/foo
。¥
includeChildMatches
boolean, defaulttrue
. Do not match any children of any matches. For example, the pattern**\/foo
would matcha/foo
, but nota/foo/b/foo
in this mode.这对于“查找所有
node_modules
文件夹,但不查找node_modules
中的文件夹”等情况特别有用。¥This is especially useful for cases like "find all
node_modules
folders, but not the ones innode_modules
".为了支持这一点,
Ignore
实现必须支持add(pattern: string)
方法。如果使用默认的Ignore
类,那么这很好,但如果将其设置为false
,并且提供的自定义Ignore
没有add()
方法,那么它将引发错误。¥In order to support this, the
Ignore
implementation must support anadd(pattern: string)
method. If using the defaultIgnore
class, then this is fine, but if this is set tofalse
, and a customIgnore
is provided that does not have anadd()
method, then it will throw an error.警告它只忽略前一个匹配的后代的匹配,并且只有在遇到祖级后匹配该后代时才会忽略。由于文件系统遍历的顺序不确定,因此如果使用多个或带括号的模式,则匹配可能已经添加到其祖级之前。
¥Caveat It only ignores matches that would be a descendant of a previous match, and only if that descendant is matched after the ancestor is encountered. Since the file system walk happens in indeterminate order, it's possible that a match will already be added before its ancestor, if multiple or braced patterns are used.
例如:
¥For example:
const results = await glob(
[
// likely to match first, since it's just a stat
'a/b/c/d/e/f',
// this pattern is more complicated! It must to various readdir()
// calls and test the results against a regular expression, and that
// is certainly going to take a little bit longer.
//
// So, later on, it encounters a match at 'a/b/c/d/e', but it's too
// late to ignore a/b/c/d/e/f, because it's already been emitted.
'a/[bdf]/?/[a-z]/*',
],
{ includeChildMatches: false },
)最好仅在你可以合理地确定模式的任何组件都不可能与彼此的文件系统后代匹配,或者偶尔包含的子条目不会导致问题时才将其设置为
false
。¥It's best to only set this to
false
if you can be reasonably sure that no components of the pattern will potentially match one another's file system descendants, or if the occasional included child entry will not cause problems.
Glob 入门
¥Glob Primer
通过运行 man bash
并搜索 Pattern Matching
,可以找到有关 glob 模式扩展的更多信息。
¥Much more information about glob pattern expansion can be found
by running man bash
and searching for Pattern Matching
.
"Globs" 是你在命令行上执行 ls *.js
之类的操作时键入的模式,或者将 build/*
放入 .gitignore
文件中。
¥"Globs" are the patterns you type when you do stuff like ls *.js
on the command line, or put build/*
in a .gitignore
file.
在解析路径部分模式之前,括号部分将扩展为一个集合。括号部分以 {
开头并以 }
结尾,其中包含 2 个或更多逗号分隔的部分。括号部分可能包含斜杠字符,因此 a{/b/c,bcd}
将扩展为 a/b/c
和 abcd
。
¥Before parsing the path part patterns, braced sections are
expanded into a set. Braced sections start with {
and end with
}
, with 2 or more comma-delimited sections within. Braced
sections may contain slash characters, so a{/b/c,bcd}
would
expand into a/b/c
and abcd
.
以下字符在路径部分使用时具有特殊的魔法含义。除了 **
之外,这些匹配路径分隔符都不是(即所有平台上的 /
和 Windows 上的 \
)。
¥The following characters have special magic meaning when used in
a path portion. With the exception of **
, none of these match
path separators (ie, /
on all platforms, and \
on Windows).
-
*
在单个路径部分中匹配 0 个或更多字符。当单独出现在路径部分时,它必须匹配至少 1 个字符。如果未指定dot:true
,则*
将不会与路径部分开头的.
字符匹配。¥
*
Matches 0 or more characters in a single path portion. When alone in a path portion, it must match at least 1 character. Ifdot:true
is not specified, then*
will not match against a.
character at the start of a path portion. -
?
匹配 1 个字符。如果未指定dot:true
,则?
将不会与路径部分开头的.
字符匹配。¥
?
Matches 1 character. Ifdot:true
is not specified, then?
will not match against a.
character at the start of a path portion. -
[...]
匹配一系列字符,类似于 RegExp 范围。如果范围的第一个字符是!
或^
,则它匹配不在范围内的任何字符。如果第一个字符是]
,则它将被视为与\]
相同,而不是字符类的结尾。¥
[...]
Matches a range of characters, similar to a RegExp range. If the first character of the range is!
or^
then it matches any character not in the range. If the first character is]
, then it will be considered the same as\]
, rather than the end of the character class. -
!(pattern|pattern|pattern)
匹配任何不匹配任何提供的模式的内容。可能不包含/
字符。与*
类似,如果路径部分中单独存在,则路径部分必须至少有一个字符。¥
!(pattern|pattern|pattern)
Matches anything that does not match any of the patterns provided. May not contain/
characters. Similar to*
, if alone in a path portion, then the path portion must have at least one character. -
?(pattern|pattern|pattern)
匹配提供的模式的零个或一个出现。可能不包含/
字符。¥
?(pattern|pattern|pattern)
Matches zero or one occurrence of the patterns provided. May not contain/
characters. -
+(pattern|pattern|pattern)
匹配提供的模式的一个或多个出现。可能不包含/
字符。¥
+(pattern|pattern|pattern)
Matches one or more occurrences of the patterns provided. May not contain/
characters. -
*(a|b|c)
匹配提供的模式的零个或多个出现。可能不包含/
字符。¥
*(a|b|c)
Matches zero or more occurrences of the patterns provided. May not contain/
characters. -
@(pattern|pat*|pat?erN)
匹配提供的模式之一。可能不包含/
字符。¥
@(pattern|pat*|pat?erN)
Matches exactly one of the patterns provided. May not contain/
characters. -
**
如果 "globstar" 单独存在于路径部分中,则它会匹配零个或多个搜索匹配项的目录和子目录。它不会抓取符号链接目录,除非在选项对象中传递了{follow:true}
。如果a/b
是目录,像a/b/**
这样的模式将仅与a/b
匹配。如果不是模式中的第一个项,则遵循 1 个符号链接,如果它是第一个项,则遵循 0,除非设置了follow:true
,在这种情况下它会遵循所有符号链接。¥
**
If a "globstar" is alone in a path portion, then it matches zero or more directories and subdirectories searching for matches. It does not crawl symlinked directories, unless{follow:true}
is passed in the options object. A pattern likea/b/**
will only matcha/b
if it is a directory. Follows 1 symbolic link if not the first item in the pattern, or 0 if it is the first item, unlessfollow:true
is set, in which case it follows all symbolic links.
此实现支持 [:class:]
模式,但不支持 [=c=]
和 [.symbol.]
样式类模式。
¥[:class:]
patterns are supported by this implementation, but
[=c=]
and [.symbol.]
style class patterns are not.
点
¥Dots
如果文件或目录路径部分的第一个字符是 .
,则它将与任何 glob 模式不匹配,除非该模式的相应路径部分的第一个字符也是 .
。
¥If a file or directory path portion has a .
as the first
character, then it will not match any glob pattern unless that
pattern's corresponding path part also has a .
as its first
character.
例如,模式 a/.*/c
将匹配 a/.b/c
处的文件。但是模式 a/*/c
不会,因为 *
不是以点字符开头。
¥For example, the pattern a/.*/c
would match the file at
a/.b/c
. However the pattern a/*/c
would not, because *
does
not start with a dot character.
你可以通过在选项中设置 dot:true
来让 glob 将点视为普通字符。
¥You can make glob treat dots as normal characters by setting
dot:true
in the options.
基本名称匹配
¥Basename Matching
如果你在选项中设置了 matchBase:true
,并且模式中没有斜杠,那么它将在树中的任何位置寻找具有匹配基本名称的任何文件。例如,*.js
将匹配 test/simple/basic.js
。
¥If you set matchBase:true
in the options, and the pattern has
no slashes in it, then it will seek for any file anywhere in the
tree with a matching basename. For example, *.js
would match
test/simple/basic.js
.
空集
¥Empty Sets
如果未找到匹配的文件,则返回一个空数组。这与 shell 不同,shell 会返回模式本身。例如:
¥If no matching files are found, then an empty array is returned. This differs from the shell, where the pattern itself is returned. For example:
$ echo a*s*d*f
a*s*d*f
与其他 fnmatch/glob 实现的比较
¥Comparisons to other fnmatch/glob implementations
虽然严格遵守现有标准是一个值得追求的目标,但 node-glob 与其他实现之间存在一些差异,这是故意的。
¥While strict compliance with the existing standards is a worthwhile goal, some discrepancies exist between node-glob and other implementations, and are intentional.
除非设置了 noglobstar
标志,否则默认情况下支持双星字符 **
。这以 bsdglob 和 bash 5 的方式支持,其中 **
仅在它是路径部分中唯一的东西时才具有特殊意义。也就是说,a/**/b
将匹配 a/x/y/b
,但 a/**b
不会。
¥The double-star character **
is supported by default, unless
the noglobstar
flag is set. This is supported in the manner of
bsdglob and bash 5, where **
only has special significance if
it is the only thing in a path part. That is, a/**/b
will match
a/x/y/b
, but a/**b
will not.
请注意,符号链接目录不会作为 **
的一部分进行遍历,尽管它们的内容可能与模式的后续部分匹配。这可以防止无限循环和重复等。你可以通过在选项中设置 {follow:true}
来强制 glob 使用 **
遍历符号链接。
¥Note that symlinked directories are not traversed as part of a
**
, though their contents may match against subsequent portions
of the pattern. This prevents infinite loops and duplicates and
the like. You can force glob to traverse symlinks with **
by
setting {follow:true}
in the options.
没有与 nonull
选项等效的选项。找不到任何匹配项的模式将解析为无。(空数组、立即结束的流等)
¥There is no equivalent of the nonull
option. A pattern that
does not find any matches simply resolves to nothing. (An empty
array, immediately ended stream, etc.)
如果未禁用括号扩展,则在对 glob 模式进行任何其他解释之前执行括号扩展。因此,像 +(a|{b),c)}
这样的模式在 bash 或 zsh 中无效,首先扩展到 +(a|b)
和 +(a|c)
的集合中,然后检查这些模式的有效性。由于这两个有效,因此匹配继续进行。
¥If brace expansion is not disabled, then it is performed before
any other interpretation of the glob pattern. Thus, a pattern
like +(a|{b),c)}
, which would not be valid in bash or zsh, is
expanded first into the set of +(a|b)
and +(a|c)
, and
those patterns are checked for validity. Since those two are
valid, matching proceeds.
字符类模式 [:class:]
(posix 标准命名类)样式类模式受支持且支持 unicode,但不支持 [=c=]
(特定于语言环境的字符排序权重)和 [.symbol.]
(排序符号)。
¥The character class patterns [:class:]
(posix standard named
classes) style class patterns are supported and unicode-aware,
but [=c=]
(locale-specific character collation weight), and
[.symbol.]
(collating symbol), are not.
重复斜杠
¥Repeated Slashes
与 Bash 和 zsh 不同,重复的 /
始终合并为单个路径分隔符。
¥Unlike Bash and zsh, repeated /
are always coalesced into a
single path separator.
注释和否定
¥Comments and Negation
以前,此模块允许你将以 #
字符开头的模式标记为 "comment",或以 !
字符开头的模式标记为 "negated" 模式。
¥Previously, this module let you mark a pattern as a "comment" if
it started with a #
character, or a "negated" pattern if it
started with a !
character.
这些选项在版本 5 中已弃用,并在版本 6 中删除。
¥These options were deprecated in version 5, and removed in version 6.
要指定不应匹配的内容,请使用 ignore
选项。
¥To specify things that should not match, use the ignore
option.
Windows
请仅在 glob 表达式中使用正斜杠。
¥Please only use forward-slashes in glob expressions.
虽然 Windows 使用 /
或 \
作为其路径分隔符,但此 glob 实现仅使用 /
字符。你必须仅在 glob 表达式中使用正斜杠。反斜杠将始终被解释为转义字符,而不是路径分隔符。
¥Though windows uses either /
or \
as its path separator, only
/
characters are used by this glob implementation. You must use
forward-slashes only in glob expressions. Back-slashes will
always be interpreted as escape characters, not path separators.
使用 path.join
将绝对模式(例如 /foo/*
)的结果安装到根设置上。在 Windows 上,这将默认导致 /foo/*
匹配 C:\foo\bar.txt
。
¥Results from absolute patterns such as /foo/*
are mounted onto
the root setting using path.join
. On windows, this will by
default result in /foo/*
matching C:\foo\bar.txt
.
要自动将模式字符串中的所有 \
字符强制转换为 /
,从而使无法转义字面量 glob 字符,你可以将 windowsPathsNoEscape
选项设置为 true
。
¥To automatically coerce all \
characters to /
in pattern
strings, thus making it impossible to escape literal glob
characters, you may set the windowsPathsNoEscape
option to
true
.
Windows、CWD、驱动器号和 UNC 路径
¥Windows, CWDs, Drive Letters, and UNC Paths
在 posix 系统上,当模式以 /
开头时,任何 cwd
选项都将被忽略,遍历从 /
开始,加上模式中指定的任何非魔法路径部分。
¥On posix systems, when a pattern starts with /
, any cwd
option is ignored, and the traversal starts at /
, plus any
non-magic path portions specified in the pattern.
在 Windows 系统上,行为类似,但 "绝对路径" 的概念更为复杂。
¥On Windows systems, the behavior is similar, but the concept of an "absolute path" is somewhat more involved.
UNC 路径
¥UNC Paths
在 Windows 平台上,UNC 路径可用作模式的开头。例如,像这样的模式://?/x:/*
将返回 x:
驱动器根目录中的所有文件条目。像 //ComputerName/Share/*
这样的模式将返回关联共享中的所有文件。
¥A UNC path may be used as the start of a pattern on Windows
platforms. For example, a pattern like: //?/x:/*
will return
all file entries in the root of the x:
drive. A pattern like
//ComputerName/Share/*
will return all files in the associated
share.
UNC 路径根始终不区分大小写进行比较。
¥UNC path roots are always compared case insensitively.
驱动器号
¥Drive Letters
以驱动器号开头的模式(如 c:/*
)将在该驱动器中搜索,无论提供任何 cwd
选项。
¥A pattern starting with a drive letter, like c:/*
, will search
in that drive, regardless of any cwd
option provided.
如果模式以 /
开头,并且不是 UNC 路径,并且有一个带有驱动器号的明确 cwd
选项设置,则 cwd
中的驱动器号将用作目录遍历的根目录。
¥If the pattern starts with /
, and is not a UNC path, and there
is an explicit cwd
option set with a drive letter, then the
drive letter in the cwd
is used as the root of the directory
traversal.
例如,glob('/tmp', { cwd: 'c:/any/thing' })
将返回 ['c:/tmp']
作为结果。
¥For example, glob('/tmp', { cwd: 'c:/any/thing' })
will return
['c:/tmp']
as the result.
如果没有提供明确的 cwd
选项,并且模式以 /
开头,则遍历将在作为 cwd
选项提供的驱动器的根目录上运行。(即,它是 path.resolve('/')
的结果。)
¥If an explicit cwd
option is not provided, and the pattern
starts with /
, then the traversal will run on the root of the
drive provided as the cwd
option. (That is, it is the result of
path.resolve('/')
.)
竞争条件
¥Race Conditions
Glob 搜索本质上容易受到竞争条件的影响,因为它依赖于目录遍历。
¥Glob searching, by its very nature, is susceptible to race conditions, since it relies on directory walking.
因此,当 glob 查找时存在的文件可能在返回结果时已被删除或修改。
¥As a result, it is possible that a file that exists when glob looks for it may have been deleted or modified by the time it returns the result.
根据设计,此实现会缓存它进行的所有 readdir 调用,以减少系统开销。但是,这也使其更容易受到竞争的影响,特别是如果缓存对象在 glob 调用之间被重用。
¥By design, this implementation caches all readdir calls that it makes, in order to cut down on system overhead. However, this also makes it even more susceptible to races, especially if the cache object is reused between glob calls.
因此,建议用户在快速变化的情况下不要使用 glob 结果作为文件系统状态的保证。对于绝大多数操作,这从来都不是问题。
¥Users are thus advised not to use a glob result as a guarantee of filesystem state in the face of rapid changes. For the vast majority of operations, this is never a problem.
另请参阅:
¥See Also:
-
man sh
-
man bash
模式匹配¥
man bash
Pattern Matching -
man 3 fnmatch
-
man 5 gitignore
Glob 徽标
¥Glob Logo
Glob 的徽标由 Tanya Brassie 创建。可以在 此处 中找到徽标文件。
¥Glob's logo was created by Tanya Brassie. Logo files can be found here.
徽标在 Creative Commons 署名-相同方式共享 4.0 国际许可证 下获得许可。
¥The logo is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
贡献
¥Contributing
任何行为更改(包括错误修复)都必须附带测试。
¥Any change to behavior (including bugfixes) must come with a test.
未通过测试或降低性能的补丁将被拒绝。
¥Patches that fail tests or reduce performance will be rejected.
# to run tests
npm test
# to re-generate test fixtures
npm run test-regen
# run the benchmarks
npm run bench
# to profile javascript
npm run prof
与其他 JavaScript Glob 实现的比较
¥Comparison to Other JavaScript Glob Implementations
tl;dr
-
如果你希望全局匹配尽可能忠实于 Bash 模式扩展语义,并且在该约束内尽可能快,请使用此模块。
¥If you want glob matching that is as faithful as possible to Bash pattern expansion semantics, and as fast as possible within that constraint, use this module.
-
如果你有理由确定你将遇到的模式相对简单,并且想要绝对最快的 glob 匹配器,请使用 fast-glob。
¥If you are reasonably sure that the patterns you will encounter are relatively simple, and want the absolutely fastest glob matcher out there, use fast-glob.
-
如果你有理由确定你将遇到的模式相对简单,并且想要自动尊重
.gitignore
文件的便利,请使用 globby。¥If you are reasonably sure that the patterns you will encounter are relatively simple, and want the convenience of automatically respecting
.gitignore
files, use globby.
npm 上还有一些其他 glob 匹配器库,但这三个(在我看来,截至 2023 年)是最好的。
¥There are some other glob matcher libraries on npm, but these three are (in my opinion, as of 2023) the best.
完整解释
¥full explanation
每个库都反映了它所做的权衡中的一组意见和优先事项。除了这个库,我个人推荐 globby 和 fast-glob,尽管它们的优点和缺点有所不同。
¥Every library reflects a set of opinions and priorities in the trade-offs it makes. Other than this library, I can personally recommend both globby and fast-glob, though they differ in their benefits and drawbacks.
两者都有非常好的 API,并且速度相当快。
¥Both have very nice APIs and are reasonably fast.
据我所知,fast-glob
是当今 JavaScript 中最快的 glob 实现。但是,在许多情况下,fast-glob
为追求速度而做出的选择意味着其结果与 Bash 和其他类似 sh 的 shell 返回的结果不同,这可能会令人惊讶。
¥fast-glob
is, as far as I am aware, the fastest glob
implementation in JavaScript today. However, there are many
cases where the choices that fast-glob
makes in pursuit of
speed mean that its results differ from the results returned by
Bash and other sh-like shells, which may be surprising.
在我的测试中,当遍历嵌套在 4 个目录 deep1 中的 200k 个文件时,fast-glob
比此模块快 10-20%。但是,Bash 匹配行为存在一些不一致之处,而此模块不会受到影响:
¥In my testing, fast-glob
is around 10-20% faster than this
module when walking over 200k files nested 4 directories
deep1. However, there are some inconsistencies
with Bash matching behavior that this module does not suffer
from:
-
**
仅匹配文件,不匹配目录¥
**
only matches files, not directories -
..
路径部分除非出现在模式开头,否则不会被处理¥
..
path portions are not handled unless they appear at the start of the pattern -
./!(<pattern>)
不会匹配任何以<pattern>
开头的文件,即使它们与<pattern>
不匹配。例如,!(9).txt
将不匹配9999.txt
。¥
./!(<pattern>)
will not match any files that start with<pattern>
, even if they do not match<pattern>
. For example,!(9).txt
will not match9999.txt
. -
模式中间的一些括号模式将导致无法找到某些匹配项。
¥Some brace patterns in the middle of a pattern will result in failing to find certain matches.
-
Extglob 模式允许包含
/
个字符。¥Extglob patterns are allowed to contain
/
characters.
Globby 表现出与 fast-glob 相同的所有模式语义(因为它是 fast-glob 的封装器),并且比 node-glob 稍慢(在基准测试集中大约慢 10-20%,换句话说,比 fast-glob 慢 20-50%)。但是,它增加了一些可能值得付出代价的 API 便利。
¥Globby exhibits all of the same pattern semantics as fast-glob, (as it is a wrapper around fast-glob) and is slightly slower than node-glob (by about 10-20% in the benchmark test set, or in other words, anywhere from 20-50% slower than fast-glob). However, it adds some API conveniences that may be worth the costs.
-
支持
.gitignore
和其他忽略文件。¥Support for
.gitignore
and other ignore files. -
支持否定通配符(即,以
!
开头的模式,而不是使用单独的ignore
选项)。¥Support for negated globs (ie, patterns starting with
!
rather than using a separateignore
option).
此模块的优先级是 "correctness",意思是尽可能忠实地执行 glob 模式扩展,以符合 Bash 和其他类似 sh 的 shell 的行为,并尽可能快。
¥The priority of this module is "correctness" in the sense of performing a glob pattern expansion as faithfully as possible to the behavior of Bash and other sh-like shells, with as much speed as possible.
请注意,node-glob
的先前版本不在此列表中。此模块的以前版本对于任何性能至关重要的情况来说都太慢了,并且是使用与当前 JavaScript 标准极为过时的 API 设计的。
¥Note that prior versions of node-glob
are not on this list.
Former versions of this module are far too slow for any cases
where performance matters at all, and were designed with APIs
that are extremely dated by current JavaScript standards.
[1]:如果此模块返回结果而
fast-glob
没有返回结果,那么当然速度会更快。
¥[1]: In the cases where this module
returns results and fast-glob
doesn't, it's even faster, of
course.
基准测试结果
¥Benchmark Results
第一个数字是时间,越小越好。
¥First number is time, smaller is better.
第二个数字是返回的结果数。
¥Second number is the count of results returned.
--- pattern: '**' ---
~~ sync ~~
node fast-glob sync 0m0.598s 200364
node globby sync 0m0.765s 200364
node current globSync mjs 0m0.683s 222656
node current glob syncStream 0m0.649s 222656
~~ async ~~
node fast-glob async 0m0.350s 200364
node globby async 0m0.509s 200364
node current glob async mjs 0m0.463s 222656
node current glob stream 0m0.411s 222656
--- pattern: '**/..' ---
~~ sync ~~
node fast-glob sync 0m0.486s 0
node globby sync 0m0.769s 200364
node current globSync mjs 0m0.564s 2242
node current glob syncStream 0m0.583s 2242
~~ async ~~
node fast-glob async 0m0.283s 0
node globby async 0m0.512s 200364
node current glob async mjs 0m0.299s 2242
node current glob stream 0m0.312s 2242
--- pattern: './**/0/**/0/**/0/**/0/**/*.txt' ---
~~ sync ~~
node fast-glob sync 0m0.490s 10
node globby sync 0m0.517s 10
node current globSync mjs 0m0.540s 10
node current glob syncStream 0m0.550s 10
~~ async ~~
node fast-glob async 0m0.290s 10
node globby async 0m0.296s 10
node current glob async mjs 0m0.278s 10
node current glob stream 0m0.302s 10
--- pattern: './**/[01]/**/[12]/**/[23]/**/[45]/**/*.txt' ---
~~ sync ~~
node fast-glob sync 0m0.500s 160
node globby sync 0m0.528s 160
node current globSync mjs 0m0.556s 160
node current glob syncStream 0m0.573s 160
~~ async ~~
node fast-glob async 0m0.283s 160
node globby async 0m0.301s 160
node current glob async mjs 0m0.306s 160
node current glob stream 0m0.322s 160
--- pattern: './**/0/**/0/**/*.txt' ---
~~ sync ~~
node fast-glob sync 0m0.502s 5230
node globby sync 0m0.527s 5230
node current globSync mjs 0m0.544s 5230
node current glob syncStream 0m0.557s 5230
~~ async ~~
node fast-glob async 0m0.285s 5230
node globby async 0m0.305s 5230
node current glob async mjs 0m0.304s 5230
node current glob stream 0m0.310s 5230
--- pattern: '**/*.txt' ---
~~ sync ~~
node fast-glob sync 0m0.580s 200023
node globby sync 0m0.771s 200023
node current globSync mjs 0m0.685s 200023
node current glob syncStream 0m0.649s 200023
~~ async ~~
node fast-glob async 0m0.349s 200023
node globby async 0m0.509s 200023
node current glob async mjs 0m0.427s 200023
node current glob stream 0m0.388s 200023
--- pattern: '{**/*.txt,**/?/**/*.txt,**/?/**/?/**/*.txt,**/?/**/?/**/?/**/*.txt,**/?/**/?/**/?/**/?/**/*.txt}' ---
~~ sync ~~
node fast-glob sync 0m0.589s 200023
node globby sync 0m0.771s 200023
node current globSync mjs 0m0.716s 200023
node current glob syncStream 0m0.684s 200023
~~ async ~~
node fast-glob async 0m0.351s 200023
node globby async 0m0.518s 200023
node current glob async mjs 0m0.462s 200023
node current glob stream 0m0.468s 200023
--- pattern: '**/5555/0000/*.txt' ---
~~ sync ~~
node fast-glob sync 0m0.496s 1000
node globby sync 0m0.519s 1000
node current globSync mjs 0m0.539s 1000
node current glob syncStream 0m0.567s 1000
~~ async ~~
node fast-glob async 0m0.285s 1000
node globby async 0m0.299s 1000
node current glob async mjs 0m0.305s 1000
node current glob stream 0m0.301s 1000
--- pattern: './**/0/**/../[01]/**/0/../**/0/*.txt' ---
~~ sync ~~
node fast-glob sync 0m0.484s 0
node globby sync 0m0.507s 0
node current globSync mjs 0m0.577s 4880
node current glob syncStream 0m0.586s 4880
~~ async ~~
node fast-glob async 0m0.280s 0
node globby async 0m0.298s 0
node current glob async mjs 0m0.327s 4880
node current glob stream 0m0.324s 4880
--- pattern: '**/????/????/????/????/*.txt' ---
~~ sync ~~
node fast-glob sync 0m0.547s 100000
node globby sync 0m0.673s 100000
node current globSync mjs 0m0.626s 100000
node current glob syncStream 0m0.618s 100000
~~ async ~~
node fast-glob async 0m0.315s 100000
node globby async 0m0.414s 100000
node current glob async mjs 0m0.366s 100000
node current glob stream 0m0.345s 100000
--- pattern: './{**/?{/**/?{/**/?{/**/?,,,,},,,,},,,,},,,}/**/*.txt' ---
~~ sync ~~
node fast-glob sync 0m0.588s 100000
node globby sync 0m0.670s 100000
node current globSync mjs 0m0.717s 200023
node current glob syncStream 0m0.687s 200023
~~ async ~~
node fast-glob async 0m0.343s 100000
node globby async 0m0.418s 100000
node current glob async mjs 0m0.519s 200023
node current glob stream 0m0.451s 200023
--- pattern: '**/!(0|9).txt' ---
~~ sync ~~
node fast-glob sync 0m0.573s 160023
node globby sync 0m0.731s 160023
node current globSync mjs 0m0.680s 180023
node current glob syncStream 0m0.659s 180023
~~ async ~~
node fast-glob async 0m0.345s 160023
node globby async 0m0.476s 160023
node current glob async mjs 0m0.427s 180023
node current glob stream 0m0.388s 180023
--- pattern: './{*/**/../{*/**/../{*/**/../{*/**/../{*/**,,,,},,,,},,,,},,,,},,,,}/*.txt' ---
~~ sync ~~
node fast-glob sync 0m0.483s 0
node globby sync 0m0.512s 0
node current globSync mjs 0m0.811s 200023
node current glob syncStream 0m0.773s 200023
~~ async ~~
node fast-glob async 0m0.280s 0
node globby async 0m0.299s 0
node current glob async mjs 0m0.617s 200023
node current glob stream 0m0.568s 200023
--- pattern: './*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/*.txt' ---
~~ sync ~~
node fast-glob sync 0m0.485s 0
node globby sync 0m0.507s 0
node current globSync mjs 0m0.759s 200023
node current glob syncStream 0m0.740s 200023
~~ async ~~
node fast-glob async 0m0.281s 0
node globby async 0m0.297s 0
node current glob async mjs 0m0.544s 200023
node current glob stream 0m0.464s 200023
--- pattern: './*/**/../*/**/../*/**/../*/**/../*/**/*.txt' ---
~~ sync ~~
node fast-glob sync 0m0.486s 0
node globby sync 0m0.513s 0
node current globSync mjs 0m0.734s 200023
node current glob syncStream 0m0.696s 200023
~~ async ~~
node fast-glob async 0m0.286s 0
node globby async 0m0.296s 0
node current glob async mjs 0m0.506s 200023
node current glob stream 0m0.483s 200023
--- pattern: './0/**/../1/**/../2/**/../3/**/../4/**/../5/**/../6/**/../7/**/*.txt' ---
~~ sync ~~
node fast-glob sync 0m0.060s 0
node globby sync 0m0.074s 0
node current globSync mjs 0m0.067s 0
node current glob syncStream 0m0.066s 0
~~ async ~~
node fast-glob async 0m0.060s 0
node globby async 0m0.075s 0
node current glob async mjs 0m0.066s 0
node current glob stream 0m0.067s 0
--- pattern: './**/?/**/?/**/?/**/?/**/*.txt' ---
~~ sync ~~
node fast-glob sync 0m0.568s 100000
node globby sync 0m0.651s 100000
node current globSync mjs 0m0.619s 100000
node current glob syncStream 0m0.617s 100000
~~ async ~~
node fast-glob async 0m0.332s 100000
node globby async 0m0.409s 100000
node current glob async mjs 0m0.372s 100000
node current glob stream 0m0.351s 100000
--- pattern: '**/*/**/*/**/*/**/*/**' ---
~~ sync ~~
node fast-glob sync 0m0.603s 200113
node globby sync 0m0.798s 200113
node current globSync mjs 0m0.730s 222137
node current glob syncStream 0m0.693s 222137
~~ async ~~
node fast-glob async 0m0.356s 200113
node globby async 0m0.525s 200113
node current glob async mjs 0m0.508s 222137
node current glob stream 0m0.455s 222137
--- pattern: './**/*/**/*/**/*/**/*/**/*.txt' ---
~~ sync ~~
node fast-glob sync 0m0.622s 200000
node globby sync 0m0.792s 200000
node current globSync mjs 0m0.722s 200000
node current glob syncStream 0m0.695s 200000
~~ async ~~
node fast-glob async 0m0.369s 200000
node globby async 0m0.527s 200000
node current glob async mjs 0m0.502s 200000
node current glob stream 0m0.481s 200000
--- pattern: '**/*.txt' ---
~~ sync ~~
node fast-glob sync 0m0.588s 200023
node globby sync 0m0.771s 200023
node current globSync mjs 0m0.684s 200023
node current glob syncStream 0m0.658s 200023
~~ async ~~
node fast-glob async 0m0.352s 200023
node globby async 0m0.516s 200023
node current glob async mjs 0m0.432s 200023
node current glob stream 0m0.384s 200023
--- pattern: './**/**/**/**/**/**/**/**/*.txt' ---
~~ sync ~~
node fast-glob sync 0m0.589s 200023
node globby sync 0m0.766s 200023
node current globSync mjs 0m0.682s 200023
node current glob syncStream 0m0.652s 200023
~~ async ~~
node fast-glob async 0m0.352s 200023
node globby async 0m0.523s 200023
node current glob async mjs 0m0.436s 200023
node current glob stream 0m0.380s 200023
--- pattern: '**/*/*.txt' ---
~~ sync ~~
node fast-glob sync 0m0.592s 200023
node globby sync 0m0.776s 200023
node current globSync mjs 0m0.691s 200023
node current glob syncStream 0m0.659s 200023
~~ async ~~
node fast-glob async 0m0.357s 200023
node globby async 0m0.513s 200023
node current glob async mjs 0m0.471s 200023
node current glob stream 0m0.424s 200023
--- pattern: '**/*/**/*.txt' ---
~~ sync ~~
node fast-glob sync 0m0.585s 200023
node globby sync 0m0.766s 200023
node current globSync mjs 0m0.694s 200023
node current glob syncStream 0m0.664s 200023
~~ async ~~
node fast-glob async 0m0.350s 200023
node globby async 0m0.514s 200023
node current glob async mjs 0m0.472s 200023
node current glob stream 0m0.424s 200023
--- pattern: '**/[0-9]/**/*.txt' ---
~~ sync ~~
node fast-glob sync 0m0.544s 100000
node globby sync 0m0.636s 100000
node current globSync mjs 0m0.626s 100000
node current glob syncStream 0m0.621s 100000
~~ async ~~
node fast-glob async 0m0.322s 100000
node globby async 0m0.404s 100000
node current glob async mjs 0m0.360s 100000
node current glob stream 0m0.352s 100000