Gulp src 文件匹配规则
Glob 详解
glob 是由普通字符和通配字符组成的字符串,用于匹配文件路径,一般叫文件匹配规则,glob只是使用的技术叫法。
可以利用一个或多个文件匹配规则在系统中定位文件。
src()
方法接受一个或由多个匹配规则组成的数组作为参数,用于确定哪些文件需要被操作。
glob 或 glob 数组必须至少匹配到一个匹配项,否则 src()
将报错。当使用 glob 数组时,将按照每个 glob 在数组中的位置依次执行匹配,这在取反操作中很有用。
文件匹配
往往我们在使用 src 方法的时候需要输入多个或者一类文件,而不仅仅是某个具体的文件,这时我们就可以使用 gulp 提供的匹配规则来处理。
匹配符 | 说明 |
---|---|
"src/file.js" |
单个文件 |
["src/file1,src/file2.js"] |
多个文件 |
* |
匹配文件路径中的 0 个或多个字符,但不会匹配路径分割符, 除非分隔符出现在末尾 |
** |
匹配路径的 0 个会多个目录及子目录 需要单独出现, 即他左右不能有其他的东西了如果出现在末尾,也能匹配文件 |
{} |
多个属性 |
? |
匹配文件路径中的一个字符(不能匹配路径分割符 /) |
! |
排除 |
[...] |
匹配方括号中 出现字符的任意一个,当方括号中第一个字符为 ^ 或!时, 则表示不匹配方括号中出现字符中的任意一个, 类似于 js 中正则表达式中的用法 |
!(pattern | pattern | pattern) |
匹配括匹配任何与括号中给定的任意模式都不匹配 |
?(pattern | pattern | pattern) |
匹配括号中给定的任意模式 0 次或 1 次 |
+(pattern | pattern | pattern) |
匹配括号中的至少一次 |
*(pattern | pattern | pattern) |
匹配括号中给定的任意模式 0 次或多次 |
@(pattern | pattern | pattern) |
匹配括号中 给定的任意模式一次 |
例子演示
src('src/*.{jpg,png,gif}') // src自身目录下的所有jpg、png和gif文件
src(['**/*.js', '!node_modules/**']) // 所有的js文件,但是node_modules下的除外
注意:src 接收的文件匹配字符串会顺序解释,所以你可以写成这样 gulp.src([’.js’, ‘!b.js’, ‘bad.js’])(排除所有以 b 开头的 JS 文件但是除了 bad.js)
* 一个星号
在一个字符串片段中匹配任意数量的字符,包括零个匹配。对于匹配单级目录下的文件很有用。
下面这个 glob 能够匹配类似 index.js
的文件,但是不能匹配类似 scripts/index.js
或 scripts/nested/index.js
的文件。
'*.js'
下面是匹配src
内的文件
src('src/*.js') // src自身目录所有的js文件,不含后代文件夹中
src('src/a*c.js')
** 两个星号
在多个字符串片段中匹配任意数量的字符,包括零个匹配。
对于匹配嵌套目录下的文件很有用。请确保适当地限制带有两个星号的 glob 的使用,以避免匹配大量不必要的目录。
下面这个 glob 被限制在 scripts/
目录下所有的js文件,含后代文件夹中的所有的js文件
它将匹配类似 scripts/index.js
、scripts/nested/index.js
和 scripts/nested/twice/index.js
的文件。
'scripts/**/*.js'
在上面的示例中,如果没有 scripts/
这个前缀做限制,node_modules
目录下的所有目录或其他目录也都将被匹配。
! 取反
由于 glob 匹配时是按照每个 glob 在数组中的位置依次进行匹配操作的,所以 glob 数组中的取反(negative)glob 必须跟在一个非取反(non-negative)的 glob 后面。
第一个 glob 匹配到一组匹配项,然后后面的取反 glob 删除这些匹配项中的一部分。
['script/**/*.js', '!scripts/vendor/']
如果任何非取反(non-negative)的 glob 跟随着一个取反(negative) glob,任何匹配项都不会被删除。
['script/**/*.js', '!scripts/vendor/', 'scripts/vendor/react.js']
取反(negative) glob 可以作为对带有两个星号的 glob 的限制手段。
如果取反 glob 只是由普通字符组成的字符串,则执行效率是最高的。
['**/*.js', '!node_modules/']
在上面的示例中,如果取反(negative)glob 是 !node_modules/**/*.js
,那么各匹配项都必须与取反 glob 进行比较,这将导致执行速度极慢,'!node_modules/'
这种才是效率最高的。
重复匹配
两个或多个 glob 故意或无意匹配了相同的文件就被认为是匹配重叠(overlapping)了,国内我们一般叫重复匹配。
- 如果在同一个
src()
中使用了会产生匹配重叠的 glob,gulp 将尽力去除重叠部分 - 如果在多个
src()
调用时产生的匹配重叠是不会被去重的。
不要使用Nodejs获取到的路径
字符串片段(segment)是指两个分隔符之间的所有字符组成的字符串。
在 glob 中,路径中的分隔符永远是 /
字符 ,无论什么系统内都是这样,不区分操作系统;
即便是在采用 \\
作为分隔符的 Windows 操作系统中。在 glob 中,\\
字符被保留作为转义符使用。
如下, \*
被转义了,因此,\*
将被作为一个普通字符使用,而不再是通配符了。
'glob_with_uncommon_\\*_character.js'
避免使用 Node 的 path
类方法来创建 glob,例如 path.join
。在 Windows 中,由于 Node 使用 \\
作为路径分隔符,因此将会产生一个无效的 glob。还要避免使用 __dirname
和 __filename
全局变量,由于同样的原因,process.cwd()
方法也要避免使用。
const invalidGlob = path.join(__dirname, 'src/*.js');
进阶资料
关于如何在 gulp 中使用 glob 的知识都已经在在上面的文档中讲解了。如果你还希望获取更多进阶资料,请参考下面列出的部分: