globbing - 正确匹配某些文件扩展名但不匹配其他文件的方法

时间:2016-07-28 22:00:48

标签: javascript node.js gruntjs glob node-glob

我在下面编写了代码片段作为grunt-aws-s3任务的一部分。

var weekCache = 'css|js';
var yearCache = 'jpg|jpeg|png|gif|ico|eot|otf|ttf|woff|woff2';
var prodFiles = [
    {expand: true, cwd: 'public', src: ['**/*.!('+weekCache+'|'+yearCache+')'], dest: '/'},
    {expand: true, cwd: 'public', src: ['**/*.@('+weekCache+')'], dest: '/', stream: true, params: {CacheControl: 'max-age=604800, public'}}, // enable stream to allow large files
    {expand: true, cwd: 'public', src: ['**/*.@('+yearCache+')'], dest: '/', stream: true, params: {CacheControl: 'max-age=31536000, public'}},
];

我们的想法是在prodFiles变量中包含三个不同的匹配项:

  1. 匹配除yearCacheweekCache
  2. 匹配的文件以外的所有文件
  3. 将所有文件与weekCache
  4. 中包含的扩展名匹配
  5. 将所有文件与yearCache
  6. 中包含的扩展名匹配

    它或多或少有效,我在public目录及其子目录中有63个文件。但是这些规则匹配72个文件,很明显一些文件至少匹配两次。

    我的全球运动有什么问题?

    修改

    使用node-glob-all进行测试显示错误属于第一种模式:

    $ glob-all '**/*.!(css|js)'
    assets/css/style-nuvue6sithwirecbhvw3dkaobiojqvtadsnhguwi7k04xklybw5djl1smadp.min.css
    assets/images/favicon.ico
    assets/js/jquery.fancybox.js
    assets/js/jquery.fancybox-thumbs.js
    

    我希望此模式可以返回所有内容,但不包括*.js*.css。针对其他两个规则进行测试会返回正确的文件。

    $ glob-all '**/*.@(css|js)'
    assets/css/style-nuvue6sithwirecbhvw3dkaobiojqvtadsnhguwi7k04xklybw5djl1smadp.min.css
    assets/js/jquery.fancybox.js
    assets/js/jquery.fancybox-thumbs.js
    

    那么,问题是如何正确否定模式'**/*.!(css|js)'

1 个答案:

答案 0 :(得分:2)

我相信你的问题是你的文件名包含多个点(。)。

您的模式指定查找所有文件名,这些文件名包含一些非点字符后跟一个点字符,后跟除“css”或“js”以外的任何字符。

让我们以文件名“jquery.fancybox.js”为例。使用此文件名,我们发现有一些非点字符,“jquery”,后跟一个点“。”,后跟不是“css”的字符而不是“js”,“ fancybox.js”。此文件名与模式匹配,因此返回。

如果上面的文件名是“fancybox.js”,它会匹配一些非点字符,“fancybox”,后跟一个点“。”,但不是后跟字符这不是“css”而不是“js”。因此,此文件名将无法模式匹配,并且不会返回。

我们想要做的是在我们的否定模式中指定在我们的“.css”或“.js”扩展名之前可能有更多的非点字符。我们可以使用以下模式执行此操作:

'**/*.!(*(*.)js|*(*.)css)'