How do I properly alias a module in RequireJS on Node.js - javascript

I'm using RequireJS on my Node.js server to aid in code re-use. I'm sharing modules between client and server, and therefore I want to keep these modules as general as possible.
The problem is that I have a 3rd party library (easeljs) that provides both a client and a server-side implementation, with the server-side implementation provided by npm as 'node-easel'.
The way I expected to deal with this doesn't work. I provided a paths config for the server side application as follows:
requirejs.config({
nodeRequire: require,
paths: {
'easeljs': 'node-easel'
}
})
The above code will first look for node-easel.js in the root directory, before falling back onto node's require('easeljs'), which is not what I want. I want requireJS to fall back onto require('node-easel'). What would be the best way to accomplish this?

I struggled a little with this myself, but actually was able to use a combination of RequireJS map configuration and a NPM module loader. The code is as follows:
requirejs.config({
paths: {
npm: 'helpers/requirejs/npmloader'
},
map: {
'*': {
dust: 'npm!dustjs-linkedin'
}
}
});
And then for helpers/requirejs/npmloader.js:
define({
normalize: function (name, normalize) {
return name;
},
load: function (name, req, onload, config) {
require(name);
}
});
With this you can easily alias NodeJS modules using RequireJS.
In package.json I also use the following:
"main": "./bin/server.js",
"bin": {
"server.js": "./bin/server.js"
}
With top level bin/server,js being a symbolic link to build/init.js and being executable chmod a+x build/server.js.
Instead of using the amdefine loader, which is rather lacking without the ability to use plugins, I use the full requirejs module with NodeJS, and then I just have define be available globally for all my modules as you can see in the code below.
Then src/init.js (or after building - build/init.js) contains the following which might be a useful example:
#!/usr/bin/env node
/**
* #file The AMD loader module configuration.
* #author runelabs <http://github.com/runelabs>
* #version $Id$
* #description
*
* MODULE 'init' OVERVIEW:
* This defines the init RequireJS configuration module,
* in contrast to other modules which are using the AMD define() pattern.
*
*/
/*global require, define, global*/ // using JShint linter
(function() {
'use strict';
var requirejs, mocha, mainProg;
global.requirejs = global.define = requirejs = require('requirejs');
mainProg = ['main'];
var config = {
deps: mainProg,
paths: {
lib: 'lib/',
tests: '../tests',
app: '.',
config: 'models/config',
packages: 'packages',
logger: 'packages/logger/logger',
pkg: 'helpers/requirejs/pkgloader',
npm: 'helpers/requirejs/npmloader',
text: 'lib/requirejs-text/text'
/* ... more paths */
},
map: {
'*': {
marionette:'npm!backbone.marionette',
dust: 'npm!dustjs-linkedin'
}
}
};
requirejs.config(config);
requirejs.onError = function (err, u, l) {
var LOG = require('./packages/logger/logger');
LOG.error('RequireJS error: ', err.requireType);
LOG.error(' mod: ', err.requireModules);
LOG.error(' map: ', err.requireMap);
if (err.requireType === 'timeout') {
LOG.error(' modules: ', err.requireModules);
}
LOG.error('ERR: ', err);
LOG.error('ERR error: ', err.error);
LOG.error('ERR type: ', typeof err);
if (err['toSource']) {
LOG.error('ERR src: ', err.toSource());
}
LOG.error('ERR name: ', err.name);
LOG.error('ERR message: ', err.message);
LOG.error('ERR file: ', err.fileName);
LOG.error('ERR line: ', err.lineNumber);
LOG.error('ERR col: ', err.columnNumber);
LOG.error('ERR stack: ', err.stack);
throw(err);
};
})();
Hope this helps someone else looking to use RequireJS to load stuff from node_modules.
EDIT: A smaller example is from RequireJS creator James Burke at:
https://groups.google.com/forum/#!msg/requirejs/ur_UQLr04rc/sSpM8y87VNMJ

Related

RequireJS module shim not working when testing via Jasmine

