Dojo build package configuration - javascript

In our Dojo system, we have something like the following specified in our dojoConfig:
packages: [{
name: "myWidgets",
location: "/js/libs/widgets"
}]
So that in our require statements, all we have to do is something like:
require(["myWidgets/myCalendarWidget"....
The problem is when I run the build, this dojoConfig is not available and I get numerous missing dependency errors because 'myWidgets' isn't defined according to the build profile.
Now, I've tried adding a package block to the build profile also, but the end result of that is to create an actual 'myWidgets' package, which I don't want.
So, is there any way to make the build see the definition of the 'myWidgets' alias, yet have the end result of the build output still mirror the regular file structure (i.e. /js/libs/widgets)? I tried to define these path aliases in the defaultConfig element in the build profile and that doesn't work either.

If you are using a profile, you can specify the packages in the profile
/util/buildscripts:./build.sh profile=../../../myProfile.js
http://dojotoolkit.org/reference-guide/1.8/build/buildSystem.html#profile-basics
You can also specify a javascript file that holds the dojoConfig
/util/buildscripts:./build.sh --dojoConfig ../build/examples/dojoConfig.js
http://dojotoolkit.org/reference-guide/1.8/build/buildSystem.html#using-a-package-configuration
Answer to your comment. The path is relative from where dojo.js is.
var dojoConfig = {
parseOnLoad: true,
isDebug: true,
locale: 'en-us',
paths: {
"evf": "../../evf"
}
};
My directory structure looks like
js/dojo-1.8.0
dijit
dojo <-- contains dojo.js
dojox
util
js/evf
myCustomWidget.js

Related

How to replace placeholders for environment variables in static `index.html` to actual values with brunch?

I use brunch for compilation of static assets. I've an index.html containing a <script> tag with environment variable placeholders. Based on the environment I want to change the placeholders to actual values. How can I do it the simplest way using brunch?
I tried several plugins, but although sounds to be a simple task, I fail to get anything replaced.
You can install handlebars-brunch plugin from master, add
handlebars: {
locals: {
env: process.env
}
}
to plugins in brunch-config.js, rename index.html to index.html.hbs and use it like this:
<script>
alert("{{env.key}}")
</script>

How to get the r.js build script working

I've read through the documentation and the example app.build.js file but just can't get my js files to concatenate and minify into one single file. I think I'm just not understanding exactly what settings I need in the build script and was hoping for some help.
My app is set up like this:
src >
js >
build.js
r.js
config.js
app >
main.js
lib >
module1.js
module2.js
module3.js
vendor >
require.js
jquery.js
jquery.validation.js
build >
// Where concat and minified file would go
config.js looks like this:
requirejs.config({
"baseUrl" : "src/js/lib", // Used because when setting dependencies in modules, this is used
"paths" : {
"app" : "../app",
"jquery" : [
"https://code.jquery.com/jquery-1.11.1.min",
"../vendor/jquery"
],
"validate" : "../vendor/jquery.validate.min"
},
"shim" : {
// Allow plugins with dependencies to load asynchronously
validate : ["jquery"]
}
});
// Load the main app module to start the app
requirejs(["app/main"]);
main.js looks like this:
require(["module1", "module2", "module3"], function(Module1, Module2, Module3) {
return [
Module1.init(),
Module2.init(),
Module3.init(),
Module4.init()
];
});
And then the build.js is where I'm lost. I thought I should load a mainConfigFile because I'm using the shim, but I'm not sure. If I do load that config file, it uses the baseUrl from that config file. I'm not sure what name: is supposed to refer to exactly and whether I'm missing some necessary configuration options.
({
//baseUrl: ".",
paths: {
jquery: "empty:",
//main: "../app/main",
//app: "app"
},
name: "app/main",
out: "../build/main.js",
//mainConfigFile: "config"
})
If I run that build file as it is (with those lines commented out) I get:
Error: ENOENT, no such file or directory
'/Users/davidpaul/Sites/require/src/js/module1.js' In module tree:
app/main
I'm not really sure what's being referred to when it says 'module tree'. I keep making changes to paths in the build file but not making progress so hoping for someone to explain this a bit to me.
The builder parses all paths relative to the build file location (unless changed via the baseUrl property). If you look relative to src/js/build.js, your main.js is in ./app/ and module1/2/3.js are in ./lib/. All paths inside modules have to be specified relatively to the common root, so to make your example work it's enough to change the signature of main.js to:
require(["lib/module1", "lib/module2", "lib/module3"], function(M1, M2, M3) {
// (...)
})
Note that config.js doesn't take part in the build process, you may need to change it as well to make your application work both "raw" and optimized.

Is it possible to stop requireJS from adding the .js file extension automatically?

I'm using requireJS to load scripts. It has this detail in the docs:
The path that is used for a module name should not include the .js
extension, since the path mapping could be for a directory.
In my app, I map all of my script files in a config path, because they're dynamically generated at runtime (my scripts start life as things like order.js but become things like order.min.b25a571965d02d9c54871b7636ca1c5e.js (this is a hash of the file contents, for cachebusting purposes).
In some cases, require will add a second .js extension to the end of these paths. Although I generate the dynamic paths on the server side and then populate the config path, I have to then write some extra javascript code to remove the .js extension from the problematic files.
Reading the requireJS docs, I really don't understand why you'd ever want the path mapping to be used for a directory. Does this mean it's possible to somehow load an entire directory's worth of files in one call? I don't get it.
Does anybody know if it's possible to just force require to stop adding .js to file paths so I don't have to hack around it?
thanks.
UPDATE: added some code samples as requested.
This is inside my HTML file (it's a Scala project so we can't write these variables directly into a .js file):
foo.js.modules = {
order : '#Static("javascripts/order.min.js")',
reqwest : 'http://5.foo.appspot.com/js/libs/reqwest',
bean : 'http://4.foo.appspot.com/js/libs/bean.min',
detect : 'order!http://4.foo.appspot.com/js/detect/detect.js',
images : 'order!http://4.foo.appspot.com/js/detect/images.js',
basicTemplate : '#Static("javascripts/libs/basicTemplate.min.js")',
trailExpander : '#Static("javascripts/libs/trailExpander.min.js")',
fetchDiscussion : '#Static("javascripts/libs/fetchDiscussion.min.js")'
mostPopular : '#Static("javascripts/libs/mostPopular.min.js")'
};
Then inside my main.js:
requirejs.config({
paths: foo.js.modules
});
require([foo.js.modules.detect, foo.js.modules.images, "bean"],
function(detect, images, bean) {
// do stuff
});
In the example above, I have to use the string "bean" (which refers to the require path) rather than my direct object (like the others use foo.js.modules.bar) otherwise I get the extra .js appended.
Hope this makes sense.
If you don't feel like adding a dependency on noext, you can also just append a dummy query string to the path to prevent the .js extension from being appended, as in:
require.config({
paths: {
'signalr-hubs': '/signalr/hubs?noext'
}
});
This is what the noext plugin does.
requirejs' noext plugin:
Load scripts without appending ".js" extension, useful for dynamic scripts...
Documentation
check the examples folder. All the info you probably need will be inside comments or on the example code itself.
Basic usage
Put the plugins inside the baseUrl folder (usually same folder as the main.js file) or create an alias to the plugin location:
require.config({
paths : {
//create alias to plugins (not needed if plugins are on the baseUrl)
async: 'lib/require/async',
font: 'lib/require/font',
goog: 'lib/require/goog',
image: 'lib/require/image',
json: 'lib/require/json',
noext: 'lib/require/noext',
mdown: 'lib/require/mdown',
propertyParser : 'lib/require/propertyParser',
markdownConverter : 'lib/Markdown.Converter'
}
});
//use plugins as if they were at baseUrl
define([
'image!awsum.jpg',
'json!data/foo.json',
'noext!js/bar.php',
'mdown!data/lorem_ipsum.md',
'async!http://maps.google.com/maps/api/js?sensor=false',
'goog!visualization,1,packages:[corechart,geochart]',
'goog!search,1',
'font!google,families:[Tangerine,Cantarell]'
], function(awsum, foo, bar, loremIpsum){
//all dependencies are loaded (including gmaps and other google apis)
}
);
I am using requirejs server side with node.js. The noext plugin does not work for me. I suspect this is because it tries to add ?noext to a url and we have filenames instead of urls serverside.
I need to name my files .njs or .model to separate them from static .js files. Hopefully the author will update requirejs to not force automatic .js file extension conventions on the users.
Meanwhile here is a quick patch to disable this behavior.
To apply this patch (against version 2.1.15 of node_modules/requirejs/bin/r.js) :
Save in a file called disableAutoExt.diff or whatever and open a terminal
cd path/to/node_modules/
patch -p1 < path/to/disableAutoExt.diff
add disableAutoExt: true, to your requirejs.config: requirejs.config({disableAutoExt: true,});
Now we can do require(["test/index.njs", ...] ... and get back to work.
Save this patch in disableAutoExt.diff :
--- mod/node_modules/requirejs/bin/r.js 2014-09-07 20:54:07.000000000 -0400
+++ node_modules/requirejs/bin/r.js 2014-12-11 09:33:21.000000000 -0500
## -1884,6 +1884,10 ##
//Delegates to req.load. Broken out as a separate function to
//allow overriding in the optimizer.
load: function (id, url) {
+ if (config.disableAutoExt && url.match(/\..*\.js$/)) {
+ url = url.replace(/\.js$/, '');
+ }
+
req.load(context, id, url);
},
The patch simply adds the following around line 1887 to node_modules/requirejs/bin/r.js:
if (config.disableAutoExt && url.match(/\..*\.js$/)) {
url = url.replace(/\.js$/, '');
}
UPDATE: Improved patch by moving url change deeper in the code so it no longer causes a hang after calling undef on a module. Needed undef because:
To disable caching of modules when developing with node.js add this to your main app file:
requirejs.onResourceLoad = function(context, map)
{
requirejs.undef(map.name);
};

dojo : how to copy a dojo component to local directory and make it work

We have extended/customized dojo for our projects inside the company. our toolkit is called xwt.
I am considering making a copy of the sample file that is part of the toolkit into a local directory and start using it. So, I copied the SampleExtendedIFWS.js file into the local directory and changed the namespace it uses from dojo.provide("xwt.widget.tests.table.store.SampleExtendedIFWS") to dojo.provide("SampleExtendedIFWS").
From my application page(jsp), I started using dojo.require("SampleExtendedIFWS") -- however, now it is expecting the file from /app/resources/dojoroot/SampleExtendedIFWS.js and not the local directory.
How can I make dojo/xwt take the local directory version of SampleExtendedIFWS.js instead of expecting from /app/resources/dojoroot/SampleExtendedIFWS.js ?
Anjan
you need to specify your own namespace else it will look into dojoroot.
so at the same level as where you have dojo and xwt, you can create your own directory, lets say anjanb and put your SampleExtendedIFWS.js and change the dojo.provide to call it anjans.SampleExtendedIFWS
Now, in your sample HTML, you need to specify the module path in djConfig. For example:
djConfig = {
isDebug: false,
debugAtAllCosts: false,
parseOnLoad: true,
baseUrl: "<path to where your dojo.js resides>",
modulePaths: {
'xwt': '../xwt',
'anjans' : '../anjans'
}
};
Note that the module path is always relative to where dojo.js resides
do a dojo.require of your object:
dojo.require ("anjans.SampleExtendedIFWS");
this should get you going
btw, If you wish to extend the functionality, dojo provides more elegant mechanisms to extend the object instead of copying and changing by using dojo.extend, for example.

In RequireJs, how do I instruct the optimizer to to produce hash output files names?

I run the optimizer like this
sudo /usr/local/bin/node /tmp/r.j/r.js -o name=main out=test.js baseUrl=.
for test
Now, how do I tell the optimizer to output the filename as a hash of the content (obviously to set max expires) and then rename the dependency in the relevant require calls?
An example situation will be something like this
require({
baseUrl: '{{ STATIC_URL }}js',
paths: {
jquery: 'https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min',
jqueryui: 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.12/jquery-ui.min'
}
}, ['order!jquery','order!jqueryui','order!main']);
requirejs should be pulling something like 13KUJAW78M.js
Based on Miller Medeiros’s suggestion I am planning to put all the require calls into a single master file. This will also mean that all such calls will also need to be optimized.
e.g
switch(document.location.pathName){
case '/foo':
require(['sections/foo/main']);
break;
case '/foo/bar':
require(['sections/foo/main', 'core/bar']);
break;
default:
require('sections/home');
}
require(['sections/foo/main']);
should be optimized to a hash file.
Can someone help?
RequireJS optimizer doesn't have this option, but you could rename the files and use the paths config to set alias to the renamed files, see this thread for more info.
On your example for instance, if you rename the files to: 'sections/foo/main.123QWERT.js', 'sections/home.4567ASDFG.js', 'core/bar.0284ZXCV.js' you could just add a paths config like this:
require.config({
paths : {
//alias to new files without JS extension
'core/bar': 'core/bar.0284ZXCV',
'sections/home' : 'sections/home.4567ASDFG',
'sections/foo/main' : 'sections/foo/main.123QWERT'
}
});
The paths config should be on a file that won't be cached, maybe just keep the config on the HTML.

Categories