glob

8 3月

glob用于正则匹配文件。

  • 特殊字符
  • API(glob,sync,hasMagic)
  • Glob类
  • glob-promise
  • globby

特殊字符

以下字符有特殊的含义:

  • * 匹配0或多个字符
  • *(a|b|c) 匹配0或多个满足表达式的内容
  • ? 匹配1个字符
  • ?(pattern|pattern|pattern) 匹配0或1个满足表达式的内容
  • +(pattern|pattern|pattern) 匹配1或多个满足表达式的内容
  • !(pattern|pattern|pattern) 匹配不满足表达式的内容
  • @(pattern|pat*|pat?erN) 精确匹配其中之一
  • ** 设置了globstar后,**的匹配范围更广一些,可以匹配当前目录(包括子目录)里的所有文件。当未设置globstar时,**的作用和*是相同的
  • […] 匹配范围内的字符,如果第一个字符是 !^ 将会取反,即不匹配范围内的字符

注意默认不会匹配 .点开头的文件或文件夹,除非你显示地指定。例如a/*/c不会匹配a/.b/c,因为*星号默认会忽略 .开头的文件或文件夹。如果文件就是 .点开头,可以这样a/.*/c,将会匹配a/.b/c。当然你可以在options里设置dot:true将 .点当作一个普通字符来处理。

API(glob,sync,hasMagic)

glob(pattern, [options], cb)

const glob = require("glob");

// 获取src根目录下的所有js文件
glob("src/*.js", {}, (err, files) => {
     console.log(files);
});

// 获取src目录下(包括子目录)的所有js文件
glob("src/**/*.js", {}, (err, files) => {
    console.log(files);
});

// 获取 ch 开头的文件
glob("src/ch*.js",function (er, files) {
    console.log(files);
});

glob.sync(pattern, [options])同步版方法,同上。返回值是匹配到的文件名数组。

glob.hasMagic(pattern, [options])判断表达式里是否含有特殊符号,有就返回true,无则返回false。不知道有什么实际应用场景…

Glob类

也可以自己new一个glob对象,返回值是一个EventEmitter:

var Glob = require("glob").Glob
var g = new Glob(pattern, options, cb)    // 参数和glob(pattern,options,cb)是一样的

如果在选项中设置sync:true,表示同步匹配。可以不传入cb回调。要获取匹配结果,可以通过g.found来获取:

const g = new glob.Glob("src/@(ch*|ex*|li*).js", {nonull:true, matchBase:true, sync:true});
console.log(g.found);

事件:

  • match:会在每次匹配到一个文件的时候触发,参数是匹配到的文件
  • end:会在文件匹配结束后触发,参数是找到的文件的数组
  • error:会在匹配遇到错误的时候触发,参数是错误信息
  • abort:当实例调用了.abort()方法时触发

方法:

  • pause:暂停匹配搜索
  • resume:继续匹配搜索
  • abort:中止匹配搜索,不能继续
const g = new glob.Glob("src/@(ch*|ex*|li*).js", {nonull:true});

g.on('match', (file) => {
    console.log(file);      // 分三次打印出:src/chalk.js  src/execa.js  src/listr.js
});
g.on('end', (files) => {
    console.log(files);     // [ 'src/chalk.js', 'src/execa.js', 'src/listr.js' ]
});
g.on('error', (err) => {
    console.log(err);
});
g.on('abort', () => {
    console.log('abort');
});

g.pause();
g.resume();
g.abort();

属性:(懒,用到再补充说明,可耻地匿了~)

  • minimatch:glob所使用的minimatch对象
  • options:用于设置匹配方式,除了原本minimatch支持的配置项外,node-glob还添加了一些自己的配置项。所有配置项如果没有特殊说明,默认都是false。
    • cwd
    • root
    • dot:将 .点当作一个普通字符来处理,否则 .点开头的文件会被忽略
    • nomount
    • mark
    • nosort
    • stat
    • silent
    • strict
    • cache
    • statCache
    • symlinks
    • sync:设为true表示同步匹配
    • nounique
    • nonull:如果一个都没有匹配,将返回空数组。这和shell不同,shell中一个都没匹配,将返回表达式。如果想行为和shell一致,可以设为true
    • debug
    • nobrace
    • noglobstar:设为true,将不支持双星字符**
    • noext
    • nocase
    • matchBase:设为true,如果表达式中没有 /斜杠,那么它将在所有位置查找匹配basename的任何文件。例如*.js等价于**/*.js,将匹配目录中所有js文件
    • nodir:设为true,只匹配文件,不匹配文件夹
    • ignore:支持正则定义需要排除的文件,例如设为[‘**/src/**/*’]。前置条件是dot:true
    • follow
    • realpath
    • nonegate
    • nocomment
  • aborted:调用g.abort()方法后,该值就是true
  • cache
  • statCache
  • symlinks
  • realpathCache

glob-promise

因为现在习惯了写promise,所以用glob-promise,就是个promise版的glob。

const fse = require('fs-extra');
const glob = require("glob-promise");

const copyFiles = async(src, dest) => {
    // package.json 和 模板文件不拷贝,后续单独处理
    const files = await glob(`${src}/**/!(package.json|index.html)`, { nodir: true });

    files.forEach(async (file) => {
        const dir = path.relative(src, file);
        await fse.copy(file, path.join(dest, dir), { overwrite: true });
    });
};

globby

globby同样支持promise,还支持直接过滤掉.gitignore中定义的文件。据说更fast,反正脚手架也就这几个文件,也没兴趣做压测,你说更快就更快吧 ^_^

发表评论

电子邮件地址不会被公开。 必填项已用*标注