I have a JavaEE project that uses RequireJS to load a few third party frameworks. One of those frameworks is OpenLayers3. Openlayers3 natively creates a global "ol" variable. However, OpenLayers3 is written to be AMD compatible and works as a module through RequireJS. I also am using an OpenLayers3 plugin called "olLayerSwitcher" which is not optimized for AMD. Instead, it depends on the "ol" variable being global.
My require config looks like the following:
paths: {
"sinon": ['/webjars/sinonjs/1.7.3/sinon'],
"jquery": ["/webjars/jquery/2.1.4/jquery"],
"backbone": ['/webjars/backbonejs/1.2.1/backbone'],
"underscore": ['/webjars/underscorejs/1.8.3/underscore'],
"text": ['/webjars/requirejs-text/2.0.14/text'],
"log4js": ['/webjars/log4javascript/1.4.13/log4javascript'],
"ol": ['/webjars/openlayers/3.5.0/ol'],
"olLayerSwitcher": ['/js/vendor/ol3-layerswitcher/1.0.1/ol3-layerswitcher']
},
shim: {
"olLayerSwitcher": {
deps: ["ol"],
exports: "olLayerSwitcher"
},
'sinon' : {
'exports' : 'sinon'
}
}
The project is uses Backbone and includes a Router module (/src/main/webapp/js/controller/AppRouter.js):
/*jslint browser : true*/
/*global Backbone*/
define([
'backbone',
'utils/logger',
'views/MapView'
], function (Backbone, logger, MapView) {
"use strict";
var applicationRouter = Backbone.Router.extend({
routes: {
'': 'mapView'
},
initialize: function () {
this.LOG = logger.init();
this.on("route:mapView", function () {
this.LOG.trace("Routing to map view");
new MapView({
mapDivId: 'map-container'
});
});
}
});
return applicationRouter;
});
The Router module depends on a View module (/src/main/webapp/js/views/MapView.js):
/*jslint browser: true */
define([
'backbone',
'utils/logger',
'ol',
'utils/mapUtils',
'olLayerSwitcher'
], function (Backbone, logger, ol, mapUtils, olLayerSwitcher) {
"use strict";
[...]
initialize: function (options) {
this.LOG = logger.init();
this.mapDivId = options.mapDivId;
this.map = new ol.Map({
[...]
controls: ol.control.defaults().extend([
new ol.control.ScaleLine(),
new ol.control.LayerSwitcher({
tipLabel: 'Switch base layers'
})
])
});
Backbone.View.prototype.initialize.apply(this, arguments);
this.render();
this.LOG.debug("Map View rendered");
}
});
return view;
});
The View module attempts to pull in both OpenLayers3 as well as the third-party OpenLayers plugin.
When the project is built and deployed, it works fine in-browser. When the View module is loaded, OpenLayers and the third-party plugin are pulled in just fine and everything renders properly.
However, when I attempt to test this in Jasmine is where all of this falls apart.
For Jasmine, I am using the Jasmine-Maven plugin. It pulls in JasmineJS, PhantomJS and RequireJS along with my libraries and runs my specs. The issue is that when run via Jasmine, the MapView module attempts to load both the OpenLayers3 library as well as the third party plugin (olLayerSwitcher) but fails because the third party plugin can't find "ol".
The test:
define([
"backbone",
"sinon",
'controller/AppRouter'
], function (Backbone, sinon, Router) {
describe("Router", function () {
beforeEach(function () {
this.router = new Router();
this.routeSpy = sinon.spy();
this.router.bind("route:mapView", this.routeSpy);
try {
Backbone.history.start({silent: true});
} catch (e) {
}
this.router.navigate("elsewhere");
});
it("does not fire for unknown paths", function () {
this.router.navigate("unknown", true);
expect(this.routeSpy.notCalled).toBeTruthy();
});
it("fires the default root with a blank hash", function () {
this.router.navigate("", true);
expect(this.routeSpy.calledOnce).toBeTruthy();
expect(this.routeSpy.calledWith(null)).toBeTruthy();
});
});
});
The error from Jasmine:
[ERROR - 2015-08-08T21:27:30.693Z] Session [4610ead0-3e14-11e5-bb2b-dd2c4b5c2c7b] - page.onError - msg: ReferenceError: Can't find variable: ol
:262 in error
[ERROR - 2015-08-08T21:27:30.694Z] Session [4610ead0-3e14-11e5-bb2b-dd2c4b5c2c7b] - page.onError - stack:
global code (http://localhost:58309/js/vendor/ol3- layerswitcher/1.0.1/ol3-layerswitcher.js:9)
:262 in error
JavaScript Console Errors:
* ReferenceError: Can't find variable: ol
The relevant section from the ol3-layerswitcher plugin on line 9 is:
[...]
ol.control.LayerSwitcher = function(opt_options) {
[...]
So it does depend on "ol" being a thing at this point.
The Jasmine-Maven plugin creates its own spec runner HTML and the relevant portion looks like this:
<script type="text/javascript">
if(window.location.href.indexOf("ManualSpecRunner.html") !== -1) {
document.body.appendChild(document.createTextNode("Warning: Opening this HTML file directly from the file system is deprecated. You should instead try running `mvn jasmine:bdd` from the command line, and then visit `http://localhost:8234` in your browser. "))
}
var specs = ['spec/controller/AppRouterSpec.js'];
var configuration = {
paths: {
"sinon": ['/webjars/sinonjs/1.7.3/sinon'],
"jquery": ["/webjars/jquery/2.1.4/jquery"],
"backbone": ['/webjars/backbonejs/1.2.1/backbone'],
"underscore": ['/webjars/underscorejs/1.8.3/underscore'],
"text": ['/webjars/requirejs-text/2.0.14/text'],
"log4js": ['/webjars/log4javascript/1.4.13/log4javascript'],
"ol": ['/webjars/openlayers/3.5.0/ol'],
"olLayerSwitcher": ['/js/vendor/ol3-layerswitcher/1.0.1/ol3-layerswitcher']
},
shim: {
"olLayerSwitcher": {
deps: ["ol"],
exports: "olLayerSwitcher"
},
'sinon' : {
'exports' : 'sinon'
}
}
};
if (!configuration.baseUrl) {
configuration.baseUrl = 'js';
}
if (!configuration.paths) {
configuration.paths = {};
}
if (!configuration.paths.specs) {
var specDir = 'spec';
if (!specDir.match(/^file/)) {
specDir = '/'+specDir;
}
configuration.paths.specs = specDir;
}
require.config(configuration);
require(specs, function() {
jasmine.boot();
});
I am able to create a customer HTML runner but am not sure what the problem is so I wouldn't know what needs changing.
This doesn't seem to be a PhantomJS issue as I can load the tests in-browser and am experiencing the same issue.
I'd appreciate if anyone has any thoughts on what could be happening here. I really do not want to hack up the third-party module to transform it into a RequireJS module as the Jasmine testing is the last-leg of implementing this completely and I'm completely stuck here.
I am using Jasmine 2.3.0 and RequireJS 2.1.18
I apologize for not linking out more but this is a new account and I don't have enough rep for it.
It will be tough to figure out the problem without a running version of your setup.
However, if you're able to customize the SpecRunner.html for jasmine generated by the maven plugin, simply include the jasmine(/ any other library causing an issue) in the SpecRunner html - <script src="/<path_to_lib>">.
In my experience, its usually not worth the effort , to make libraries used in source amd compliant and play nicely with every other library for testing setup.

Unit Testing Angular + Browserify + Gulp and Jasmine

I'm having an angular project bundled with browserify using Gulp. Here is the tree
|--app
|--src
--js
-main.js
-otherFiles.js
|--spec
--mainspec.js <-- jasmin spec file
|--public
--js
--main.js
I'm having a gulp file which takes my source, main.js file, and browserifies it along with a gulp-jasmine tasks
gulp.task('js', function() {
return gulp.src('src/js/main.js')
.pipe(browserify({}))
.pipe(gulp.dest('public/js'));
});
gulp.task('specs', function () {
return gulp.src('spec/*.js')
.pipe(jasmine());
});
Along with some watch tasks etc.
Now, in my mainspec.js file, angular is not recognized, considering my test code:
describe("An Angular App", function() {
it("should actually have angular defined", function() {
expect(angular).toBeDefined();
});
});
And I'm getting an ReferenceError: angular is not defined error on terminal. I tried to require('angular'); on the first line but with no luck, getting a new error ReferenceError: window is not defined. I know there is something wrong with the setup and the test file not being able to reach the browserified files, but I can't just figure out the solution.
Any ideas?
Thanks in advance.
You need to define all aspects in your config file
function getKarmaConfig(environment) {
return {
frameworks : ['jasmine'],
files : [
// Angular + translate specified for build order
environment + '/js/jquery.min.js',
environment + '/js/angular.js',
environment + '/js/angular-translate.min.js',
environment + '/js/**/*.js',
'bower_components/angular-mocks/angular-mocks.js',
'test/unit/**/*.js'
],
exclude : [
],
browsers : ['PhantomJS'],
reporters : ['dots', 'junit','coverage'],
junitReporter: {
outputFile: 'test-results.xml'
},
preprocessors : {
'prod/js/*.js': ['coverage']
},
coverageReporter:{
type: 'html',
dir: 'coverage'
}
};
};
and define a gulp test task like this
gulp.task('test', ['build_prod'], function () {
var testKarma = getKarmaConfig(environment);
testKarma.action = 'run';
testKarma.browsers = ['PhantomJS'];
return gulp.src('./fake')
.pipe(karma(testKarma));
});
You just need to define src perfectly as per your structure. This will work :)

RequireJS load only concatenated file

I'm using RequireJS (version 2.1.14) and would like to concatenate my JavaScript files into one single app-built.js.
I've created a little node module which reads my app.js, extracts the project paths and gets executed once I run node build in the js directory of my application.
The node module (build.js):
var fs = require('fs'),
path = require('path'),
directory = __dirname + path.sep,
requirejs = require(directory + 'vendor/r.js');
fs.readFile(directory + 'app.js', 'utf8', function(err, data) {
if (err) {
console.log('Error: ' + err);
return
} else {
data = data.replace(/'/g, '"').replace(/\s+/g, '');
var paths = data.substr(data.indexOf('{'), data.indexOf('}')),
paths = paths.substr(0, paths.indexOf('}') + 1),
paths = JSON.parse(paths);
createAppBuilt(paths);
}
});
function createAppBuilt(paths) {
var config = {
baseUrl: __dirname,
paths: paths,
name: 'app',
out: 'app-built.js',
preserveLicenseComments: false,
findNestedDependencies: true,
removeCombined: true
};
requirejs.optimize(config, function(buildResponse) {
var contents = fs.readFileSync(config.out, 'utf8');
console.log('Created app-built.js');
}, function(err) {
console.log('Error: ' + err);
return;
});
}
app.js:
var paths = {
'jquery': 'vendor/jquery-1.11.0.min',
// other paths
};
// Set language, necessary for validtaion plugin -> validation.js
if (Modernizr.localstorage) {
localStorage.getItem('language') || localStorage.setItem('language', navigator.language || navigator.userLanguage);
}
requirejs.config({
paths: paths,
shim: {
touchswipe: {
deps: ['jquery']
},
icheck: {
deps: ['jquery']
},
validate: {
deps: ['jquery']
},
mask: {
deps: ['jquery']
},
chosenImage: {
deps: ['jquery', 'chosen']
},
cookie: {
deps: ['jquery']
}
}
});
require(['globals', 'jquery', 'underscore'], function() {
var initial = ['main'];
if (!Modernizr.localstorage) {
initial.push('cookie');
}
require(initial, function(Main) {
$(function() {
if (!Modernizr.localstorage) {
$.cookie.json = true;
}
Main.init();
});
});
});
The app-built.js gets generated but when I include it in my index.php all the other modules get loaded as well. How can I prevent the loading of all modules and only load the app-built.js?
I recommend you look into http://webpack.github.io/
or http://browserify.org/ as these solve this problem for you.
They allow you to use require much as before, yet the code is compiled/concatenated into a single file.
Webpack allows for a bit more flexibility in loading different chunks of code for different parts of your site, but Browserify is the most well-known so far.
There may be a cost in switching over to these, as I don't think that they're 100% compatible requirejs, however they bring great advantages.
Here's someone's journey from RequireJS to Browserify with some Pros and Cons.
Separate modules into different files, e.g. app-built.js, user-built.js. Then load script when it's needed.
Here's a demo: http://plnkr.co/edit/s6hUOEHjRbDhtGxaagdR?p=preview .
When page loaded, requirejs only loads global.js. After clicking the Change Color button, requirejs starts to load colorfy.js and random-color.js, which required by colorfy.js.
I am not sure about the exact details, but, yet if you don't have an exports option, r.js doesn't define a named module for you, that causes to actually load the script.
I assume you have jquery plugins there so add this extra exports option:
shim: {
touchswipe: {
deps: ['jquery'],
exports: 'jQuery.fn.touchswipe'
},
This should force r.js to build a named module for touchswipe:
define("touchswipe", (function (global) {
return function () {
var ret, fn;
return ret || global.jQuery.fn.touchswipe;
};
}(this)));
Note that, exports option might not build this named module, in that case your best bet is to include this manually.
Again I am not sure about why and how this happens, It must be a bug in requirejs, it's unlikely there is a tweak for this.
Changing the r.js optimizer (to uglify2) solved the problem for me:
var config = {
baseUrl: __dirname,
paths: paths,
name: 'app',
out: 'app-built.js',
findNestedDependencies: true,
preserveLicenseComments: false,
removeCombined: true,
optimize: 'uglify2'
};

Loader requireJs doesn't respect dependencies

I use requireJs to load my javascript files.
I import the lib pixi.js and pixi_extends.js, but pixi_extends generate an error because PIXI is undefined... I don't understand because pixi_extends should wait that pixi.js is uploaded before run.
It's the same with the Bundle, same error about pixi.
I don't understant, I did the "deps" correctly I assume!
loader-index.ts: (I use TypeScript!)
/// <reference path="../def/require.d.ts" />
/// <reference path="Init.class.ts" />
/**
* paths List of the files to load. (Cannot contains references TS classes)
* key: New reference name of the file.
* path: Relative path to /public/js/ of the file.
*
* shim Config about the libraries (dependencies and more).
* See http://requirejs.org/docs/api.html#config-shim
*/
require.config({
//urlArgs: "t=" + (new Date()).getTime(),
//baseUrl: "../",
paths: {
/*
******** Load libraries ********
*/
// Lib - jQuery
'jquery': '../generated/lib/jquery-1.10.2.min',
'jqueryUiCore': '../generated/lib/jquery.ui.core.min',
'jqueryUiEffect': '../generated/lib/jquery.ui.effect.min',
// Lib - Javascript extends
'class': '../generated/lib/class.min',
// Lib - Pixi
'pixi': '../generated/lib/pixi.min',
'pixiExtends': '../generated/lib/pixi_extends.min',
// Lib - Socket
'socketIo': '../generated/lib/socket.io.min',
// Lib - Pomelo
'pomeloclient': '../generated/lib/pomeloclient.min',
// Lib - Path finder
'aStar': '../generated/lib/AStar.min',
/*
******** Load shared source code ********
*/
'Message': '../generated/shared/Message.min',
'ValidatorMessage': '../generated/shared/ValidatorMessage.min',
/*
******** Load other scripts ********
*/
'bundle': '../generated/bundle.min'
},
shim: {
'jquery': {
exports: '$'
},
'jqueryUiCore': {
deps: ["jquery"],
exports: '$'
},
'jqueryUiEffect': {
deps: ["jquery"],
exports: "$"
},
'pixiExtends': {
deps: ["jquery", "pixi"]
},
'pomeloclient': {
deps: ["socketIo"]
},
'ValidatorMessage': {
deps: ["Message"]
},
'bundle': {
deps: ["pixi", "pixiExtends", "pomeloclient"]
}
}
});
/**
* [] Array of name that should be the same than those defined in the config.paths. Exception for the TS classes with reference in this file.
*/
require(
[
'Init.class',
'jquery', 'jqueryUiCore', 'jqueryUiEffect',
'class',
'pixi', 'pixiExtends',
'socketIo', 'pomeloclient',
'aStar',
'Message', 'ValidatorMessage',
'bundle'
],
(
_init,
$, jqueryUiCore, jqueryUiEffect,
_class,
_pixi, pixiExtends,
_socketIo, _pomeloclient,
_aStar,
_message, _validatorMessage,
_bundle
)
=> {
// Initialization.
var init = new _init.Init();
// Make shared source classes public, to help.
_exports([
_message.Message,
_validatorMessage.ValidatorMessage
]);
/**
* Export an array of object to made them public on the browser.
* #param objects - Array of objects. Class of function basically.
* #private
*/
function _exports(objects){
for(var i in objects){
_export(objects[i]);
}
}
/**
*Export an object to the browser to make it public.
* #param o Object to export.
* #param name Customise the name. Optional.
* #private
*/
function _export(o: any, name: any = ''){
if(!name){
name = o.name;
}
window[name] = o;
}
}
);
It should be enough to add the following entry to the shim section:
'pixi': {
exports: 'PIXI'
}
This turns this library into an AMD-compatibile module which can be used as a standalone dependency, also in the deps section of other shims.
Edit:
Reading your comments seems that this "pixi_extends" module is your own code; you're not supposed to shim your own modules, it's only meant to be used for legacy non-AMD libraries. If you want to augment Pixi with your customisations, do something like this:
define(['pixi'], function (ThePixiObject) {
ThePixiObject.customFunction = function () {
console.log('Pixi now has customFunction()');
}
// no need to return anything - we're only interested in the side-effect above
});
Recommended: official documentation regarding shim
NB. Also, there's no need to configure shim for jQuery, it's already AMD compatibile.
I fixed it with using the require() function in the pixi_extends and removing my changes from the official pixi.js lib. Now that works.
But the exports with requirejs doesn't have any effect, I don't get it. That should export in global the PIXI value, it's what that should do and that doesn't work.
I can export it manually once everything is loaded, it's a solution if I wanted to have PIXI as global. But I don't absolutely need it so I'll keep in this way.
But I would like to understand why the "shim exports" doesn't works.

Configuring modules with RequireJS when config depends on RequireJS

Apologies if I have missed this in the docs. Basically I want to use the RequireJS module configuration feature. I would like to centrally manage the config values given to modules in a package.
This is an example from the docs:
requirejs.config({
config: {
'bar': {
size: 'large'
},
'baz': {
color: 'blue'
}
}
});
//bar.js, which uses simplified CJS wrapping:
define(function (require, exports, module) {
//Will be the value 'large'
var size = module.config().size;
});
//baz.js which uses a dependency array,
define(['module'], function (module) {
//Will be the value 'blue'
var color = module.config().color;
});
My problem is that my configuration info will be a little more complex, and will itself have dependencies. I would like to do:
requirejs.config({
config: {
'bar': {
path: path.dirname(module.uri)
key: crypto.randomBytes(64)
},
}
});
Where variables in my config need to use requireJS to evaluate.
To me it would make sense for there to be a logical separation between the RequireJS configuration - the config necessary to load modules - and the user's module configuration. But I am currently struggling to find this :(
For this sort of solution, I would have the module depend on a "config" module that you can swap for a different one using paths config. So if "bar" needed some config, "bar.js" would look like:
define(['barConfig'], function (config) {
});
Then barConfig.js could have your other dependencies:
define(['crypto'], function (crypto) {
return {
key: crypto.randomBytes(64)
}
});
Then, if you needed different configs for say, production vs. dev, use paths config to map barConfig to other values:
requirejs.config({
paths: {
barConfig: 'barConfig-prod'
}
});
I think the proper way to do this is to make a config module...
// config.js
define(['module', 'path', 'crypto'], function(module, path, crypto) {
return {
path: path.dirname(module.uri)
key: crypto.randomBytes(64)
};
});
Then use it in other modules...
// bar.js
define(['config'], function (config) {
var key = config.key;
});
You can then make it as complicated as you like!
EDIT: You could pollute the global namespace for this special class...
define(['module', 'path', 'crypto'], function(module, path, crypto) {
window.config = {
path: path.dirname(module.uri)
key: crypto.randomBytes(64)
};
});
Add it to the top level require call:
require(['config', 'main']);
Then you can use it without always adding it to your define:
// bar.js
define([], function() {
var key = config.key;
});
Having thought about this a little more I have come up with a workaround. It is not particularly pretty but it does seem to work.
I simply do requireJS(...) twice, first to create the config, and second to load the application modules with the config..
requireJSConfig =
baseUrl: __dirname
nodeRequire: require
# Create the require function with basic config
requireJS = require('requirejs').config(requireJSConfig)
requireJS ['module', 'node.extend', 'crypto', 'path'], (module, extend, crypto, path) ->
# Application configuration
appConfig =
'bar':
path: path.dirname(module.uri)
key: crypto.randomBytes(64) # for doing cookie encryption
# get a new requireJS function with CONFIG data
requireJS = require('requirejs').config(extend(requireJSConfig, config: appConfig))
requireJS ['bar'], (app) ->
###
Load and start the server
###
appServer = new app()
# And start the app on that interface (and port).
appServer.start()
And in bar.coffee
# bar.coffee
define ['module'], (module) ->
# config is now available in this module
console.log(module.config().key)
Riffing on what #jrburke is saying, I found the following pattern to be quite useful: define a config module and it's dependencies in the main.js just before the invocation of require.config().
main.js
define('config', ['crypto'], function (crypto) {
return {
'bar': {
key: crypto.randomBytes(64)
},
};
});
requirejs.config({
deps: ['app'],
});
app.js
require(['config'], function (config){
// outputs value of: crypto.bar.key
console.log(config.bar.key);
});
Plnkr Demo: http://plnkr.co/edit/I35bEgaazEAMD0u4cNuj

Categories

Resources