How to get a single javascript page using r.js - requirejs

I am doing my first try using requireJS and it works great !
I now would like to use the optimizer and i meet some issues when running my code in the browser.
I have these JS files:
/public/javascripts/build.js
/public/javascripts/main.js
/public/javascripts/lib/jquery.min.js
/public/javascripts/lib/require.min.js
/public/javascripts/a.js
/public/javascripts/b.js
/public/javascripts/c.js
a.js, b.js and c.js are modules i define for my application using requireJS.
main.js:
require.config({
paths: {
'jQuery': 'lib/jquery.min.js'
},
shim: {
'jQuery': {
exports: '$'
}
}
});
require(['a.js'], function(A){
var Entity = new A();
});
build.js
({
baseUrl: ".",
paths: {
requireLib: "lib/require.min",
jquery: "lib/jquery.min"
},
name: "main",
out: "main-built.js",
include: ["requireLib"]
})
Also i am wondering why do we have to specify the paths of the libraries into the build.js and not the other javascript files.
When i do not use the optimizer and only load the file
<script src="/javascripts/lib/require.min.js" data-main="/javascripts/main"></script>
it works great, but when i run r.js -o ./public/javascripts/build.js and only load
<script src="/javascripts/main-built.js"></script> i get the error Uncaught TypeError: undefined is not a function in the minified code.
How to explain that ?
Here are the logs i get when running r.js
Tracing dependencies for: main
Uglifying file: /public/javascripts/main-built.js
/public/javascripts/main-built.js
----------------
/public/javascripts/lib/require.min.js
/public/javascripts/a.js
/public/javascripts/b.js
/public/javascripts/lib/jquery.min.js
/public/javascripts/c.js
/public/javascripts/main.js

This is definitely wrong:
require(['a.js'], function(A){
var Entity = new A();
});
You should not use extensions in the list of dependencies you give to require or define. Modules should be named without extension. So here 'a', not 'a.js'. Using 'a.js' will cause RequireJS to fail loading what you really want once the optimizer has run. Let's say you have a file named a.js which has:
define(function () {
return function () {};
});
The optimizer will include it into your main-built.js file like this:
define("a", function () {
return function () {};
});
Note how the first parameter to define is now "a". This has been added by r.js. This is the name of the module. When you load main-built.js, a module named "a" is defined. When you use require with "a.js", you are telling RequireJS you want something in a file named a.js so RequireJS will go looking for that and ignore what is in main-built.js.
Also, jQuery 1.8 or over does not need a shim.

I just have added
shim: {
'jQuery': {
exports: '$'
}
}
into the build.js file, and it works perfectly !
Thanks !

Related

requirejs callback undefined

