I am trying to use r.js to optimize my code but I keep running to this error:
Tracing dependencies for: init
Error: Load timeout for modules: backbone,jquerymobile
The command I am running is this:
$ java -classpath /Users/dixond/build-tools/rhino1_7R4/js.jar:/Users/dixond/build-tools/closurecompiler/compiler.jar org.mozilla.javascript.tools.shell.Main /Users/dixond/build-tools/r.js/dist/r.js -o /Users/dixond/Sites/omm_mobile/js/build.js
My build.js file looks like this:
( {
//appDir: "some/path/",
baseUrl : ".",
mainConfigFile : 'init.js',
paths : {
jquery : 'libs/jquery-1.8.3.min',
backbone : 'libs/backbone.0.9.9',
underscore : 'libs/underscore-1.4.3',
json2 : 'libs/json2',
jquerymobile : 'libs/jquery.mobile-1.2.0.min'
},
packages : [],
shim : {
jquery : {
exports : 'jQuery'
},
jquerymobile : {
deps : ['jquery'],
exports : 'jQuery.mobile'
},
underscore : {
exports : '_'
},
backbone : {
deps : ['jquerymobile', 'jquery', 'underscore'],
exports : 'Backbone'
}
},
keepBuildDir : true,
locale : "en-us",
optimize : "closure",
skipDirOptimize : false,
generateSourceMaps : false,
normalizeDirDefines : "skip",
uglify : {
toplevel : true,
ascii_only : true,
beautify : true,
max_line_length : 1000,
defines : {
DEBUG : ['name', 'false']
},
no_mangle : true
},
uglify2 : {},
closure : {
CompilerOptions : {},
CompilationLevel : 'SIMPLE_OPTIMIZATIONS',
loggingLevel : 'WARNING'
},
cssImportIgnore : null,
inlineText : true,
useStrict : false,
pragmas : {
fooExclude : true
},
pragmasOnSave : {
//Just an example
excludeCoffeeScript : true
},
has : {
'function-bind' : true,
'string-trim' : false
},
hasOnSave : {
'function-bind' : true,
'string-trim' : false
},
//namespace: 'foo',
skipPragmas : false,
skipModuleInsertion : false,
optimizeAllPluginResources : false,
findNestedDependencies : false,
removeCombined : false,
name : "init",
out : "main-built.js",
wrap : {
start : "(function() {",
end : "}());"
},
preserveLicenseComments : true,
logLevel : 0,
cjsTranslate : true,
useSourceUrl : true
})
And my init.js looks like this:
requirejs.config({
//libraries
paths: {
jquery: 'libs/jquery-1.8.3.min',
backbone: 'libs/backbone.0.9.9',
underscore: 'libs/underscore-1.4.3',
json2 : 'libs/json2',
jquerymobile: 'libs/jquery.mobile-1.2.0.min'
},
//shimming enables loading non-AMD modules
//define dependencies and an export object
shim: {
jquerymobile: {
deps: ['jquery'],
exports: 'jQuery.mobile'
},
underscore: {
exports: '_'
},
backbone: {
deps: ['jquerymobile', 'jquery', 'underscore', 'json2'],
exports: 'Backbone'
}
}
});
requirejs(["backbone",], function(Backbone) {
//Execute code here
});
What am I doing wrong in this build process?
Require.js has a Config option called waitSeconds. This may help.
RequireJS waitSeconds
Here's an example where waitSeconds is used:
requirejs.config({
baseUrl: "scripts",
enforceDefine: true,
urlArgs: "bust=" + (new Date()).getTime(),
waitSeconds: 200,
paths: {
"jquery": "libs/jquery-1.8.3",
"underscore": "libs/underscore",
"backbone": "libs/backbone"
},
shim: {
"underscore": {
deps: [],
exports: "_"
},
"backbone": {
deps: ["jquery", "underscore"],
exports: "Backbone"
},
}
});
define(["jquery", "underscore", "backbone"],
function ($, _, Backbone) {
console.log("Test output");
console.log("$: " + typeof $);
console.log("_: " + typeof _);
console.log("Backbone: " + typeof Backbone);
}
);
The Error
I recently had a very similar issue with an angularJS project using requireJS.
I'm using Chrome canary build (Version 34.0.1801.0 canary) but also had a stable version installed (Version 32.0.1700.77) showing the exact same issue when loading the app with Developer console open:
Uncaught Error: Load timeout for modules
The developer console is key here since I didn't get the error when the console wasn't open. I tried resetting all chrome settings, uninstalling any plugin, ... nothing helped so far.
The Solution
The big pointer was a Google group discussion (see resources below) about the waitSeconds config option. Setting that to 0 solved my issue. I wouldn't check this in since this just sets the timeout to infinite. But as a fix during development this is just fine. Example config:
<script src="scripts/require.js"></script>
<script>
require.config({
baseUrl: "/another/path",
paths: {
"some": "some/v1.0"
},
waitSeconds: 0
});
require( ["some/module", "my/module", "a.js", "b.js"],
function(someModule, myModule) {
//This function will be called when all the dependencies
//listed above are loaded. Note that this function could
//be called before the page is loaded.
//This callback is optional.
}
);
</script>
Most common other causes for this error are:
errors in modules
wrong paths in configuration (check paths and baseUrl option)
double entry in config
More Resources
Troubleshooting page from requireJS: http://requirejs.org/docs/errors.html#timeout point 2, 3 and 4 can be of interest.
Similar SO question: Ripple - Uncaught Error: Load timeout for modules: app http://requirejs.org/docs/errors.html#timeout
A related Google groups discussion: https://groups.google.com/forum/#!topic/requirejs/70HQXxNylYg
In case others have this issue and still struggling with it (like I was), this problem can also arise from circular dependencies, e.g. A depends on B, and B depends on A.
The RequireJS docs don't mention that circular dependencies can cause the "Load timeout" error, but I've now observed it for two different circular dependencies.
Default value for waitSeconds = 7 (7 seconds)
If set to 0, timeout is completely disabled.
src: http://requirejs.org/docs/api.html
The reason for the issue is that Require.js runs into the timeout since the project might have dependencies to large libraries. The default timeout is 7 seconds. Increasing the value for this config option (called waitSeconds) solves it of course but it is not the right approach.
Correct approach would be to improve the page loading time. One of the best technics to speed up a page loading is minification - the process of compressing the code. There are some good tools for minification like r.js or webpack.
I only get this error when running tests on Mobile Safari 6.0.0 (iOS 6.1.4). waitSeconds: 0 has given me a successful build for now. I'll update if my build fails on this again
TLDR:
Requiring the same file twice with two valid different names, possibly two of the following:
absolute path: '/path/to/file.js'
relative path: './path/to/file.js'
as a module: 'path/to/file'
as a module on main paths config:
paths: {
'my/module/file' : '/path/to/file'
}
Recently had this same issue. I did change some require paths in bulk so I knew the issue was about that.
I could clearly see on both server side logs and network debugging tab the file being served in less than a second. It was not a real timeout issue.
I tried to use xrayrequire as suggested to find any circular dependency without success. I looked for requires of the conflicting file and found out I was requiring it twice with different names.
Related
So i never used requireJS before, but because Qlik Sense is using it for its mashups i had to try it one way or another.
I just made a simple bootstrap mashup, added the highcharts library and bought a bootstrap admin theme (name = Naut) on a theme website.
I moved everything i could use from the bought theme to the simple bootstrap mashup (css, html, js) and then i tried to modify the require.config
this is how my require.config file is looking at the moment.
Keep in mind that jQuery is default inside of the requireJS file (i think the developers of Qlik Sense have made it that way by default).
var config = {
host: window.location.hostname,
prefix: "/",
port: window.location.port,
isSecure: window.location.protocol === "https:"
};
require.config( {
baseUrl: ( config.isSecure ? "https://" : "http://" ) + config.host + (config.port ? ":" + config.port: "") + config.prefix + "resources",
paths: {
bootstrap: "/extensions/fitcloud/js/vendor/bootstrap.min",
bootstrapSwitch: "/extensions/fitcloud/js/vendor/bootstrap-switch.min",
highcharts: "/extensions/fitcloud/js/vendor/highcharts",
senseutils: "/extensions/fitcloud/js/vendor/senseUtils",
treefy: "/extensions/fitcloud/js/vendor/bootstrap-treefy.min",
mainsc: "/extensions/fitcloud/js/main",
vendor: "/extensions/fitcloud/scripts/vendor",
plugins: "/extensions/fitcloud/scripts/plugins",
main: "/extensions/fitcloud/scripts/main"
},
shim: {
bootstrap : {
deps : ['jquery']
},
bootstrapSwitch : {
deps : ['jquery']
},
highcharts : {
deps : ['jquery'],
exports: 'Highcharts'
},
treefy : {
deps : ['jquery']
},
mainsc : {
deps : ['treefy']
},
senseutils : {
deps : ['bootstrap']
},
vendor : {
deps : ['jquery']
},
plugins : {
deps : ['vendor']
},
main : {
deps : ['plugins']
}
}
} );
require( ["js/qlik"], function ( qlik ) { qlik.setOnError( function ( error ) { alert( error.message ); } );
require(["jquery", "bootstrap", "bootstrapSwitch", "highcharts", "senseutils", "treefy", "mainsc", "vendor", "plugins", "main"], function (jq, bs, bss, hs, su, tf, ms, ve, pl, ma) {
var app = qlik.openApp('test.qvf', config);
// All the rest of my javascript code goes in here
});
The js files vendor, plugins & main are the javascript files from the theme i bought. When i put them into the require.config and require i start getting errors TypeError: $(...).highcharts is not a function & TypeError: $(...).bootstrapSwitch is not a function and my app is broken, no charts are loaded and bootstrapSwitch buttons are not working eather. If i remove them, everthing is working fine except i don't have the interactivity the theme is having ( closing sidebar, bouncing menu, ... ).
Am i doing anything wrong, or could it be that some function names are used in multiple libraries?
Your start of the extension should look like this (properties, qlik, jquery, always needed the js dependencies after that are optional but you will probably need
define(["./properties", "qlik","jquery","highcharts", "bootstrapSwitch"],
function(Props, qlik,$,highcharts,boostrapswitch) {
To explain, it first loads in the actual files with this part define(["./properties", "qlik","jquery","highcharts", "bootstrapSwitch"],
That is telling Qlik which JS files to bring in (you dont actually need to put.js after the files.
The error you describe happens when you are not properly passing the stuff inside these js files to the function. This is done in the second part..
function(Props, qlik,$,highcharts,boostrapswitch)
You see there are 5 params because you originally pass 5 js files.
You need to make sure they are in the same order for both parts.
Here is an example of a Qlik Sense extension, I recommend you examine the properties.js and the TalkToQlik.js to see how it should look.
https://github.com/cookiejest/TalkToQlik
Here is some instructions for that extension:
http://webofwork.com/qlik-sense-voice-control-extension-for-accessibility/
When I run my project locally with my grunt:server task, the project works as I expect. However, after building which takes all the vendor code and puts it into one file, two of my needed module aren't avialable, and the project doesn't work.
Here is my requirejs configuration:
requirejs.config
baseUrl: './js'
shim:
'underscore':
exports: '_'
'backbone':
deps: ['underscore', 'jquery']
exports: 'Backbone'
'stack':
deps: ['d3.global']
exports: 'stack'
'highlight':
exports: 'hljs'
paths:
'underscore': '../components/underscore/underscore'
'backbone': '../components/backbone/backbone'
'jquery': '../components/jquery/jquery'
'd3': '../components/d3/d3'
'd3.global': '../components/d3.global/d3.global'
'stack': '../components/stack/stack'
'highlight': '../components/highlightjs/highlight.pack'
require ['app/vendors'],->
console.log("Backbone", Backbone)
console.log("_", _)
console.log("$", $)
console.log("d3", d3)
console.log("stack", stack)
console.log("hljs", hljs)
app/vendors looks like
define [
'underscore'
'jquery'
'backbone'
'text'
'd3.global'
'stack'
'highlight'
], ->
When I run the project locally via grunt, I see all the globals printed out. However, when I build the project, Backbone Underscore and JQuery print out, while stack fails (hljs is also not available, and if I remove stack from app/vendors, it doesn't fix highlight, so its probably not an order thing).
the requirejs optimizer is called with the following configuration:
requirejs:
compile:
options:
baseUrl: 'js/'
appDir: './<%= yeoman.tmp_dist %>/'
dir: './<%= yeoman.dist %>/'
wrap: true
removeCombined: true
keepBuildDir: true
inlineText: true
mainConfigFile: '<%= yeoman.tmp_dist %>/js/main.js'
# no minification, is done by the min task
optimize: "none"
modules: [
{ name: 'app/vendors', exclude: [] }
{ name: 'app/app', exclude: ['app/vendors'] }
{ name: 'main', exclude: ['app/app', 'app/vendors'] }
Could there be something wrong with the stack and highlight files that I need to fix in order to make requirejs optimization and uglify work with them?
I installed highlightjs via bower by adding "highlightjs": "~8.0" to my bower.json file and running bower install. I downloaded stack.js from mbostock's stack project. I'm using v0 at the moment, with minor changes to make it work in this project. The source for all these are in the components directory of my github project.
BOUNTY If anyone is willing to clone the repo themselves, and try running the project with grunt server and grunt build to help me track down the problem, I'd greatly appreciate it. At the moment I have the vendor scripts in the github repo itself, so all you should need is compass and bower to run it.
This is due to wrap: true in the r.js config. Here's a simple configuration that isolates the issue:
main.js
define([ 'legacy' ], function(legacy) {
var greeting = 'hi';
console.log(greeting, legacy.foo);
});
legacy.js
var globalThing = { foo: 1, bar: 2 };
build.json
{
"name": "main",
"optimize": "none",
"out": "main-built.js",
"shim": { "legacy": { "exports": "globalThing" } },
"wrap": true
}
Let's run r.js (r.js -o build.json) and consider the result (formatted by me):
(function() { // this immediately-invoked function expression (IIFE)
// is here because r.js has "wrap: true" in the config
var globalThing = { foo: 1, bar: 2 };
// code generated from the "shim" entry in the config
define('legacy', function(global) {
return function() {
var ret, fn;
// since global.globalThing is undefined,
// that's where it goes wrong
return ret || global.globalThing;
};
}(this));
define('main', [ 'legacy' ], function(legacy) {
var greeting = 'hi';
console.log(greeting, legacy.foo);
});
})(); // end of the IIFE
As you can see from the code above, globalThing isn't global any more. The same happens with the stack and highlight libraries in your project as they use var and function declarations to define their globals.
To tackle this issue, we have a couple of options. The first is to consider whether you really need wrap: true in the config. If you drop it, the globals will get global again and everything should start working as expected. The second option is to try adding wrapShim: true to the config. You can read about nuances of using this option here. If we try it with our sample configuration, we'll get something like this:
(function() {
(function(root) {
define('legacy', [], function() {
return function() {
var globalThing = { foo: 1, bar: 2 };
return root.globalThing = globalThing;
}.apply(root, arguments);
});
})(this);
define('main', [ 'legacy' ], function(legacy) {
var greeting = 'hi';
console.log(greeting, legacy.foo);
});
})();
Looks good to me.
Everything works (Karama, Jasmine, Underscore, Backbone, testr) as evidenced by the _UnitTestUnitTest passing. But simple testr statements always fail.
The basic _UnitTestUnitTest works!
it('works for jquery', function() {
expect( $("document")).toBeTruthy();
});
it('works for underscore', function() {
expect(_.size([1,2,3])).toEqual(3);
});
it('works for backbone', function() {
var model = Backbone.Model.extend();
expect(model).toBeTruthy();
});
it('works for testr', function() {
expect(testr).toBeTruthy();
});
However, in my other real unit test, it fails on the testr line:
AccountSummaryCollection_CLASS = testr('models/sales-rep/AccountSummaryCollection');
I'm certain i'm including my dependency of 'models/sales-rep/AccountSummaryCollection' correctly in my config (I see it hosted and getting loaded by require.js deps!!!
However, the big problem is it claims our application module is not loaded even though it is. I also tried to wrap the whole AccountSummaryUnitTest.js inside of require([‘AccountSummaryCollection’], function(){…. This produces a new error where inside a dependency (AccountSummary.js) the error “Backbone is not defined” is thrown. That makes no sense in the context because obviously the AccountSummaryCollection has already resolved Backbone.Collection. This bad resolution is what makes me suspect it is testr that is fishy.
I also tried to manually include the file using the karma config, but requirejs does not like that since it’s a conflicting define() function.
Below: serving actually means Requested by Client and the {{{dependency}}} file is my own trace to confirm they are added to the deps list in the karma-spec-runner.js.
It fails at this line:
AccountSummaryUnitCollection line 27: AccountSummaryCollection_CLASS = testr('models/sales-rep/AccountSummaryCollection');
Here's the "spec runner" javascript (basically copied from the docs, with some extra logging).
var dependencies = [];
for (var file in window.__karma__.files) {
if (window.__karma__.files.hasOwnProperty(file)) {
//
if (/Test\.js$/.test(file)) {
//traces my test files fine!
console.log("{{{testing file}}} --> "+ file );
dependencies.push(file);
}
}
}
// jam our application files into the deps
for (var file in window.__karma__.files) {
if (window.__karma__.files.hasOwnProperty(file)) {
if (file.indexOf('src/main/app/') !== -1 ) {
//traces my dep files fine!
console.log("{{{dependency}}} file --> "+ file );
dependencies.push(file);
}
}
}
require.config({
baseUrl: 'base/src/main/app/',
paths: {
'resources' : '../resources/',
'jquery' : '../resources/js/lib/jquery-2.1.0.min',
'text' : '../resources/js/lib/text-2.0.10',
'i18n' : '../resources/js/lib/i18n-2.0.4',
'd3' : '../resources/js/lib/d3.v3.1.10.min',
'AppMeasurement' : '../resources/js/lib/appMeasurement',
'underscore' : '../resources/js/lib/underscore-1.5.2',
'Backbone' : '../resources/js/lib/backbone-1.1.2.min',
'testr' : '../../test/lib/testr'
},
deps: dependencies,
shim: {
d3: {
exports: 'd3'
},
AppMeasurement: {
exports: 'AppMeasurement'
},
underscore: {
deps:["jquery"],
exports: '_'
},
Backbone: {
deps:["jquery"],
exports: 'Backbone'
},
testr:{
exports: 'testr'
}
},
callback: window.__karma__.start,
locale: "en-us"
});
Here's the karma section of my gruntfile
karma: {
unit: {
background: false,
options: {
logLevel : 'debug',
basePath:'./',
// files for karma to host
files: [
{pattern: 'src/main/resources/js/lib/**/*.js', included: false, served: true},
{pattern: 'src/main/resources/js/plugins/**/*.js', included:false, served: true },
{pattern: 'src/test/lib/sinon.js', included: false },
{pattern: 'src/test/lib/testr.js', included: false },
{pattern: 'src/test/js/stubs/**/*.js', included: false, served: true},
// manually load our application unit test & deps to examine the simplest case
{pattern:'src/main/app/models/sales-rep/AccountSummary.js', included: false },
{pattern:'src/main/app/models/sales-rep/AccountSummaryCollection.js', included: false },
{pattern: '_UnitTestUnitTest.js', included: false},
{pattern: 'src/test/js/unit/AccountSummaryCollectionUnitTest.js', included: false},
'src/test/js/karma-spec-runner.js'
],
plugins: [
"karma-jasmine",
"karma-phantomjs-launcher",
"karma-requirejs",
'karma-chrome-launcher',
],
frameworks: [
"jasmine",
"requirejs"
],
browsers: [
//"PhantomJS"
"Chrome"
]
}
}
},
Here's a sample test that fails
Note that the testr config is per unit test. Plus, this test WORKS in plain in the browser jasmine!
// tried with and without the leading require statement as noted in main question.
require( ['models/sales-rep/AccountSummaryCollection'], function() {
describe('AccountSummaryCollectionUnitTest', function () {
var AccountSummaryCollection_CLASS;
function configureTestr() {
testr.config({
whitelist: [
'models/sales-rep/AccountSummaryCollection',
'models/sales-rep/AccountSummary'
]
});
}
beforeEach(function () {
configureTestr();
console.log("initializing AccountSummaryCollection_CLASS");
//fails on following line
AccountSummaryCollection_CLASS = testr('models/sales-rep/AccountSummaryCollection');
});
You need specific versions of libs to get it to work right:
testr 1.0.2 (NOT 1.0.3!!!!!)
Backbone 1.0.0 (not 1.1.2 for some reason)
underscore 1.6
require-2.1.11 [production] (for some reason we had 2.1.2)
Then I had to include:true for underscore and backbone in the Karma config. Then the shim works with require 2.1.11 without the mismatched anonymous define error.
Additioanlly, to make sure to delay the test execution. I did not have luck with the waitSeconds (that just increases the test duration).
The key part of the require config:
// since we are forcing Backbone in the dom instead of requiring it
callback: function(){
setTimeout(function () {
window.__karma__.start();
}, 4000);
},
I have kind of the same problem described in this question but there seem to be no right answer.
I'm trying to load the "loadImages" lib with require.js but I get this
Uncaught TypeError: Object [object Object] has no method 'imagesLoaded'
Here is the script on my page :
require(['./js/common'], function(common)
{
require(['home/main-home']);
});
My common.js
requirejs.config({
baseUrl: './js',
paths: {
jquery : 'libs/jquery/jquery-2.0.3.min',
eventie : 'libs/eventie/eventie',
eventEmitter : 'libs/eventEmitter/eventEmitter.min',
imagesLoaded : 'libs/imagesLoaded/imagesloaded.pkgd.min',
masonry : 'libs/masonry/masonry.pkgd.min',
wall : './wall/wall',
underscore : '../libs/underscore/underscore-min',
backbone : '../libs/backbone/backbone-min',
},
shim: {
jquery : {
exports : '$'
},
imagesLoaded : {
deps : ['jquery', 'eventie', 'eventEmitter']
},
masonry : ['jquery'],
wall : ['masonry', 'imagesLoaded'],
backbone : {
deps : ['jquery', 'underscore'],
exports : 'Backbone'
},
underscore : {
exports : '_'
}
}
});
and this is my main-home.js where I want to use the imagesLoaded lib.
define([
'wall'
],
function(Wall){
$(function()
{
$('#photos').imagesLoaded( function(){}); // ERROR
});
return true;
});
In the imagesLoaded doc there's a small paragrah about require.js which i don't really understand. I tried to load thoses libs as well, but it is not changing anything.
// Install imagesLoaded and its dependencies
// Update your RequireJS paths config so it can find those modules
requirejs.config({
paths: {
"eventie": "bower_components/eventie",
"eventEmitter": "bower_components/eventEmitter"
}
});
They seem to talk about it in here https://github.com/desandro/imagesloaded/issues/68, but I don't really know what to do.
Here is the js files my page is loading :
We can see that imagesLoaded is loaded...
How come do I still have this error then ?
This jsfiddle works.
I've edited the ImagesLoaded JS (as a gist) to give the modules a valid module id.
Search for:
// --------------------------------------------------
// ADDED A MODULE ID
// --------------------------------------------------
in the code for the 3 changes (to define the imagesLoaded, eventEmitter/EventEmitter and eventie/eventie modules).
Given that the ImageLoaded JS file already includes the other 2 modules, there is no need for any more paths/shims.
HTML
<div id="photos"></div>
<script>
require = {
paths: {
"jquery": "http://code.jquery.com/jquery-2.0.3",
"imagesLoaded": "https://rawgithub.com/gitgrimbo/6451492/raw/f26e23d7a180ee23fd3dea3b0b152dbf523854a1/ImageLoaded-mod"
}
};
</script>
<script src="http://requirejs.org/docs/release/2.1.8/comments/require.js"></script>
JS
require(["jquery", "imagesLoaded"], function($, imagesLoaded) {
console.log($.fn.jquery);
console.log(imagesLoaded);
$('#photos').imagesLoaded(function() {
console.log("something");
});
});
Output
2.0.3
ImagesLoaded( elem, options, onAlways )
something
I'm getting this error when the optimizer is launched by grunt
(I'm using yeoman backbone-generator )
Running "requirejs:dist" (requirejs) task
Error: ReferenceError: window is not defined
I'm using requirejs and the plugin i18n.
This is my main.js
require.config({
//locale: "en",
shim: {
underscore: {
exports: '_'
},
backbone: {
deps: [
'underscore',
'jquery'
],
exports: 'Backbone'
},
'jquery-notify': {
deps: [
'jquery'
]
},
swiper: {
deps: [
'jquery'
],
exports: 'Swiper'
},
bstrapcollapse: {
deps: [
'jquery',
'bstraptransition'
],
exports: 'collapse',
}
},
paths: {
jquery: '../bower_components/jquery/jquery',
backbone: '../bower_components/backbone-amd/backbone',
underscore: '../bower_components/underscore-amd/underscore',
i18n: '../bower_components/requirejs-i18n/i18n',
'backbone.marionette': '../bower_components/backbone.marionette/lib/core/amd/backbone.marionette',
'backbone.wreqr': '../bower_components/backbone.wreqr/lib/amd/backbone.wreqr',
'backbone.babysitter': '../bower_components/backbone.babysitter/lib/amd/backbone.babysitter',
'jquery-ui': '../bower_components/jquery-ui/ui/jquery-ui',
loglevel: '../bower_components/loglevel/dist/loglevel.min',
moment: '../bower_components/moment/moment',
alertify: '../bower_components/alertify/alertify',
swiper: '../bower_components/swiper/dist/idangerous.swiper-2.0.min',
fastclick: '../bower_components/fastclick/lib/fastclick',
bstrapcollapse: '../bower_components/sass-bootstrap/js/bootstrap-collapse',
bstraptransition: '../bower_components/sass-bootstrap/js/bootstrap-transition',
'requirejs-text': '../bower_components/requirejs-text/text',
async: '../bower_components/requirejs-plugins/src/async',
},
config: {
i18n: {
locale: JSON.parse(window.localStorage.getItem('settings')).language || 'en',
}
}
});
I need to change language based on user input that's why i need to fetch localStorage and set the locale in the config.
There's a solution for this?
Thank you.
I haven't done much in the region of runtime javascript, but I know that many of the libraries you know and are used to in browsers (document object model's "getElementById", local storage) are not available in runtimes like Grunt or Rhino. Your use of localStorage in that settings file appears to be the issue.
Instead, you need to make use of whatever API is given to you. For instance, a quick search found some Grunt examples where they read/write to a file on the filesystem: http://gruntjs.com/sample-gruntfile
Obviously, this would be impossible in a browser, as browsers don't let you access files; but you may as well take advantage of it in Grunt. You can also feature-detect which mode you're in with clauses like this:
if (window) {
...
}
else if (grunt) {
...
}
A workaround that worked for me :
config: {
i18n: {
locale: (function(){
try{
return localStorage.getItem('locale') || 'en' ;
}catch(ex){
return 'en';
}
})()
}
}
But still not convinced by this trick. Maybe someone else has a better idea ?