RequireJS 2.1.9使用Grunt时会导致“最大调用堆栈..”错误

我正在使用Grunt构build一个多模块应用程序(Backbone,Marionette,RequireJS,Handlebars),但我一直得到“Error:RangeError:Maximum call stack size exceeded”消息。 如果我用2.1.5replacer.js 2.1.9文件,它可以工作。 我不知道哪里可以开始debugging。

注意:从节点运行相同的构buildconfiguration选项可以使用2.1.9

node r.js -o build.js 

它只是不喜欢从Grunt跑。

r.js 2.1.9

grunt-cli v0.1.11

grunt v0.4.2

这是我的Gruntfile.js

 module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), requirejs: { compile: { options: { appDir: "src/main/webapp", baseUrl: 'js/', dir: "target", mainConfigFile: 'src/main/webapp/js/require-config.js', //optimizeAllPluginResources : true, findNestedDependencies: true, //removeCombined : true, //optimize : 'none', //inlineText : true, modules: [{ name: "main", excludeShallow: ["config"], override: { paths: { "shipping-address": "empty:", "shipping-method": "empty:", "payment-method": "empty:", "place-order": "empty:", "order-confirmation": "empty:", "quote": "empty:" } } }, { name: 'shipping-address', exclude: ["main", "config"], override: { paths: { "shipping-method": "empty:" } } }, { name: 'shipping-method', exclude: ["main", "config", 'shipping-address'], override: { paths: { "payment-method": "empty:" } } }, { name: 'payment-method', exclude: ["main", "config", 'shipping-address', 'shipping-method'], override: { paths: { "place-order": "empty:" } } }, { name: 'place-order', exclude: ["main", "config", 'shipping-address', 'shipping-method', 'payment-method'], override: { paths: { "order-confirmation": "empty:" } } }, { name: 'order-confirmation', exclude: ["main", "config", 'shipping-address', 'shipping-method', 'payment-method', 'place-order'] }, { name: 'quote', exclude: ["main", "config"] }], //stubModules: ['hbs', 'checkout-controller'], preserveLicenseComments: false, pragmasOnSave: { //removes Handlebars.Parser code (used to compile template strings) set //it to `false` if you need to parse template strings even after build excludeHbsParser: true, // kills the entire plugin set once it's built. excludeHbs: true, // removes i18n precompiler, handlebars and json2 excludeAfterBuild: true } } } }, handlebars: { compile: { options: { namespace: "JST" }, files: [{ src: ['src/main/webapp/templates/**/*.html'], dest: 'dest/out.js' }] } }, concat: { options: {}, dist: { src: ["src/main/webapp/brands/arrow/parts/Header/js/bootstrap-tooltip.js", "src/main/webapp/brands/arrow/parts/Header/js/respond.src.js", 'src/main/webapp/brands/arrow/**/*.js'], dest: 'src/main/webapp/js/arrow.min.js' } }, uglify: { options: {}, 'dist': { src: ["src/main/webapp/brands/arrow/parts/Header/js/bootstrap-tooltip.js", "src/main/webapp/brands/arrow/parts/Header/js/respond.src.js", 'src/main/webapp/brands/arrow/**/*.js'], dest: 'src/main/webapp/js/arrow.min.js' } }, jshint: { files: ['src/main/webapp/js/**/*.js', '!src/main/webapp/js/**/libs/**'], options: { // Settings "passfail": false, // Stop on first error. "maxerr": 50, // Maximum error before stopping. // Predefined globals whom JSHint will ignore. "browser": true, // Standard browser globals eg `window`, `document`. "couch": false, "dojo": false, "jquery": true, "mootools": false, "node": false, "prototypejs": false, "rhino": false, "wsh": false, // Custom globals. "predef": ["define", "require"], // Development. "debug": false, // Allow debugger statements eg browser breakpoints. "devel": false, // Allow developments statements eg `console.log();`. // EcmaScript 5. "es5": false, // Allow EcmaScript 5 syntax. "globalstrict": false, // Allow global "use strict" (also enables 'strict'). "strict": false, // Require `use strict` pragma in every file. // The Good Parts. "asi": false, // Tolerate Automatic Semicolon Insertion (no semicolons). "bitwise": false, // Prohibit bitwise operators (&, |, ^, etc.). "boss": true, // Tolerate assignments inside if, for & while. Usually conditions & loops are for comparison, not assignments. "curly": false, // Require {} for every new block or scope. "eqeqeq": true, // Require triple equals ie `===`. "eqnull": true, // Tolerate use of `== null`. "evil": false, // Tolerate use of `eval`. "expr": false, // Tolerate `ExpressionStatement` as Programs. "forin": false, // Tolerate `for in` loops without `hasOwnPrototype`. "immed": true, // Require immediate invocations to be wrapped in parens eg `( function(){}() );` "latedef": false, // Prohibit variable use before definition. "laxbreak": false, // Tolerate unsafe line breaks eg `return [\n] x` without semicolons. "loopfunc": false, // Allow functions to be defined within loops. "noarg": true, // Prohibit use of `arguments.caller` and `arguments.callee`. "regexdash": true, // Tolerate unescaped last dash ie `[-...]`. "regexp": false, // Prohibit `.` and `[^...]` in regular expressions. "scripturl": false, // Tolerate script-targeted URLs. "shadow": false, // Allows re-define variables later in code eg `var x=1; x=2;`. "supernew": false, // Tolerate `new function () { ... };` and `new Object;`. "undef": false, // Require all non-global variables be declared before they are used. // Personal styling prefrences. "newcap": true, // Require capitalization of all constructor functions eg `new F()`. "noempty": true, // Prohipit use of empty blocks. "nomen": false, // Prohibit use of initial or trailing underbars in names. "nonew": true, // Prohibit use of constructors for side-effects. "onevar": false, // Allow only one `var` statement per function. "plusplus": false, // Prohibit use of `++` & `--`. "sub": false, // Tolerate all forms of subscript notation besides dot notation eg `dict['key']` instead of `dict.key`. "trailing": true, // Prohibit trailing whitespaces. "white": false // Check against strict whitespace and indentation rules. }, } }); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-requirejs'); grunt.loadNpmTasks('grunt-contrib-handlebars'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-closure-tools'); //grunt.loadNpmTasks('grunt-contrib-uglify'); //grunt.loadNpmTasks('grunt-contrib-qunit'); //grunt.loadNpmTasks('grunt-contrib-watch'); //grunt.loadNpmTasks('grunt-contrib-concat'); //grunt.registerTask('test', ['jshint', 'qunit']); grunt.registerTask('default', ['requirejs']); }; 

这是我的require-config.js

 define('require-config', ["console"], function() { var toAbsolutePath = function(url) { var loc = location.href; loc = loc.substring(0, loc.lastIndexOf('/')); while (/^\.\./.test(url)) { loc = loc.substring(0, loc.lastIndexOf('/')); url = url.substring(3); } return loc + '/' + url; }; var parseQueryString = function(query) { if (query.indexOf("?") == 0) { query = query.substr(1); } var a = query.split('&'); var b = {}; for (var i = 0; i < a.length; ++i) { var p = a[i].split('='); if (p.length != 2) continue; b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " ")); } return b; }; // Require.js allows us to configure shortcut alias require.config({ paths : { jquery : 'libs/jquery/jquery-require', underscore : 'libs/underscore/underscore', backbone : 'libs/backbone/backbone', "backbone.marionette" : 'libs/backbone/backbone.marionette', bootstrap : 'libs/bootstrap/bootstrap', alert : 'libs/bootstrap/bootstrap-alert', datePicker : 'libs/bootstrap/bootstrap-datepicker', paginator : 'libs/bootstrap/bootstrap-paginator', templates : '../templates', 'jquery.ui.widget' : 'libs/jqueryui/jquery.ui.widget', iframetransport : 'libs/jquery/plugins/jquery.iframe-transport-custom', viewstack : 'libs/jquery/plugins/jquery.jquery-viewstack', xdrtransport : "libs/cors/jquery.xdr-transport", dropdown : "libs/jquery/plugins/jquery.dropdown", scrollTo : "libs/jquery/plugins/jquery.scrollTo-1.4.3.1-min", fileupload : "libs/jquery/plugins/jquery.fileupload", i18n : "libs/jquery/plugins/i18n", modalPop : "libs/jquery/plugins/jquery.simplemodal-custom", payment : "libs/jquery/plugins/jquery.payment", printThis : "libs/jquery/plugins/jquery.printThis", placeholder : "libs/jquery/plugins/jquery.placeholder.1.3.min", highlight : "libs/jqueryui/jquery-ui-highlight.min", BaseClass : "base-class", apis : "apis", fixture : 'libs/jquery/plugins/jquery.fixture', UserModel : 'models/user-model', OrderModel : 'models/order-model', PendingSalesOrderModel : 'models/pending-sales-order-model', ShoppingCart : "collections/shopping-cart-collection", ShoppingCartItemModel : "models/shopping-cart-item-model", AddressItemModel : "models/address-item-model", catalogModel : "models/catalog-model", CreditLimitModel : "models/credit-limit-model", AddressCollection : "collections/address-collection", ShippingOptionCollection : "collections/shipping-option-collection", CountriesAndStatesCollection : "collections/countries-and-states-collection", OrderHistoryCollection : "collections/order-history-collection", "jquery.validate" : "libs/jquery/plugins/jquery.validate", "blockUI" : "libs/jquery/plugins/jquery.blockUI", handlebars : "libs/handlebars/handlebars", "handlebars.runtime" : "libs/handlebars/handlebars.runtime", hbs : "libs/handlebars/hbs", json2 : "libs/handlebars/json2", i18nprecompile : 'libs/handlebars/i18nprecompile', "backbone.marionette.handlebars" : "libs/handlebars/backbone.marionette.handlebars", "paypalHelper" : "paypal-helper", 'accounting' : "libs/accounting", vent : "vent", addressVent : "addressVent", "CartDialog" : "views/shoppingcart/shoppingcart-item-update-dialog", config : "config", tracker : "tracker", "checkout-controller" : "controllers/checkout-controller", "shoppingcart-controller" : "controllers/shoppingcart-controller", "partquote-controller" : "controllers/partquote-controller", "shipping-address" : "views/checkout/shipping-address", "shipping-method" : "views/checkout/shipping-method", "payment-method" : "views/checkout/payment-method", "place-order" : "views/checkout/place-order", "order-confirmation" : "views/checkout/order-confirmation", "quote" : "views/quote/quote", "ecliptek" : "views/quote/ecliptek-quote" }, shim : { underscore : { exports : '_' }, backbone : { deps : ["underscore", "jquery"], exports : "Backbone" }, "backbone.marionette" : { exports : 'Backbone.Marionette', deps : ['backbone'] }, "jquery.validate" : { deps : ['jquery'] }, "blockUI" : { deps : ['jquery'] }, 'libs/bootstrap/bootstrap-tab' : { deps : ['jquery'] }, "libs/bootstrap/bootstrap-dropdown" : { deps : ['jquery'] }, 'arrowjs' : { deps : ['jquery'] }, "libs/bootstrap/bootstrap-collapse" : { deps : ['jquery'] }, "libs/bootstrap/bootstrap-modal" : { deps : ['jquery'] }, 'libs/bootstrap/bootstrap-datepicker' : { deps : ['jquery'] }, 'libs/bootstrap/bootstrap-paginator' : { deps :['jquery'] }, 'libs/bootstrap/bootstrap-alert' : { deps : ['jquery'] }, hbs : { deps : ['handlebars', 'json2', 'i18nprecompile'] }, "backbone.marionette.handlebars" : { deps : ["backbone.marionette"] }, "colorAnimator" : { deps : ['jquery'] }, scrollTo : { deps : ['jquery'] }, dropdown : { deps : ['jquery'] } }, deps : ["template_helper", "blockUI", "jquery.validate", "backbone.marionette", 'handlebars', "backbone.marionette.handlebars"], // default plugin settings, listing here just as a reference hbs : { templateExtension : 'html', // if disableI18n is `true` it won't load locales and the i18n helper // won't work as well. disableI18n : true, disableHelpers : true } }); require.config({ paths : { config : window ? toAbsolutePath("js/config") : "config" } }); }) 

控制台输出

 Tracing dependencies for: main Tracing dependencies for: shipping-address Tracing dependencies for: shipping-method Tracing dependencies for: payment-method Tracing dependencies for: place-order Tracing dependencies for: order-confirmation Tracing dependencies for: quote Tracing dependencies for: config Tracing dependencies for: config Tracing dependencies for: config Tracing dependencies for: config Tracing dependencies for: config Tracing dependencies for: config { [Error: RangeError: Maximum call stack size exceeded] originalError: [RangeError: Maximum call stack size exceeded] } 

有没有什么原因希望启用findNestedDependencies: true, 如果您的require.config设置正确,实际上没有这种需要。

希望能帮助到你。