Adding a package to dojo config at runtime - javascript

Is there a way I can add a new package to dojo config? I know I can do this: Add packages when dojo.js loads.
<script src='dojo_1.7.2/dojo/dojo.js'
data-dojo-config="async:true,isDebug:true,parseOnLoad:false,
packages:[{name:'project1',location:'../../js/proj1'},
{name:'common',location:'../../common'}]"></script>
I want to be able to add new packages at runtime.
dojo.registerModulePath did do this job prior to dojo1.6 (i think) but its now deprecated in 1.7
I am using dojo 1.7.2.
Thanks.

You can add extra packages after load by calling require with a config object.
Eg:
require({
packages: [
{"name": "myLib", "location": "release/myLib"}
]
});
This will however, create another instance of Dojo, according to the documentation (dojo/_base/config). Also, this is version 1.8 code; I don't think it works with 1.7.
I thought it might possible to push an extra object to dojoConfig or require.rawConfig but these are not picked-up by the loader. It appears that config cannot be changed after load.
You can pass a config object to require, so:
Eg.
dojoConfig.packages.push({"name": "myLib", "location": "release/myLib"});
require(dojoConfig, [...moduleIds...], function(...arguments...) {
});
This will work for the individual require but will not modify the global config (and hence will not work in define() or subsequent calls to require()). Again, I'm using 1.8 here but I assume it works in 1.7.
There may be another simpler way of making this work that someone else as found?

The solution by Stephen Simpson didn't seem to work right for me with dojo v1.13. It ignored the given location and was still trying to load the files relative to the default basePath despite of the project path starting it with a /. I got errors in the console, too.
But the documentation also mentions the paths parameter which worked for me. In your case:
require({paths:{"project1": "../../js/proj1", …}});
It probably worked for you because you're using a relative path and I don't.
It used to be dojo.registerModulePath("myModule", "/path/goes/here");.

Related

how to jquery and bootstrap file using in requirejs?

define(["jquery","bootstrap","jquery.min"],function($){
var inittest = function(){
alert("hello");
}
var init = function(){
inittest();
};
return {
init: init
}
});
It's not working. How to use jQuery to define array?
You need to do two things here (the details are in the useful thread I linked you to, so please read).
Configure requirejs so that when you declare modules (e.g. "jquery", "bootstrap"), requirejs can resolve them to actual files, minified or otherwise.
Shim bootstrap by specifying jquery as its dependency, so that jquery is loaded before it.
To accomplish these, make a call to requirejs.config({...}) with the appropriate options (here is an example). The use case there is exactly the same as yours: jquery is specified as a bootstrap dependency by shimming bootstrap. There you will also see an example of how to tell requirejs where your files are (this is accomplished via the paths property). Note how the .js extension is not explicitly specified there; do the same.
Needless to say, configuring requirejs can get complicated, but the basic idea is there, configure it by specifying the base directory and where the files are to be found, then shim non-AMD modules. An important thing to be aware of is that bootstrap is going to be what's called a declarative module, which means that it's only used for its side-effects (viz. for what changes it makes to $).

Dojo build css and custom javascript

