如何使用grunt使用r.js将AMD应用程序正确构建为单个文件?

时间:2015-11-26 18:21:11

标签: gruntjs requirejs r.js grunt-contrib-requirejs

执行编译文件时我一直看到这个错误:

未捕捉错误:没有json

这是我当前的requirejs grunt任务配置:

requirejs: {
    options: {
            baseUrl: "build/repos/staging/dev",
            mainConfigFile: "dev/main.js",

            generateSourceMaps: false,
            preserveLicenseComments: false,

            name: "almond",
            out: "./static/js/compiled.js",
            //excludeShallow: ['vendor'],
            findNestedDependencies: true,
            removeCombined: true,
            //wrap: true,
            optimize: "uglify2",
            uglify2: {
                output: {
                    beautify: true,
                },
                lint: true,
                mangle: false,
                compress: false,
                compress: {
                    sequences: false
                }
            }
        }
    }

这是我的dev / main.js文件:

// This is the runtime configuration file.
// It also complements the Gruntfile.js by supplementing shared properties.require.config({
waitSeconds: 180,
urlArgs: 'bust=' + (new Date()).getTime(),
paths: {

    "underscore": "../vendor/underscore/underscore",
    "backbone": "../vendor/backbone/backbone",
    "layoutmanager": "../vendor/layoutmanager/backbone.layoutmanager",
    "lodash": "../vendor/lodash/lodash",
    "ldsh": "../vendor/lodash-template-loader/loader",
    "text": "../vendor/requirejs-plugins/lib/text",
    "json": "../vendor/requirejs-plugins/json",
    "almond": "../vendor/almond/almond",

    // jquery
    "jquery": "../vendor/jquery/jquery",
    "jquery.transit": "../vendor/jquery.transit/jquery.transit",
    "jquery.mousewheel": "../vendor/jquery.mousewheel/jquery.mousewheel",
    "jquery.jscrollpane": "../vendor/jquery.jscrollpane/jquery.jscrollpane"
},

shim: {
    'backbone': {
        deps: ['underscore']
    },
    'layoutmanager': {
        deps: ['backbone', 'lodash', 'ldsh']
    },
    'jquery.transit': {
        deps: ['jquery']
    },
    'json': {
        deps: ['text']
    }
}});
// App initialization
require(["app"], function(instance) {
    "use strict";
    window.app = instance;
    app.load();
});

最后,我的dev / app.js文件:

define(function(require, exports, module) {

"use strict";

// External global dependencies.
var _ = require("underscore"),
    $ = require("jquery"),
    Transit = require('jquery.transit'),
    Backbone = require("backbone"),
    Layout = require("layoutmanager");

module.exports = {

    'layout': null,

    'load': function() {

        var paths = [

                // ***
                // *** 1- define its path
                // ***

                'json!config/main.json',
                'modules/nav',
                'modules/store',
                'modules/utils',
                'modules/preloader',
                'modules/popup',
                'modules/login',
                'modules/user',
                'modules/footer',
            ];

        try {
            require(paths, function(

                    // ***
                    // *** 2- call it a name
                    // ***

                    Config,
                    Nav,
                    Store,
                    Utils,
                    Preloader,
                    Popup,
                    Login,
                    User,
                    Footer
                ) {

                    // ***
                    // *** 3- instance it in the app
                    // ***

                    app.Config = Config;
                    app.Nav = Nav;
                    app.Store = Store;
                    app.Utils = Utils;
                    app.Preloader = Preloader;
                    app.Popup = Popup;
                    app.Login = Login;
                    app.User = User;
                    app.Footer = Footer;

                    // require and instance the router
                    require(['router'], function(Router) {

                        // app configuration
                        app.configure();

                        // app initialization
                        app.Router = new Router();
                    });
            });
        } catch (e) {
            console.error(e);
        }
    },


    'configure': function() {

        var that = this;

        // set environment
        this.Config.env = 'local';

        // Ajax global settings
        Backbone.$.ajaxSetup({
            'url': that.Config.envs[that.Config.env].core,
            'timeout': 90000,
            'beforeSend': function() {
            },
            'complete': function(xhr, textstatus) {
            }
        });

        // Template & layout
        _.templateSettings = {
            interpolate: /\{\{(.+?)\}\}/g
        };

        Layout.configure({
            // Allow LayoutManager to augment Backbone.View.prototype.
            manage: true,
            // Indicate where templates are stored.
            prefix: "app/templates/",
            // This custom fetch method will load pre-compiled templates or fetch them
            // remotely with AJAX.
            fetch: function(path) {
                // Concatenate the file extension.
                path = path + ".html";
                // If cached, use the compiled template.
                if (window.JST && window.JST[path]) {
                    return window.JST[path];
                }
                // Put fetch into `async-mode`.
                var done = this.async();
                // Seek out the template asynchronously.
                $.get('/' + path, function(contents) {
                    window.JST[path] = contents;
                    done(_.template(contents));
                }, "text");
            }
        });
    },

};
});

任何想法为什么在执行grunt requirejs时json模块不是“必需”?

提前致谢。

1 个答案:

答案 0 :(得分:0)

不确定这仍然是一个问题,但是来自requirejs优化器文档(http://requirejs.org/docs/optimization.html):

  

优化器只会组合在传递给顶级require和define调用的字符串文字数组中指定的模块,或者在简化的CommonJS包装中组合require(' name')字符串文字调用。因此,它不会找到通过变量名加载的模块......

听起来,requirejs优化器不喜欢使用变量依赖数组的变量进行require调用。

听起来好像requirejs优化器并不喜欢在优化的实际文件中使用require([ dependency array ], callback )的语法

您可能必须在 dev / app.js 中重构您的依赖声明以符合此规范。例如,您可以使用以下步骤1和2的重构:

var Config = require('json!config/main.json');
var Nav = require('modules/nav');
var Store = require('modules/store');
var Utils = require('modules/utils');
var Preloader = require('modules/preloader');
var Popup = require('modules/popup');
var Login = require('modules/login');
var User = require('modules/user');
var Footer = require('modules/footer');

如果这确实有效,看起来你也必须为路由器依赖声明做类似的事情。

此外,您可能希望在运行 后将其包含在您的requirejs配置 中的次要添加内容:

stubModules : ['json']

由于构建的文件中应包含JSON对象,因此您甚至不需要构建文件中的插件!因此,您可以通过从中删除json插件来减小文件大小。