glob

FIS3 中支持的 glob 规则,FIS3 使用 node-glob 提供 glob 支持。

简要说明

node-glob 中的使用方式有很多,如果要了解全部,请前往 node-glob

这里把常用的一些用法做说明。

  • * 匹配0或多个除了 / 以外的字符
  • ? 匹配单个除了 / 以外的字符
  • ** 匹配多个字符包括 /
  • {} 可以让多个规则用 , 逗号分隔,起到或者的作用
  • ! 出现在规则的开头,表示取反。即匹配不命中后面规则的文件

需要注意的是,fis 中的文件路径都是以 / 开头的,所以编写规则时,请尽量严格的以 / 开头。

当设置规则时,没有严格的以 / 开头,比如 a.js, 它匹配的是所有目录下面的 a.js, 包括:/a.js/a/a.js/a/b/a.js。 如果要严格只命中根目录下面的 /a.js, 请使用 fis.match('/a.js')

另外 /foo/*.js, 只会命中 /foo 目录下面的所有 js 文件,不包含子目录。
/foo/**/*.js 是命中所有子目录以及其子目录下面的所有 js 文件,不包含当前目录下面的 js 文件。
如果需要命中 foo 目录下面以及所有其子目录下面的 js 文件,请使用 /foo/**.js

扩展的规则

  1. 假设匹配 widget 目录下以及其子目录下的所有 js 文件,使用 node-glob 需要这么写

    1. widget/{*.js,**/*.js}

    这样写起来比较麻烦,所以扩展了这块的语法,以下方式等价于上面的用法

    1. widget/**.js
  2. node-glob 中没有捕获分组,而 fis 中经常用到分组信息,如下面这种正则用法:

    1. // 让 a 目录下面的 js 发布到 b 目录下面,保留原始文件名。
    2. fis.match(/^\/a\/(.*\.js$)/i, {
    3. release: '/b/$1'
    4. });

    由于原始 node-glob 不支持捕获分组,所以做了对括号用法的扩展,如下用法和正则用法等价。

    1. // 让 a 目录下面的 js 发布到 b 目录下面,保留原始文件名。
    2. fis.match('/a/(**.js)', {
    3. release: '/b/$1'
    4. });

    捕获分组

    使用 node-glob 捕获的分组,可以用于其他属性的设定,如 release, url, id 等。使用的方式与正则替换类似,我们可以用 $1, $2, $3 来代表相应的捕获分组。其中 $0 代表的是 match 到的整个字符串。

    1. fis.match('/a/(**.js)', {
    2. release: '/b/$1' // $1 代表 (**.js) 匹配的内容
    3. });
    1. fis.match('/a/(**.js)', {
    2. release: '/b/$0' // $0 代表 /a/(**.js) 匹配的内容
    3. });

    特殊用法(类 css 伪类)

    1. ::package 用来匹配 fis 的打包过程。
    2. ::text 用来匹配文本文件。

      默认识别这类后缀的文件。

      1. [
      2. 'css', 'tpl', 'js', 'php',
      3. 'txt', 'json', 'xml', 'htm',
      4. 'text', 'xhtml', 'html', 'md',
      5. 'conf', 'po', 'config', 'tmpl',
      6. 'coffee', 'less', 'sass', 'jsp',
      7. 'scss', 'manifest', 'bak', 'asp',
      8. 'tmp', 'haml', 'jade', 'aspx',
      9. 'ashx', 'java', 'py', 'c', 'cpp',
      10. 'h', 'cshtml', 'asax', 'master',
      11. 'ascx', 'cs', 'ftl', 'vm', 'ejs',
      12. 'styl', 'jsx', 'handlebars'
      13. ]

      如果你希望命中的文件类型不在列表中,请通过 fis.set('project.fileType.text') 扩展,多个后缀用 , 分割。

      1. fis.set('project.fileType.text', 'cpp,hhp');
    3. ::image 用来匹配文件类型为图片的文件。

      默认识别这类后缀的文件。

      1. [
      2. 'svg', 'tif', 'tiff', 'wbmp',
      3. 'png', 'bmp', 'fax', 'gif',
      4. 'ico', 'jfif', 'jpe', 'jpeg',
      5. 'jpg', 'woff', 'cur', 'webp',
      6. 'swf', 'ttf', 'eot', 'woff2'
      7. ]

      如果你希望命中的文件类型不在列表中,请通过 fis.set('project.fileType.image') 扩展,多个后缀用 , 分割。

      1. fis.set('project.fileType.image', 'raw,bpg');
    4. *.html:js 用来匹配命中的 html 文件中的内嵌的 js 部分。

      fis3 htmlLike 的文件内嵌的 js 内容也会走单文件编译流程,默认只做标准化处理,如果想压缩,可以进行如下配置。

      1. fis.match('*.html:js', {
      2. optimizer: fis.plugin('uglify-js')
      3. });
    5. *.html:css 用来匹配命中的 html 文件中内嵌的 css 部分。

      fis3 htmlLike 的文件内嵌的 css 内容也会走单文件编译流程,默认只做标准化处理,如果想压缩,可以进行如下配置。

      1. fis.match('*.html:css', {
      2. optimizer: fis.plugin('clean-css')
      3. });
    6. *.html:inline-style 用来匹配命中的 html 文件中的内联样式。可以配置些 auto prefix 之类的插件。

    7. *.html:scss 用来命中 html 文件中的 scss 部分,具体请参考 fis3-demo 中的 use-xlang

注意事项

fis3 小于 3.3.4 的版本需要注意, 3.3.4 以上的版本已修复此问题。

node-glob 扩展分组功能确实还存在缺陷。分组 () 与 或{} 搭配使用时存在问题。

比如: /a/({b,c}/**.js) 会拆分成并列的两个规则 /a/(b/**.js)/a/(c/**.js),当这两个合成一个正则的时候,这个时候问题来了,
一个分组变成了两个分组,分组 1 为 (b/**.js) 分组 2 为 (c/**.js)。那么当希望获取捕获信息时,不能按原来的分组序号去获取了。

  1. // 错误
  2. fis.match('/a/({b,c}/**.js)', {
  3. release: '/static/$1'
  4. });
  5. // 正确
  6. fis.match('/a/({b,c}/**.js)', {
  7. release: '/static/$1$2'
  8. });