I've set up a single html page that uses three dojo widgets and I'm trying to create a custom build from it using dojo 1.7.5. The build succeeds leaving me with a dojo.js that includes the files I need using this build file:
var dependencies = {
action: "release",
selectorEngine: "acme",
stripConsole: "none",
cssOptimize: "comments.keepLines",
layers: [
{
name: "dojo.js",
dependencies: [
"dijit.form.ValidationTextBox",
"dijit.form.DropDownButton",
"dijit.form.Button",
"dijit.form.Form",
"dijit._base",
"dijit._Container",
"dijit._HasDropDown",
"dijit.form.ComboButton",
"dijit.form.ToggleButton",
"dijit.form._ToggleButtonMixin",
"dojo.parser",
"dojo.date.stamp",
"dojo._firebug.firebug"
]
}, {
name: "../test/test.js",
dependencies: [
"test.test"
]
}
],
prefixes: [
[ "dijit", "../dijit" ],
[ "dojox", "../dojox" ],
[ "ourpeople", "../ourpeople" ]
]
};
The questions I can't seem to find an answer to:
I'm using cssOptimize, I was expecting a single css file in which all the used css files were imported. However I can't find such a file. Is this the way dojo compresses it's css or are my expectations wrong? If so where can I find it in my release folder?
My test.js contains a function test1() if I call it from my built js it states test1 is not defined. I call that function directly without dojo. I'm assuming that building custom js only works if it is a dojo class using declare?
Final question, I needed to include several dojo files in the build manually such as dojo._firebug.firebug since after my initial build it was still using xhr calls to get those files. After including the files manually I still see xhr calls from dojo to specific resources: dojo/nls/dojo_ROOT and dijit/form/nls/validate.js. Those files are created during the build process and therefore can't be included in the dependencies in the build profile. Anyone any thoughts on this matter since I'm looking to distribute dojo in a single file.
I'm fairly new to the dojo build system and (especially) so perhaps I'm expecting things that the dojo build system isn't designed to do or maybe om going about this the wrong way if so any tips or suggestions are more than welcome.
Cheers!
Test.js:
function test1() {
console.log("test1");
}
Index.php:
<script type="text/javascript" src="js/release/dojo/dojo/dojo.js"></script>
<script type="text/javascript" src="js/release/dojo/test/test.js"></script>
<script type="text/javascript">
dojo.require("dijit.form.ValidationTextBox");
dojo.require("dijit.form.Button");
dojo.require("dijit.form.Form");
dojo.ready(function() {
test1();
});
</script>
I'm using cssOptimize, I was expecting a single css file in which all the used css files were imported. However I can't find such a file. Is this the way dojo compresses it's css or are my expectations wrong? If so where can I find it in my release folder?
When you use cssOptimize, the Dojo build optimizes and flattens CSS files in place. So for example, if you're using Dijit's Claro theme, when you load dijit/themes/claro/claro.css from source, it contains a series of #import statements which in turn load more files. When you load claro.css from a build with cssOptimize, it is one file containing all of the styles previously referenced via those separate files.
My test.js contains a function test1() if I call it from my built js it states test1 is not defined. I call that function directly without dojo. I'm assuming that building custom js only works if it is a dojo class using declare?
Dojo doesn't expect every JS file to be a "class" using declare but it does expect each file to be a module which doesn't implicitly define globals (since globals should be avoided in modules anyway). When the build process encounters a module that it thinks or knows isn't AMD, it assumes it's a legacy Dojo module and wraps it in a boilerplate to convert it to AMD. This boilerplate ends up encapsulating your globals into a function scope, so they are no longer globals.
Given that you're using Dojo 1.7, you should ideally be using the AMD format to define and consume modules. dojotoolkit.org has a tutorial introducing AMD modules, and if you're migrating from Dojo 1.6 or earlier, there's also a tutorial to help you transition.
Final question, I needed to include several dojo files in the build manually such as dojo._firebug.firebug since after my initial build it was still using xhr calls to get those files. After including the files manually I still see xhr calls from dojo to specific resources: dojo/nls/dojo_ROOT and dijit/form/nls/validate.js. Those files are created during the build process and therefore can't be included in the dependencies in the build profile. Anyone any thoughts on this matter since I'm looking to distribute dojo in a single file.
I'm not sure why you're seeing dojo/_firebug/firebug being automatically loaded, but based on what you've said/shown above I would immediately suggest the following:
Convert your modules/code to AMD format
Add async: true to your dojoConfig which will cause the loader to operate in asynchronous mode, which means:
It loads modules through script injection instead of synchronous XHR
It won't unconditionally load all of dojo/_base
Add customBase: true to your dojo/dojo layer which will prevent the build from defaulting to include all of dojo/_base
As for the nls modules, to an extent it's normal to still see NLS files requested, though if your build is configured properly there would ordinarily just be one NLS file per layer and that's it (the fact that you're seeing a separate request for validate leads me to think you haven't covered all of your dependencies). The reason NLS remains separate is because there is one NLS bundle per locale, and it doesn't make sense to build all locales into one layer - that would force people to pay for resources in 20 languages they don't care about.

RequireJS, AccountingJs - passing global config into accounting