Project Structure
root
wwwroot <-- files under this location are static files public to the site
css
lib
bootstrap/js/bootstrap.js
jquery/js/jquery.js
knockout/knockout.js
requires/require.js
scripts
modules ┌───────────────┐
global.js <--│ Built modules │
dropdown.js └───────────────┘
modules
global.js ┌────────────────┐
dropdown <--│ Source modules │
dropdown.js └────────────────┘
gruntfile.js
global.cs Contents (pre-built version at ~/modules/global.js)
require.config({
baseUrl: "scripts/modules",
paths: {
jquery: "../../lib/jquery/js/jquery",
bootstrap: "../../lib/bootstrap/js/bootstrap",
knockout: "../../lib/knockout/knockout"
},
shims: {
bootstrap: {
deps: ['jquery']
}
},
});
define(function (require) {
var $ = require('jquery');
var ko = require('knockout');
var bootstrap = require('bootstrap');
});
dropdown.js Contents (pre-built version at ~/modules/dropdown.js)
define(function () {
console.log('dropdown initialized');
return 'foo';
});
HTML Page
Contains this script tag in the <head> of the page for loading requires config:
<script src="~/lib/requirejs/require.js" data-main="scripts/modules/global"></script>
In the body of the HTML page, I have the following:
<script>
require(['global'], function () {
require(['dropdown'], function (dropdown) {
console.log(dropdown);
});
});
</script>
Issue
The dropdown callback is undefined instead of the expected "foo" string that I'm returning from the defined module.
In fact, the console does not contain a log item for "dropdown initialized" either. This makes me believe the module is not being invoked somehow? However, it's strange the dropdown.js is present in F12 debugger as a script loaded into the page. Therefore, requires did make a call to load it, but did not run the contents of the define?
Noteworthy mentions
I'm using r.js to optimize and build. Both global.js and dropdown.js are processed over.
The name assigned to the dropdown module by r.js processing is "modules/dropdown/dropdown.js". I'm unsure if I should be using this somehow, or if I'm referring to the module correctly as just dropdown and relying on my baseUrl config having the correct path.
Edit #1
I have added the r.js build configuration used with grunt per commenter request. In conjunction, I updated the file structure to include the overall project structure, instead of just the runtime public wwwroot structure.
The r.js process will compile built forms of global.js + other modules in ~/wwwroot/scripts/modules from the source location ~/modules in summary.
function getRequireJsConfiguration() {
var baseUrl = './';
var paths = {
jquery: "wwwroot/lib/jquery/js/jquery",
bootstrap: "wwwroot/lib/bootstrap/js/bootstrap",
knockout: "wwwroot/lib/knockout/knockout"
};
var shims = {
bootstrap: {
deps: ['jquery']
}
};
var optimize = 'none';
var configuration = {};
var jsFilePaths = grunt.file.expand('modules/**/*.js');
jsFilePaths.forEach(function (jsFilePath) {
var fileName = jsFilePath.split('/').pop();
if (configuration[fileName]) {
throw 'Duplicate module name conflict: ' + fileName;
}
configuration[fileName] = {
options: {
baseUrl: './',
name: jsFilePath,
out: 'wwwroot/scripts/modules/' + fileName,
paths: paths,
shims: shims,
optimize: optimize,
exclude: ['jquery', 'knockout', 'bootstrap']
}
};
});
configuration['global'] = {
options: {
baseUrl: './',
name: 'modules/global.js',
out: 'wwwroot/scripts/modules/global.js',
paths: paths,
shims: shims,
optimize: optimize,
}
};
return configuration;
}
Edit #2
Thought it'd be a good idea to include the versions of requirejs packages I'm using:
requirejs: 2.1.15
grunt-contrib-requirejs: 0.4.4
Thanks.
The name assigned to the dropdown module by r.js processing is "modules/dropdown/dropdown.js". I'm unsure if I should be using this somehow, or if I'm referring to the module correctly as just dropdown and relying on my baseUrl config having the correct path.
In a sense, yes, you should be using that full path. That's what Require refers to as the module id - "modules/dropdown/dropdown" (if the .js in the above output was real, I suggest stripping that extension in the "name" config. .js is assumed by RequireJS, you don't want that string in your module ids). The basePath is used, when given IDs, to transform some unknown ID to a file path (e.g. 'bootstrap' id -> (applying path config) -> '../../lib/bootstrap/js/bootstrap' -> (applying base URL) -> 'scripts/modules/../../lib/bootstrap/js/bootstrap').
Really, though, just allowing r.js to concatenate everything into one file
is the preferred way to go. You could use the include option to include modules un-referenced by global.js in with the optimized bundle, too ( https://github.com/jrburke/r.js/blob/master/build/example.build.js#L438 )
As to your specific problem: your lazy require(['dropdown']) call is misleading you. By combining the requested module id with the basePath, RequireJS comes up with the URL you want - scripts/modules/dropdown - which defines a module with the module id scripts/module/dropdown - but since you requested the module id dropdown, you get nothing. (I would've guessed you'd get a RuntimeError instead of undefined, but I suppose that's how things go). One way or another you need to address the id/path mismatches.
Although I have resolved my issue with the hints wyantb's answer provided, I've since changed my approach to a single file concat due to the simplicity it brings. I still wanted to post the specifics of how I solved this question's issue for anyone else to happens along it.
In the grunt build configuration options, I added the onBuildWrite field to transform the content, so my assigned module IDs lined up with how I was lazily loading them.
onBuildWrite: function (moduleName, path, contents) {
return contents.replace(/modules\/global.js/, 'global');
}
This code is specifically for the global.js file. I implemented a similar onBuildWrite for the other module files (in the foreach loop). The transformation will essentially strip the path and extension from the module name that r.js assigns.
Here are some examples of before and after:
Before After
/modules/global.js global
/modules/dropdown/dropdown.js dropdown
/modules/loginButton/loginButton.js loginButton
Therefore, when I load the modules using the HTML script from my original question, requirejs resolves and finds a match.
Either require by path or define global and dropdown in global.cs
require(['./global'], function () {
require(['./dropdown'], function (dropdown) {
console.log(dropdown);
});
});

Using Gulp to build requireJS project - gulp-requirejs

I am trying to use gulp-requirejs to build a demo project. I expect result to be a single file with all js dependencies and template included. Here is my gulpfile.js
var gulp = require('gulp');
var rjs = require('gulp-requirejs');
var paths = {
scripts: ['app/**/*.js'],
images: 'app/img/**/*'
};
gulp.task('requirejsBuild', function() {
rjs({
name: 'main',
baseUrl: './app',
out: 'result.js'
})
.pipe(gulp.dest('app/dist'));
});
// The default task (called when you run `gulp` from cli)
gulp.task('default', ['requirejsBuild']);
The above build file works with no error, but the result.js only contains the content of main.js and config.js. All the view files, jquery, underscore, backbone is not included.
How can I configure gulp-requirejs to put every js template into one js file?
If it is not the right way to go, can you please suggest other method?
Edit
config.js
require.config({
paths: {
"almond": "/bower_components/almond/almond",
"underscore": "/bower_components/lodash/dist/lodash.underscore",
"jquery": "/bower_components/jquery/dist/jquery",
"backbone": "/bower_components/backbone/backbone",
"text":"/bower_components/requirejs-text/text",
"book": "./model-book"
}
});
main.js
// Break out the application running from the configuration definition to
// assist with testing.
require(["config"], function() {
// Kick off the application.
require(["app", "router"], function(app, Router) {
// Define your master router on the application namespace and trigger all
// navigation from this instance.
app.router = new Router();
// Trigger the initial route and enable HTML5 History API support, set the
// root folder to '/' by default. Change in app.js.
Backbone.history.start({ pushState: false, root: '/' });
});
});
The output is just a combination this two files, which is not what I expected.
gulp-requirejs has been blacklisted by the gulp folks. They see the RequireJS optimizer as its own build system, incompatible with gulp. I don't know much about that, but I did find an alternative in amd-optimize that worked for me.
npm install amd-optimize --save-dev
Then in your gulpfile:
var amdOptimize = require('amd-optimize');
var concat = require('gulp-concat');
gulp.task('bundle', function ()
{
return gulp.src('**/*.js')
.pipe(amdOptimize('main'))
.pipe(concat('main-bundle.js'))
.pipe(gulp.dest('dist'));
});
The output of amdOptimize is a stream which contains the dependencies of the primary module (main in the above example) in an order that resolves correctly when loaded. These files are then concatenated together via concat into a single file main-bundle.js before being written into the dist folder.
You could also minify this file and perform other transformations as needed.
As an aside, in my case I was compiling TypeScript into AMD modules for bundling. Thinking this through further I realized that when bundling everything I don't need the asynchronous loading provided by AMD/RequireJS. I am going to experiment with having TypeScript compile CommonJS modules instead, then bundling them using webpack or browserify, both of which seem to have good support within gulp.
UPDATE
My previous answer always reported taskReady even if requirejs reported an error. I reconsidered this approach and added error logging. Also I try to fail the build completely as described here gulp-jshint: How to fail the build? because a silent fail really eats your time.
See updated code below.
Drew's comment about blacklist was very helpfull and gulp folks suggest using requirejs directly. So I post my direct requirejs solution:
var DIST = './dist';
var requirejs = require('requirejs');
var requirejsConfig = require('./requireConfig.js').RJSConfig;
gulp.task('requirejs', function (taskReady) {
requirejsConfig.name = 'index';
requirejsConfig.out = DIST + 'app.js';
requirejsConfig.optimize = 'uglify';
requirejs.optimize(requirejsConfig, function () {
taskReady();
}, function (error) {
console.error('requirejs task failed', JSON.stringify(error))
process.exit(1);
});
});
The file at ./dist/app.js is built and uglified. And this way gulp will know when require has finished building. So the task can be used as a dependency.
My solution works like this:
./client/js/main.js:
require.config({
paths: {
jquery: "../vendor/jquery/dist/jquery",
...
},
shim: {
...
}
});
define(["jquery"], function($) {
console.log($);
});
./gulpfile.js:
var gulp = require('gulp'),
....
amdOptimize = require("amd-optimize"),
concat = require('gulp-concat'),
...
gulp.task('scripts', function(cb) {
var js = gulp.src(path.scripts + '.js')
.pipe(cached('scripts'))
.pipe(jshint())
.pipe(jshint.reporter('default'))
.pipe(remember('scripts'))
.pipe(amdOptimize("main",
{
name: "main",
configFile: "./client/js/main.js",
baseUrl: './client/js'
}
))
.pipe(concat('main.js'));
.pipe(gulp.dest(path.destScripts));
}
...
This part was important:
configFile: "./client/js/main.js",
baseUrl: './client/js'
This allowed me to keep my configuration in one place. Otherwise I was having to duplicate my paths and shims into gulpfile.js.
This works for me. I seems that one ought to add in uglification etc via gulp if desired. .pipe(uglify()) ...
Currently I have to duplicate the config in main.js to run asynchronously.
....
var amdOptimize = require("amd-optimize");
...
var js = gulp.src(path.scripts + '.js')
.pipe(cached('scripts'))
.pipe(jshint())
.pipe(jshint.reporter('default'))
.pipe(remember('scripts'))
.pipe(amdOptimize("main",
{
name: "main",
paths: {
jquery: "client/vendor/jquery/dist/jquery",
jqueryColor: "client/vendor/jquery-color/jquery.color",
bootstrap: "client/vendor/bootstrap/dist/js/bootstrap",
underscore: "client/vendor/underscore-amd/underscore"
},
shim: {
jqueryColor : {
deps: ["jquery"]
},
bootstrap: {
deps: ["jquery"]
},
app: {
deps: ["bootstrap", "jqueryColor", "jquery"]
}
}
}
))
.pipe(concat('main.js'));
Try this code in your gulpfile:
// Node modules
var
fs = require('fs'),
vm = require('vm'),
merge = require('deeply');
// Gulp and plugins
var
gulp = require('gulp'),
gulprjs= require('gulp-requirejs-bundler');
// Config
var
requireJsRuntimeConfig = vm.runInNewContext(fs.readFileSync('app/config.js') + '; require;'),
requireJsOptimizerConfig = merge(requireJsRuntimeConfig, {
name: 'main',
baseUrl: './app',
out: 'result.js',
paths: {
requireLib: 'bower_modules/requirejs/require'
},
insertRequire: ['main'],
// aliases from config.js - libs will be included to result.js
include: [
'requireLib',
"almond",
"underscore",
"jquery",
"backbone",
"text",
"book"
]
});
gulp.task('requirejsBuild', ['component-scripts', 'external-scripts'], function (cb) {
return gulprjs(requireJsOptimizerConfig)
.pipe(gulp.dest('app/dist'));
});
Sorry for my english. This solution works for me. (I used gulp-requirejs at my job)
I think you've forgotten to set mainConfigFile in your gulpfile.js. So, this code will be work
gulp.task('requirejsBuild', function() {
rjs({
name: 'main',
mainConfigFile: 'path_to_config/config.js',
baseUrl: './app',
out: 'result.js'
})
.pipe(gulp.dest('app/dist'));
});
In addition, I think when you run that task in gulp, require can not find its config file and
This is not gulp-requirejs fault.
The reason why only main.js and config.js is in the output is because you're not requiring/defining any other files. Without doing so, the require optimizer wont understand which files to add, the paths in your config-file isn't a way to require them!
For example you could load a main.js file from your config file and in main define all your files (not optimal but just a an example).
In the bottom of your config-file:
// Load the main app module to start the app
requirejs(["main"]);
The main.js-file: (just adding jquery to show the technique.
define(["jquery"], function($) {});
I might also recommend gulp-requirejs-optimize instead, mainly because it adds the minification/obfuscation functions gulp-requirejs lacks: https://github.com/jlouns/gulp-requirejs-optimize
How to implement it:
var requirejsOptimize = require('gulp-requirejs-optimize');
gulp.task('requirejsoptimize', function () {
return gulp.src('src/js/require.config.js')
.pipe(requirejsOptimize(function(file) {
return {
baseUrl: "src/js",
mainConfigFile: 'src/js/require.config.js',
paths: {
requireLib: "vendor/require/require"
},
include: "requireLib",
name: "require.config",
out: "dist/js/bundle2.js"
};
})).pipe(gulp.dest(''));
});

How do you setup a require.js config with typescript?

Ok, I've been reading a lot of questions and answers about this, and a lot of it is rubbish.
I have a very simple question. How do I do the equivalent of this:
require.config({
paths: {
"blah": '/libs/blah/blah',
}
});
require(['blah'], function(b) {
console.log(b);
});
In typescript?
This doesn't work:
declare var require;
require.config({
paths: {
"blah": '/libs/blah/blah',
}
});
import b = require('blah');
console.log(b);
s.ts(8,1): error TS2071: Unable to resolve external module ''blah''.
s.ts(8,1): error TS2072: Module cannot be aliased to a non-module type.
error TS5037: Cannot compile external modules unless the '--module' flag is provided.
Compiling with the --module flag, with a dummy blah.ts shim compiles, but the output is:
define(["require", "exports", 'blah'], function(require, exports, b) {
require.config({
paths: {
"blah": '/libs/blah/blah'
}
});
console.log(b);
});
Looks like it might work, but actually no, the require.config is inside the require block, it is set after it is already needed.
SO! I've ended up so far with this as a solution:
class RequireJS {
private _r:any = window['require'];
public config(config:any):void {
this._r['config'](config);
}
public require(reqs:string[], callback:any):void {
this._r(reqs, callback);
}
}
var rjs = new RequireJS();
rjs.config({
paths: {
"jquery": '/libs/jquery/jquery',
"slider": '/js/blah/slider'
}
});
rjs.require(['slider'], function(slider) {
console.log(slider);
});
Which seems terrible.
So be clear, inside modules that depend on each other, this sort of thing works perfectly fine:
import $ = require('jquery');
export module blah {
...
}
I just need a proper way to setting the requirejs config at a top level, so that the imported paths for the various named modules are correct.
(...and this is because, largely, 3rd party dependencies are resolved using bower, and installed in the /lib/blah, where as the shim files I have for their definitions are in src/deps/blah.d.ts, so the default import paths are incorrect after moving the generated modules files into /js/ on the site)
NB. I've mentioned jquery here, but the problem is not that jquery doesn't work property as an AMD module; I have a shim jquery.ts.d file for this. The issue here is the requirejs paths.
Yesterday I wrote up a solution to this exact issue on my blog - http://edcourtenay.co.uk/musings-of-an-idiot/2014/11/26/typescript-requirejs-and-jquery:
TL;DR - create a config file config.ts that looks something like:
requirejs.config({
paths: {
"jquery": "Scripts/jquery-2.1.1"
}
});
require(["app"]);
and ensure your RequireJS entry point points to the new config file:
<script src="Scripts/require.js" data-main="config"></script>
You can now use the $ namespace from within your TypeScript files by simply using
import $ = require("jquery")
Hope this helps
This post is 3 years old, and there's a lot of changes that have been made when using Typescript. Anyway, after some search on the web,some research on TS documentation-these guys made some good job, I found something that could help.
so this can apply to the latest current of TS (2.2.1)
you probably know that you can use
npm install --save #types/jquery
do the same for your 3rd party JS librairies such as require
now you need to define what your TypeScript Compiler has to do, and how, so create a tsconfig.json file that contains:
// tsconfig.json file
{
"compilerOptions": {
"allowJs": true,
"baseUrl": "./Scripts",//Same as require.config
"module": "amd",
"moduleResolution": "Node",//to consider node_modules/#types folders
"noImplicitAny": false,
"target": "es5", // or whatever you want
"watch": true
}
now, let's focus on require's configuration
// require-config.ts
declare var require: any;
require.config({
baseUrl: "./Scripts/",
paths: {
"jquery": "vendor/jquery/jquery.x.y.z"
// add here all the paths your want
// personnally, I just add all the 3rd party JS librairies I used
// do not forget the shims with dependencies if needed...
}
});
so far so good
now focus on your module written in TS that would use jquery and that is located in Scripts/Module folder:
// module/blah.ts
/// <amd-module name="module/blah" />
import $ = require("jquery");
export function doSomething(){
console.log("jQuery version :", $.version);
}
So this answer looks the same as Ed Courtenay's, doesn't it?
and user210757 mentioned that it does NOT work!!!
and it does not! if you type in your console tsc -w --traceResolution, you'll see that tsc cannot find any definition for jquery.
Here's how to alleviate assuming you previously launch npm install --save #types/jquery by doing this, in a folder named node_modules\#types, you should get the TS definition for jquery
select the package.json file in jquery subfolder
look for the "main" property
set it to "jquery", the same as the alias you are using in your require.config
and done! your module would be transpiled as
define("module/blah", ["require", "exports", "jquery"], function (require, exports, $) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function doSomething() {
console.log("jQuery version:", $.fn.jQuery);
}
exports.doSomething = doSomething;
});
and that JS code looks good to me!
I just don't like the fact that our module dependencies list "require" & "exports", that sounds like a TS issue, but anyway IT WORKS!
if you want to use import for javascript modules you need to tell typescript about it so,
declare var require;
require.config({
paths: {
"blah": '/libs/blah/blah',
}
});
// Important, place in an external.d.ts:
declare module 'blah'{
// your opportunity to give typescript more information about this js file
// for now just stick with "any"
var mainobj:any;
export = mainobj;
}
import b = require('blah');
console.log(b);
alternatively you could simply do:
var b = require('blah'); and it should work as well

jQuery file upload and RequireJS configuration

I'm trying to use jQuery file upload, but I'm getting stuck with the RequireJS configuration. We install our dependencies in a /ext/ folder, e.g:
/src
/ext
/jquery-file-upload
In my main.js I use the following config:
require.config({
paths: {
"ext/jquery-file-upload": "../ext/jquery-file-upload/js/jquery.fileupload"
}
});
require([
"ext/jquery-file-upload"
]);
But then RequireJS tries to load jquery.ui.widget.js from the root instead of as a relative file. It is located in the jquery-file-upload directory..
Does anyone know what I'm doing wrong, or does anyone know of a working RequireJS config for jQuery file upload?
Thanks,
Martijn
If you look at the jquery.fileupload.js file, at the top it declares its own dependencies
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define([
'jquery',
'jquery.ui.widget'
], factory);
You need to edit your require.config path for the jquery.ui.widget item.
require.config({
paths: {
'jquery.ui.widget': 'your_path_here/jquery.ui.widget'
}
});
If I don't mistake, your problem is that your plugin - jquery-file-upload - tries to load its dependencies by itself.
The problem is that filepaths in JS are relative to the page loading the script file, not to the file itself (Relative Paths in Javascript in an external file). This explains why your file seems to be loaded relatively to the root and not the given path.
In this case, you probably will have to manipulate a bit of the plugin code and take a look at the explanations given here concerning requireJS and dependencies loading:
How do I use requireJS and jQuery together? .
Try mapping jquery.widget.ui to the correct path...
require.config({
paths: {
"ext/jquery-file-upload": "../ext/jquery-file-upload/js/jquery.fileupload"
"jquery.ui.widget": "../ext/jquery-file-upload/js/vendor/jquery.ui.widget"
}
});
require([
"ext/jquery-file-upload"
]);
For anyone else having this problem...this is the config that worked for us.Hope it helps someone
The paths declaration
paths: {
'jquery.ui.widget': '../../Scripts/FileUpload/jqueryui/jquery.ui.widget',
'jquery_iframe_transport': '../../Scripts/FileUpload/jquery.iframe-transport',
'jquery.fileupload': '../../Scripts/FileUpload/jquery.fileupload'
}
The Define statement
define(['jquery.ui.widget','jquery_iframe_transport','jquery.fileupload'])
The above is dependent on jquery being loaded. We are using Durandal hence dont need a shim but you will need to ensure jquery is loaded before anything else
The initialisation in code
function uploadFile() {
var url = '/Backload/UploadHandler';
$('#fileupload').fileupload({
url: url,
dataType: 'json',
done: function (e, data) {
$.each(data.result.files, function (index, file) {
$('<p/>').text(file.name).appendTo('#files');
});
},
progressall: function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$('#progress .bar').css(
'width',
progress + '%'
);
}
});
}
This is the basic upload example..

RequireJS module attempts to load shim'ed module

I'm having an issue attempting to create a RequireJS shim for some javascript code that was written by another team in my organization. The script is loaded via a noraml HTML script as such:
<script src="MyCustomModule.js" type="text/javascript"></script>
My main.js contains the following:
requirejs.config({
paths: { 'text': 'durandal/amd/text' },
shim: {
'MyCustomModule': { exports: 'My.Custom.Module' }
}
});
And I have tried accessing the custom module in a variety of ways, but this is my current code:
define(['MyCustomModule'], function (require, MyCustomModule) {
...
}
But each time the page/app loads I get an error from RequireJS indicating that it failed to load app/MyCustomModule.js (and I can see the 404 error in the console where it attempted to request the file from the server). What am I doing wrong?
You also need to include MyCustomModule in paths:
requirejs.config({
paths: {
'text': 'durandal/amd/text'
'MyCustomModule': 'path/to/MyCustomModule'
},
shim: {
'MyCustomModule': {
exports: 'My.Custom.Module'
}
}
});
If you don't do that, define(['MyCustomModule'] (...) will look for the dependency in the baseUrl location, in your case: app/MyCustomModule.
In other words: shim can't "pick up" global variables that are not loaded by RequireJS.

Resources