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 结尾的原因,即使它们只是被编译/合并)。这个过程运行良好。

目前,我的 concat 任务是获取 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来做copy的,没什么用。

我想做这样的事情:

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

我已经阅读了很多,但似乎我只能找到答案并且无法将这些概念放在一起。我发现很多只是将单个文件放入新目录中,并重命名。我希望多个文件将单个文件重新命名到新目录中。因为这就是我滚动的方式:)

4

1 回答 1

24

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

这篇 SO 帖子基本上是同一个问题,答案很好。不幸的是,当我创建我的问题时它没有出现,否则你就不会阅读这个。

我的需求略有调整。我需要为每个模块而不是一个 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。我的默认任务(手表设置为在开发期间运行)仍然完成我的所有处理。

这给我留下了以下结构,准备好缩小为 prod/:

| dev
    | js
        | modules
            |-- moduleOne.min.js
            |-- moduleTwo.min.js
于 2014-02-20T22:35:45.853 回答