Im quite new to using requireJs and im having an issue with setting global configuration for a module.
I am using accountingJs and want to modify the setting globally in this case i want to change the symbol from $ to £.
Without RequireJS you would simply do something like this as accounting would be in the global namespace
accounting.settings = $.extend(accounting.settings, {
currency: { symbol: '\u00A3 '}
});
accountingJs is AMD compliant and works perfectly with require but i cant seem to figure out a way of passing the config into it globally rather than .
I have seen the config setting in require docs here and i can set the config here but accountingjs doesn't pick this up (it isnt coded to!).
My question is how can i set configuration like this for a AMD compliant module globally within the page?
I can see a few options
Edit accountingjs to look at module.config() and load any config it sees - i have tried this and it does work as expected but i dont really want a custom.
use shim config and use the init call back - i havent got this to work (maybe because it is already AMD compliant)
create a new module to wrap accountingjs in another define and apply the config here and use this module in each page - not tries this but i guess it would work...
what i really ant to do is have a way of globally applying config to an already existing module from the require config is it possible??
If the AMD module is not designed to use module.config, then you can't force it to use it. The solution you mention last is the most robust: create a wrapper module that configures the actual module as you want. This wrapper can use module.config to grab values. This solution is likely to work with RequireJS now and for quite a long time since you're using API features that are well documented and central to RequireJS' functionality.
As for a shim, I don't recall the docs for RequireJS ever providing a solution that consists as using a shim for a module that is already designed to work with AMD loaders. So if using a shim worked, it would be by happenstance rather than by design.

requirejs require text! with relative path cause unnormalized error on iphone, bet works on emulator

I am using requirejs with phonegap, and load some text file in module definition like this
define(['text!../configuration/systemcore.cfg', //config files
'text!../language/cn.systemcore.lang', //languagefiles
'Configuration', 'DatabaseHandler', 'Language', //framework js
'FileHandler', 'NotificationHandler',
'BaseModule' //base classes
],
function(cfg, lang,
Configuration, DatabaseHandler, Language, FileHandler, NotificationHandler,
BaseModule) {
Everything works fine in the ios emulator, but once loaded into ios device, it causes
unnormalized error on text file which leads to load module timeout, why...
Ok, I added text : 'path/to/text.js' in the requirejs.config({ patch : {...}}) and it solved the problem. It is still weird how can it work before in the emulator when I dont specifically point to the text.js
Maybe this answer is not a solution for this specific question, but however this topic I've found searching for similar problem: unnormalized error and load timeout in console, so might be useful to post it here.
Text plugin seems to work incorrectly when referenced two times with different paths (from my experience).
E.g. if you reference it with full path first:
define(["js/libs/text!somefile.html"], ...)
and then config requireJS path and use alias to it:
require.config({paths: {
"text": "js/libs/text.js"
}});
define(["text!somefile.html"], ...)
it makes the same module to be loaded twice, and the second define causes an error. Correct me if I am wrong.

I don't understand how require.js handles the load paths. Do I need to use require.config every time I define a module?

I am learning about require.js and think I am just missing something. I don't understand how it loads files.
I have my jquery file in a lib directory.
This does not work:
It shows that jquery is being loaded in the chrome network panel. Error is: Uncaught TypeError: undefined is not a function . so it is basically saying that $ is undefined.
require(['lib/jquery'],function($) {
$(document).ready(function(){
alert('hello');
});
});
This works:
require.config({
paths: {
jquery: 'lib/jquery'
}
});
require(['jquery'],function($) {
$(document).ready(function(){
alert('hello');
});
});
In other examples I see online you don't have to set the paths with require.config. Do I have to do this every time that I want to define a module? I know I am using require and not define in this case, but I am having the same issue with the define method. Every time I make a module using define I have to set the paths using require.config(). I think I am missing something here. Can anyone point me in the right direction?
This is a constraint on the AMD registration done by jquery. It explicitly registers as a named module called 'jquery' so you must have a paths config in for it, or in the case above, set baseUrl to be 'lib' then you do not need the paths config.
Other libraries normally should use an anonymous module registration, so you should not need to do a paths config for every library. More details here.
Also, some libraries, like underscore, do not call define() directly, but you can get a level of support by using the shim config.
Update to reflect comments and James' answer:
You have two problems:
jQuery, for the reasons James outlines in his answer, requires that you either have paths set in your config, or that you, in the code you've outlined, set baseUrl to "lib".
you have to remember that you can't just load any old script with RequireJS. Only scripts that conform to the AMD standard can be loaded.
Having said this, I'd advice you use require-jquery instead.
You'll probably end up using jQuery plugins that will assume jQuery is loaded on the page, and those won't work with the approach you're trying.

Categories

Resources