多应用程序项目的Grunt和requirejs优化器

Gre*_*ale 9 javascript optimization task requirejs gruntjs

我在让Grunt对具有以下结构的项目执行requirejs优化时遇到问题:

static/js
    |?? apps
        |?? app.js
        |?? dash.js
        |?? news.js
        ... (many more 'app' files)
    |?? build
    |?? collections
    |?? libs
    |?? models
    |?? util
    |?? views
Run Code Online (Sandbox Code Playgroud)

每个static/js/apps/*.js都应编译为static/js/build/*.js包含相关的依赖项(例如views/view1,libs/query等).

目前这是由一个基本的bash脚本执行的:

JS_ROOT="static/js"

for f in ${JS_ROOT}/apps/*
do
    FILE=$(basename -s .js ${f})
    pushd .
    cd ${JS_ROOT} && r.js -o baseUrl=. name=libs/require-min.js include=apps/${FILE} out=build/${FILE}.js
    popd
done
Run Code Online (Sandbox Code Playgroud)

我正在尝试转向基于Grunt的优化,其中包含以下内容Grunt.js:

requirejs: {
    compile: {
        options: {
            appDir: 'static/js/',
            baseUrl: './apps/',
            dir: 'static/js/build/',
            modules: [
                {
                    name: 'app',
                }
            ]
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

运行会生成以下错误:

>> Tracing dependencies for: app
>> Error: ENOENT, no such file or directory
>> 'static/js/build/apps/libs/jquery.js'
>> In module tree:
>>     app
Run Code Online (Sandbox Code Playgroud)

我可以清楚地看到问题是什么,但我没有弄清楚如何指出每个static/js/apps/*.js文件中的依赖关系static/js/不是static/js/build

除此之外,我假设modules包含的块name: 'app'应该static/js/build/app.js从内容输出编译文件static/js/apps/app.js.

如果不module为每个文件创建一个附加块static/js/apps,如何将每个文件编译到相关static/js/build/*.js文件中?

更新1

所以我的Gruntfile中的以下内容static/js/apps/app.js成功编译成static/js/build/app.js:

requirejs: {
    compile: {
        options: {
            baseUrl: 'static/js/',
            include: './apps/app.js',
            out: 'static/js/build/app.js',
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

下一步骤是编译static/js/apps/*.jsstatic/js/build/*.js,而不必单独定义每个...

更新2

修改以上内容:

requirejs: {
    compile: {
        options: {
            baseUrl: '../',
            include: './apps/<%= appFile %>',
            out: 'static/js/build/<%= appFile %>',
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

并创建任务:

grunt.registerTask('buildrjs', function() {
    var dir='static/js/apps/';
    grunt.file.setBase(dir);
    var files = grunt.file.expand(['*.js']);
    files.forEach(function(filename) {
        grunt.log.write('Compiling '+filename+'\n');
        grunt.config.set('appFile', filename);
        grunt.task.run('requirejs:compile');
    });
});
Run Code Online (Sandbox Code Playgroud)

差点让我找到解决方案.任务遍历每个文件static/js/apps/并将文件名传递到grunt.config.set('appFile', filename);.任务输出Compiling app.js Compiling news.js...等输出,然后实际requirejs:compile任务在static/js/apps/目录中的最后一个文件而不是每个单独的文件上反复运行.一个异步问题?

Gre*_*ale 11

解决了,通过将多组选项传递给requirejs任务,感谢本文提供了我需要的最终指针:

module.exports = function(grunt) {
    var files = grunt.file.expand('static/js/apps/*.js');
    var requirejsOptions = {};

    files.forEach(function(file) {
        var filename = file.split('/').pop();
        requirejsOptions[filename] = {
            options: {
                baseUrl: 'static/js/',
                include: './apps/'+filename,
                out: 'static/js/build/'+filename
            }
        };
    });

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        requirejs: requirejsOptions,
    });
};
Run Code Online (Sandbox Code Playgroud)

然后,该['requirejs']任务可以正常运行,并将根据options: {}指定的每个块输出相应的已编译.js文件requirejsOptions,例如:

grunt.registerTask('default', ['requirejs']);