使用Grunt将多个目录中的多个文件合并成单个重命名文件并放置在新目录中

19

我有一个Angular项目,其中可能有许多模块。每个模块都有自己的目录,包括控制器、指令、服务等子目录。就像这样:

src
|-- js
    |-- modules
        |-- moduleOne
            | module.js
            |-- controllers
                | listController.js
                | detailController.js
            |-- directives
                | listItem.js
                | summaryWidget.js
            |-- filters
            |-- services
                | moduleService.js

我的构建本质上是将src/中的文件捆绑和编译,然后放到dev/中,然后将dev/中的文件进行最小化处理,并移动到prod/中。在开发过程中,服务器指向dev/文件夹,在生产中,服务器指向prod/文件夹(这也是为什么文件以.min.js结尾,即使它们只是被编译/连接而已)。这个过程很顺利。

目前,我的连接任务正在获取moduleOne/中的所有文件,并在我的dev目录中创建一个单独的moduleOne.js文件。这正是我想要发生的事情,但需要更加动态化:

concat: {
    modules: {
        files: {
            "dev/js/modules/moduleOne.min.js": [
                "src/js/modules/moduleOne/*.js",
                "src/js/modules/moduleOne/**/*.js"
            ],
            "dev/js/modules/moduleTwo.min.js": [
                "src/js/modules/moduleTwo/*.js",
                "src/js/modules/moduleTwo/**/*.js"
            ]
        } 
    }
}
问题在于我必须为每个模块都这样做,但我认为我并不需要这样做。
我尝试了以下操作,因为这与我想要做的有些相似。
concat: {
    modules: {
        files: [{
            expand: true,
            cwd: "src/js/modules",
            src: "**/*.js",
            dest: "dev/js/modules",
            ext: ".min.js"
        }]
    }
}

但结果是我的所有文件和目录结构都从 src/ 移动到了 dev/。我基本上使用 concat 来进行复制,这并没有帮助。

我想做类似这样的事情:

concat: {
    modules: {
        files: [{
            expand: true,
            cwd: "src/js/modules",
            src: "**/*.js",
            dest: "dev/js/modules/<foldername>.min.js",  <- how do I achieve this?
        }]
    }
}

我一直在阅读,但似乎只接近找到答案,却难以将概念整合起来。我发现的大部分只是将单个文件移到新目录并重命名。我想将多个文件合并成一个文件并移至新目录并重命名,因为这就是我的风格 :)

1个回答

24

所以,我找到了我正在寻找的答案。

这篇Stack Overflow帖子基本上是同样的问题,并且回答得非常好。不幸的是,在我创建问题时它没有出现,否则你就不会看到这个问题了。

对我的需求进行了一些微小的调整。我需要根据每个模块进行动态映射,而不仅仅是一个 compile.js 文件,因此我的最终代码如下,放置在 initConfig() 之后:

grunt.registerTask("prepareModules", "Finds and prepares modules for concatenation.", function() {

    // get all module directories
    grunt.file.expand("src/js/modules/*").forEach(function (dir) {

        // get the module name from the directory name
        var dirName = dir.substr(dir.lastIndexOf('/')+1);

        // get the current concat object from initConfig
        var concat = grunt.config.get('concat') || {};

        // create a subtask for each module, find all src files
        // and combine into a single js file per module
        concat[dirName] = {
            src: [dir + '/**/*.js'],
            dest: 'dev/js/modules/' + dirName + '.min.js'
        };

        // add module subtasks to the concat task in initConfig
        grunt.config.set('concat', concat);
    });
});

// the default task
grunt.registerTask("default", ["sass", "ngtemplates", "prepareModules", "concat", "uglify", "cssmin"]);

这实质上使我的连接(concat)任务看起来像我手动编码时一样,只是更简单(且可扩展!)。

concat: {
    ...
    moduleOne: {
        src: "src/js/modules/moduleOne/**/*.js",            
        dest: "dev/js/modules/moduleOne.min.js"
    },
    moduleTwo:{
        src: "src/js/modules/moduleTwo/**/*.js",
        dest: "dev/js/modules/moduleTwo.min.js"
    }
}

我在 SO 的帖子中偏离了一点,我选择不让 prepareModules 在完成后独立运行 concat。我的默认任务(由 watch 在开发期间设置)仍然处理所有内容。

这使得我的结构保持如下,可以被压缩为生产环境所用:

| dev
    | js
        | modules
            |-- moduleOne.min.js
            |-- moduleTwo.min.js

是否可以排除子文件夹? - pcnate
很可能,我敢打赌你可以想出来的。当我使用grunt时,我并不需要它,自从发表这篇文章后,我一直在使用gulp。 - coblr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接