Cross Domain Defining using require.js - javascript

I'm learning how to use require.js. I am trying to define modules like this:
define('presenter', ['jquery'].......
The problem is that my host page is on a different domain at 'http://localhost:62607/' so I get a 404 error looking for presenter there.
Presenter is actually located here: 'http://localhost:62588/scripts/app/presenter'.
So if I define presenter like:
define('http://localhost:62588/scripts/app/presenter', ['jquery'],
Everything works fine but I much prefer the more readable first version.
Is there anything that can be done to achieve this?
Thanks

You can use the baseUrl and path properties in the requireJS configuration for achieving this.
From the requireJS documentation:
requirejs.config({
//By default load any module IDs from js/lib
baseUrl: 'js/lib',
//except, if the module ID starts with "app",
//load it from the js/app directory. paths
//config is relative to the baseUrl, and
//never includes a ".js" extension since
//the paths config could be for a directory.
paths: {
app: '../app'
}
});
If you define a module called app, requireJS will look for it at ../app

Related

RequireJS: optimizer generates name for define module

I'm using gulp.js and an optimization tool for requirejs (gulp-requirejs) it combines all scritps into one file. I have one define module with no name but it generates a name for it. The problem is I don't know how to call that module from another file.
For example in page1.js:
...
define("map",["jquery"],function($){
...
});
define("lib", ["jquery"],function($){
...
});
and in page2.js I would like to call page1.js lib module but I am not sure how to do it? I would prefer if the optimization tool did not set a name then my code works but this way I have no idea how to make it work. Any ideas?
It is not possible to use multiple modules in a single file, unless these modules are named. Otherwise RequireJS won't know how to relate a request for a module with the actual code that defines it.
The typical scenario when optimizing all modules into a single bundle is that there is going to be one specific module in the bundle which serves as the entry point of your application, and then you can just put that module name in paths:
require.config({
paths: {
lib: 'path/to/page1',
}
});
If you do not have a single entry point but may in fact also have code outside the bundle that will initiate loading modules that are in the bundle, then you need to list those modules in bundles:
require.config({
paths: {
lib: 'path/to/page1',
},
bundles: {
lib: ['map', ...],
}
});
The bundles setting I have shown above says essentially "when you look for the module named map, fetch the module lib, and you will have the definition of map."

Dynamic requirejs configuration extending

I'm using requirejs for multipage project. Each page is an App. All of the apps have some common dependencies, i.e. jquery, backbone, underscore etc.
I want to move all this dependencies to the one single file.
That's how the js folder structure looks like:
js
base-app-require-configuration.coffee
app
homepeage
init.coffee
build.js
application.coffee
app1
init.coffee
build.js
application.coffee
app2
init.coffee
build.js
application.coffee
Homepage application example:
js/base-app-require-configuration.coffee
define ->
requirejs.config
urlArgs: "bust=#{ new Date().getTime() }"
# yep, tricky paths here
paths:
jquery: '../../jquery.min'
underscore: '../../underscore-min'
backbone: '../../backbone.min'
js/app/homepage/init.coffee
define [
'../../base-app-require-configuration'
], (
baseRequireConfig
) ->
requirejs.config
paths:
'jquery.alphanum': '../../jquery.alphanum'
shim:
'jquery.alphanum':
deps: ['jquery']
require [
'jquery'
'application'
], (
$
Application
) ->
$ -> new Application
js/app/homepage/build.js
({
mainConfigFile: ['../../base-app-require-configuration.js', 'init.js'],
wrapShim: 'true',
baseUrl: './',
name: 'init',
findNestedDependencies: true,
out: 'init.js'
})
My data-name is init.js
The thing works pretty well for multiple apps with the common dependencies moved to one sigle file - base-app-require-configuration.coffee, except one thing: the only way to compress/optimize this using r.js is to set the flag findNestedDependencies to true, because otherwise r.js won't see requirejs.config calls nested into define/require.
My questions are:
Is using findNestedDependencies a good practice?
Is there a prettier way to organize my dependencies without repeating?
If there is such a way - will it be compatible with r.js?
Let me share this solution with you.
I'm also looking for the similar solution with requirejs (how to organize the multipage project without repetitions of a long configuration, with a "shim" feature), and I have found the following one (I would be glad if this snippet can help you):
Inside HTML:
...
<script src="js/lib/require.js"></script>
<script>
//Load common code that includes config, then load the app
//logic for this page. Do the requirejs calls here instead of
//a separate file so after a build there are only 2 HTTP
//requests instead of three.
requirejs(['./js/common'], function (common) {
//js/common sets the baseUrl to be js/ so
//can just ask for 'app/main1' here instead
//of 'js/app/main1'
requirejs(['app/main1']);
});
</script>
...
where "common.js" contains the common configuration of requirejs for your project. This sample is from: https://github.com/requirejs/example-multipage-shim/blob/master/www/page1.html.
The full code of a sample project is here: https://github.com/requirejs/example-multipage-shim. The sample "build.js" file also providen, I see there is no necessity in "findNestedDependencies" in this case.
Sure, there is a bit more code inside HTML, but I think this is not significant downside.
Is using findNestedDependencies a good practice?
Not sure. the only thing i know, is that this option can slow down the bundling process quite a lot:
Is r.js dependency tracing significantly slower since v2.1.16? Or is it just me?
Is there a prettier way to organize my dependencies without repeating?
If there is such a way - will it be compatible with r.js?
this is a great article out organising backbone modules using r.js:
https://cdnjs.com/libraries/backbone.js/tutorials/organizing-backbone-using-modules

Combining multiple files in grunt-requirejs

I have a Javascript application spanning multiple files using RequireJS, which I want to concatenate into one for the production environment.
I've been looking at grunt-contrib-requirejs but the instructions for setting up the configuration in Gruntfile.js assume that you already have the concatenated, production source. I'm aware that I could also use grunt-contrib-concat for this, but I was wondering if there's a way to do it with the grunt-contrib-requirejs module.
I've also tried using a wildcard selection for the name field in the configuration, but although Grunt works fine with specifications like app/**/*.js grunt-contrib-requirejs doesn't concatenate them when I specify this.
I found this example on how to do this, but when I include multiple entries in the modules array, running Grunt complains that certain files can't load their dependencies that are specified in the main file's require.config.
For example, if this is main.js:
require.config({
paths: {
'angular': 'http://some.cdn/angular.min'
},
shim: {
angular: {
exports: 'angular'
}
}
});
//Set up basic code
And this is controllers/ctrl.js:
define(['angular'], function(angular) {
...
});
Then it's apparently not loading the configuration from main.js and complains that there's no file /my/project/controllers/angular.js
I've also tried moving the configuration to a file specified with the mainConfigFile option, but this option does not work and it seems that this option was meant to take the Grunt configuration and not the RequireJS configuration.

node.js / backbone.js application load configuration file settings

I have a node / backbone / sails project that needs to have deployment specific configuration files loaded.
So in the sails portion of the app, I can place a config file in
myapp/config/mysettings.js
and reference it sails.config.mysettings.foo. This works as expected.
But in the backbone portion of the app, I cannot for the life of me figure out how to reference that same file (... are snips for brevity).
define([
'jquery',
'async',
...,
**'/config/mysettings.js'**
], function ($, async, ..., **mysettings**) {
relevantAjaxFunction: function() {
...
**fail**:
console.log(mysettings.foo);
Produces an undefined message in the console. What's the correct way to reference an application wide settings file like this? I've looked and cannot find anything, which makes me think it's either super obvious or I'm phrasing the question wrong.
Sails doesn't make your config files publicly browsable. That would be...bad.
You have a few options here that I can think of:
Make a symlink inside your assets folder that points to the config file. The tricky part here is that the symlink will be copied as-is into your .tmp/public folder, so if you use a relative path in your symlink, it needs to be the relative path from .tmp/public to config/mysettings.js. Or you could just use an absolute path in the symlink.
Make a custom route that just streams the file using fs:
require('fs')
.createReadStream(sails.config.paths.config+"/mysettings.js")
.pipe(res);
although you should really use the path module for determining the file path, and wrap the whole thing in a try/catch just in case...
Use a policy to add the config settings in a local variable for every request, for example:
module.exports = function myConfigPolicy(req, res, next) {
res.locals.mysettings = sails.config.mysettings;
return next();
}
and in your views/layout.ejs do something like:
<script type="text/javascript">
var mySettings = <%= JSON.stringify(mysettings) %>;
</script>
Adjusting for your template engine of choice. Of course this doesn't use AMD to load the config at runtime, so if that's a concern go with choice #1 or #2!

Configure location of text.js

I'm using requirejs with the text plugin. By default, requirejs assumes text.js lives in your baseUrl. However, I want to keep it somewhere else. Where/how/when do I need to configure requirejs?
To add to shioyama's answer, the .js in the "/absolute/path/to/text.js" is not necessary. It is appended when require.js checks the path:
requirejs.config({
paths: {
"text": "/absolute/path/to/text"
}
});
You can use requirejs's path config for this. From the documentation:
paths: path mappings for module names not found directly under baseUrl. The path settings are assumed to be relative to baseUrl, unless the paths setting starts with a "/" or has a URL protocol in it ("like http:").
So you could do something like this:
requirejs.config({
paths: {
"text": "/absolute/path/to/text.js"
}
});
Then you can use text as a dependency in modules and require.js will know to look for the file in /absolute/path/to/text.js.

Categories

Resources