Npm grunt unused-循环目录中的子文件夹

Npm grunt unused-循环目录中的子文件夹,npm,gruntjs,Npm,Gruntjs,我正在尝试使用删除多个子目录中所有未使用的图像链接。为清晰起见,以下是我的文件夹结构: |-- dist | |-- site-1 | | |—-index.html | | |—-style.css | | |—-app.js | | |—-image1.jpg | | |—-image2.jpg | | |—-image3.jpg | | |—-image4.jpg | |-- site-2 | | |—-index.html | | |—-style

我正在尝试使用删除多个子目录中所有未使用的图像链接。为清晰起见,以下是我的文件夹结构:

|-- dist
|  |-- site-1
|  |  |—-index.html
|  |  |—-style.css
|  |  |—-app.js
|  |  |—-image1.jpg
|  |  |—-image2.jpg
|  |  |—-image3.jpg
|  |  |—-image4.jpg
|  |-- site-2
|  |  |—-index.html
|  |  |—-style.css
|  |  |—-app.js
|  |  |—-image1.jpg
|  |  |—-image2.jpg
|  |  |—-image3.jpg
|  |  |—-image4.jpg
|  |-- site-3
|  |  |—-index.html
|  |  |—-style.css
|  |  |—-app.js
|  |  |—-image1.jpg
|  |  |—-image2.jpg
|  |  |—-image3.jpg
|  |  |—-image4.jpg
我编写了一个“forEach”函数,以这些子文件夹为目标,然后引用每个文件夹,类似于,但它不适用于未使用的任务。它不会在每个目录中循环,控制台也不会在很短的时间内检测到任何未使用的文件,就像它实际上没有做任何事情一样

我哪里做错了

grunt.registerTask('prodOutput', function () {

    // read all subdirectories of dist/ folder, excluding the assets folder
    grunt.file.expand('dist/*', '!dist/assets/**').forEach(function (dir) {

        //get the current unused config
        var unusedConfig = grunt.config.get('unused') || {};

        //set options for grunt-unused, including the folder variable 'dir' as the reference of where to look
        unusedConfig[dir] = {
            option: {
                reference: dir + '/',
                directory: ['**/*.css', '**/*.html', '**/*.js'],
                remove: false, // set to true to delete unused files from project
                reportOutput: 'report.txt', // set to false to disable file output
                fail: false // set to true to make the task fail when unused files are found
            }
        };

        grunt.config.set('unused', unusedConfig);

    });

    grunt.task.run('unused');

});
问题 正如我之前在评论中提到的。。。主要问题是,在运行任务之前,您正在
forEach
函数中动态配置多个,但是不支持多个目标配置

另外,
grunt unused
希望包含指向其他文件的引用/链接的文件(即
index.html
)与它引用的文件(例如图像、css等)位于不同的目录/文件夹中,但是您的帖子中提供的文件夹结构是扁平的


解决方案 在快速查看其他grunt插件之后,似乎没有一个能够满足您的需求。我认为实现这一点的唯一方法是编写自己的自定义任务/插件来处理这个问题

要实现这一点,您可以执行以下操作:

创建一个单独的Javascript模块,导出一个。将文件命名为
delete unused.js
,并将其保存到名为
tasks
的目录中,该目录与
grunfile.js
位于同一顶级目录中

目录结构

您的目录结构应该如下所示:

.
├── dist
│   ├── site-1
│   ├── site-2
│   ├── ...
│   └── assets
│
├── Gruntfile.js
│
├── node_modules
│   └── ...
│
├── package.json
│
└── tasks
    └── delete-unused.js
删除未使用的.js

module.exports=函数(grunt){
"严格使用",;
//要求
var fs=需要('fs');
var path=require('path');
registerMultiTask('unused','Delete unused assets',function(){
//默认选项。这些选项在没有选项时使用
//通过initConfig({…})parse任务提供。
var options=this.options({
reportOutput:false,
删除:false
});
var reportTxt='';
//在通过configs src数组提供的每个src目录路径上循环。
this.data.src.forEach(函数(dir){
//如果找不到提供的目录src路径,则记录日志。
如果(!grunt.file.isDir(dir)){
grunt.fail.warn('未找到目录:'.yellow+dir.yellow);
}
//如果提供了目录路径,请附加正斜杠
//在src中,数组不以一结尾。
如果(直接切片(-1)!='/')){
dir+='/';
}
//生成globbin模式(只有一层深!)。
变量glob=[dir,'*'].join('');
//创建所有顶级文件夹的数组(例如站点-*)
//在dist目录中,并排除assets目录。
var dirs=grunt.file.expand(glob.map)(函数(dir){
返回目录;
});
//在每个目录上循环。
dirs.forEach(函数(dir){
//在此处添加要排除的文件夹。
if(dir=='./dist/assets'){
返回;
}
//日志状态和更新报告
grunt.log.write('\n处理文件夹'+dir);
reportTxt+='\n处理文件夹'+dir;
//要用未使用的资产引用填充的空数组。
var未使用=[];
//定义index.html的路径
var pathToHtml=[dir,'/','index.html'].join('');
//创建文件名和文件路径数组(排除index.html)
var assets=grunt.file.expand([dir+'/****.','!index.html'])
.map(函数(文件){
返回{
fpath:file,
fname:path.basename(文件)
};
});
//日志/报告缺少“index.html”并提前返回。
如果(!grunt.file.exists(pathToHtml)){
grunt.log.write('\n>>在'+dir+'/\n'中找不到index.html');
reportTxt+='\n>>在'+dir+'/\n'中找不到index.html;
返回;
}
//阅读index.html的内容。
var html=fs.readFileSync(pathToHtml{
编码:“utf8”
});
//在每个文件资源上循环以查找是否在index.html中链接
资产。forEach(功能(资产){
//对RegExp对象的文件名中的点[.]进行反斜杠转义。
var escapedFilename=asset.fname.replace('.','\\.');
//动态创建RegExp对象以搜索实例
//index.html内容中的资产文件名。
//这将确保引用是实际链接的资产,并且
//不是文档中其他地方的纯文本。
//
//有关此正则表达式的说明,请访问:
// https://regex101.com/r/XZpldm/4/
var regex=new RegExp((?:href=| src=| url\\()(?:[\”,'])(.*
+转义文件名+”[\”,“,\)]+?”,“g”);
//使用正则表达式搜索index.html
if(html.search(regex)==-1&&asset.fname!=='index.html'){

未使用。推送(资产);//主要问题是,在运行任务之前,您在
forEach
函数中动态配置多个,但是
grunt unused
不支持多个目标配置。为了帮助更好地理解您的需求:…名为
site-1
site-2
等的文件夹是否可能包括未使用的as集合(即
site-1
文件夹中的资产不能在
index.html
中链接/引用,也可以存储在同一文件夹中)?在这种情况下,如果它们没有在
index.html
中链接,您想删除实际文件吗?嗨,Rob,谢谢您的发布。是的,site-1、site-2等中可能有未使用的图像,并且不会以任何方式链接。在此之前,我正在运行另一个任务,该任务正在包含所有图像的master'/image'文件夹的内容中运行或者所有站点(站点1、站点2等)是否还有其他站点