【问题标题】:Grunt & requirejs optimizer for a multi app project多应用项目的 Grunt 和 requirejs 优化器
【发布时间】:2014-01-02 05:50:49
【问题描述】:

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

static/js
    |── apps
        |── app.js
        |── dash.js
        |── news.js
        ... (many more 'app' files)
    |── build
    |── collections
    |── libs
    |── models
    |── util
    |── views

每个static/js/apps/*.js 都应编译为包含相关依赖项的static/js/build/*.js(例如views/view1libs/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

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

requirejs: {
    compile: {
        options: {
            appDir: 'static/js/',
            baseUrl: './apps/',
            dir: 'static/js/build/',
            modules: [
                {
                    name: 'app',
                }
            ]
        }
    }
}

运行产生如下错误:

>> Tracing dependencies for: app
>> Error: ENOENT, no such file or directory
>> 'static/js/build/apps/libs/jquery.js'
>> In module tree:
>>     app

我可以清楚地看到问题出在哪里,但我无法弄清楚如何指出每个 static/js/apps/*.js 文件中的依赖关系在 static/js/ 而不是 static/js/build

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

如果不为static/js/apps 中的每个文件创建额外的module 块,我如何将每个文件编译成相关的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',
        }
    }
}

下一步是将static/js/apps/*.js 编译成static/js/build/*.js,而无需单独定义...

更新 2

将上面的修改为:

requirejs: {
    compile: {
        options: {
            baseUrl: '../',
            include: './apps/<%= appFile %>',
            out: 'static/js/build/<%= appFile %>',
        }
    }
}

并创建任务:

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');
    });
});

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

【问题讨论】:

    标签: javascript optimization requirejs task gruntjs


    【解决方案1】:

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

    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,
        });
    };
    

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

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

    【讨论】:

      【解决方案2】:

      您需要在 requirejs 构建配置中将 baseUrl 从 apps 更改为 static/js。由于当前 baseUrl 指向 apps 目录,因此 require 正在尝试在 apps 目录中搜索依赖文件。如果将 baseUrl 更改为 static/js,它将找到那些依赖文件。

         requirejs: {
           compile: {
             options: {
               appDir: 'static/js/',
               baseUrl: 'static/js',
               dir: 'static/js/build/',
               modules: [
                {
                      name: 'app',
                }
               ]
             }
           }
         }
      

      【讨论】:

      • 但是baseUrl 是相对于appDir 的,所以在加载app 模块时,requirejs 将在/static/js/static/js/app.js 中查找。
      • 对不起,我错过了这一点。然后你可以将 BaseUrl 更改为 . baseUrl: "."
      • 谢谢。但是,在这种情况下,module 需要更新为 name: 'apps/app'。这导致static/js 的全部内容被复制到static/js/build
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-04
      • 1970-01-01
      相关资源
      最近更新 更多