Don't include module in optimized script - requirejs

I'm using play 2.1 and requireJs bundled with the framework.
I have some client javascript modules and some libraries (such as jquery, bootstrap, etc).
I want to get following combined/minified modules: main.js - for all my client scripts and libs.js - for all library scripts.
I created libs module (it's in coffeescript):
requirejs.config(
paths:
'jquery': 'jquery-1.8.3'
shim:
'jquery-ui-1.9.1':
deps: ['jquery']
'jquery.layout-1.3.0-rc30.74':
deps: ['jquery', 'jquery-ui-1.9.1']
'bootstrap':
deps: ['jquery']
'bootstrap-fileupload':
deps: ['bootstrap']
)
define(["jquery", "jquery-ui-1.9.1", "jquery.layout-1.3.0-rc30.74",
"bootstrap", "bootstrap-fileupload"],
->
return {}
)
And somewhere in my client code I require libs module (I tried to provide it in dependency list and call require("libs");) but in production mode I get all my client code and libs combined in one main.js file.
Also I specified in Build.scala two modules:
val main = play.Project(appName, appVersion, appDependencies).settings(
requireJs += "main.js",
requireJs += "libs.js",
requireJsShim += "libs.js"
)
How can I split them in production mode?
Thanks for any help! Have a good day!

Related

RequireJS module load timeout when using bundles

Have require js working fine without the bundles. But whenever i use a bundle, i get timeouts for the modules i am trying to import.
Here is how i build the bundles with the asp.net mvc bundler/minifier
bundles.Add(new ScriptBundle("~/bundles/test").Include(
"~/scripts/jquery-{version}.js",
"~/scripts/bootstrap.js",
"~/scripts/moment.js"));
bundles.EnableOptimizations = true;
Heres is the require js config in the cshtml file:
<script>
require.config({
baseUrl: "/scripts",
paths: {
jquery: "jquery-1.11.2"
},
waitSeconds: 20,
shim: {
bootstrap: {
deps: ['jquery']
}
},
bundles: {
'#Scripts.Url("~/bundles/test").ToString()': [
'jquery',
'bootstrap',
'moment'
]
}
});
require(["app/main/test"]);
</script>
And the js for the page (app/main/test):
require(['jquery', 'moment'], function ($, moment) {
console.log(moment().format());
});
Jquery, bootstrap and moment libraries are in the test bundle i have created, but i get load timeouts loading the page for moment.
Here's the chrome inspector error:
Any ideas?
thanks in advance.
This is happening because you are not requiring your bundle at all. Your require call has only jquery and moment. You have provided jquery file path, so requirejs uses that path to download and provide jquery module. But since there is no path definition for moment, it is only part of the bundle that you have created. So requirejs tries downloading moment by its module name as path and thus throws an error.
A simple fix for this is to require bundle itself.
require(['#Scripts.Url("~/bundles/test").ToString()'], function(bundle){
//At this point jquery, moment and bootstrap will be loaded.
});
You can choose to use jQuery, moment from global namespace in above example directly or you can try requiring them seperately in below example. I am not sure, but you may get into error with below example because of cyclic dependency.
require(['#Scripts.Url("~/bundles/test").ToString()', 'jquery', 'moment'], function(bundle, $, moment){
//At this point jquery, moment and bootstrap will be loaded.
});
Just remove 'jquery' from your bundles
bundles.Add(new ScriptBundle("~/bundles/test").Include(
"~/scripts/bootstrap.js",
"~/scripts/moment.js"));
...
bundles: {
'#Scripts.Url("~/bundles/test").ToString()': [
'bootstrap',
'moment'
]
}
...
You already have it specified in the paths
paths: {
jquery: "jquery-1.11.2"
},
It seems require.js maps the modules to bundles so that once a module that is part of a bundle is loaded, that bundle is not loaded again.

RequireJS path 'alias' problems

Getting mighty tired fighting to get requireJS to work in a predictable manner. Its debugging support is underwhelming.
My config.js file as follows:
require.config({
baseUrl: "Scripts",
paths: {
"jquery": "jquery-2.1.1.min",
"bootstrap": "bootstrap.min",
"knockout": "knockout-3.1.0"
},
shim: {
"bootstrap": {
deps: ["jquery"],
exports: "$.fn.popover"
}
},
enforceDefine: true
});
require(["jquery", "bootstrap"], function ($, bootstrap) {
console.log("(A) loaded jq + bs");
if ($)
console.log("$ is present");
if (bootstrap)
console.log("bootstrap is present");
});
//# sourceMappingURL=Config.js.map
JavaScript in the /Scripts folder, which is where Config.js resides. 'jquery' is supposed to alias to a specific version, but when the browser loads it tries to load /Scripts/jquery.js
The aliased file /Scripts/jquery-2.1.1.min.js exists.
The same happens with bootstrap - it loads boostrap.js instead of bootstrap.min.js
I hate the way requireJS has this arcane way of mixing different behaviours into the same path setting, which changes based on string contents.
This link may help you.. the configuration file is being loaded asynchronously and has not been executed when you first call require()
Check this one
Require JS is ignoring my config

Building Durandal with Grunt (R.js + Text)

I would like to use Grunt to build a Durandal project, because Weyland remains completely undocumented and isn't as standard as Grunt.
To do this, the grunt task needs to pull in all the js and html files during optimization, but I am unable to get RequireJS to inline the html files via the text module.
It looks like weyland copies the text files manually, but I can't figure out what it's doing to get requirejs (or almond, in this case), to actually use them. I have seeen this question, but it requires the text modules to be referenced in the define call, which isn't done in Durandal.
My gruntfile for require uses this config
requirejs: {
build: {
options: {
name: '../lib/require/almond-custom', //to deploy with require.js, use the build's name here instead
insertRequire: ['main'], //needed for almond, not require
baseUrl: 'src/client/app',
out: 'build/main-built.js',
mainConfigFile: 'src/client/app/main.js', //needed for almond, not require
wrap: true, //needed for almond, not require
paths: {
'text': '../lib/require/text',
'durandal':'../lib/durandal/js',
'plugins' : '../lib/durandal/js/plugins',
'transitions' : '../lib/durandal/js/transitions',
'knockout': '../lib/knockout-2.3.0',
'bootstrap': '../lib/bootstrap.min',
'jquery': '../lib/jquery-1.9.1',
'Q' : '../lib/q.min'
},
inlineText: true,
optimize: 'none',
stubModules: ['text']
}
}
}
You might want to give https://npmjs.org/package/grunt-durandal a try. I'm using this as part of a grunt based build process. See https://github.com/RainerAtSpirit/HTMLStarterKitPro for an example.
durandal: {
main: {
src: ['app/**/*.*', 'lib/durandal/**/*.js'],
options: {
name: '../lib/require/almond-custom',
baseUrl: requireConfig.baseUrl,
mainPath: 'app/main',
paths: mixIn({}, requireConfig.paths, { 'almond': '../lib/require/almond-custom.js' }),
exclude: [],
optimize: 'none',
out: 'build/app/main.js'
}
}
},
As a possible alternative to Grunt I would suggest looking at Mimosa. It's not as widely used as Grunt but is well documented and requires a good deal less configuration and if you start with the durandal skeleton everything is configured for you including inlining html.
Durandal also recommends it and tells you how to get started with it: http://durandaljs.com/pages/get-started/
You can run make start to start developing and make dist to have it package everything up for release.

Require.js not compiling single js file correctly

I'm trying to build my require.js modules to one javascript file for production.
The command I'm running is...
r.js -o name=main out=main.min.js mainConfigFile=main.js
This compiles but the compiled main.min.js file is not compiled correctly and still includes the "define" statement blocks. and the browser obviously returns
Uncaught ReferenceError: define is not defined
My main.js file looks like:
require.config({
paths: {
jquery: 'libs/jquery/jquery',
},
shim: {
bootstrap: {
deps: ['jquery'],
exports: 'jquery'
}
}
});
require(['app', 'jquery'], function (app, $) {
'use strict';
// use app here
console.log(app);
console.log('Running jQuery %s', $().jquery);
});
Please let me know what I'm overlooking here.
Thanks!
You're correct, you need to include requireJS in your build. Take a look at http://requirejs.org/docs/optimization.html#onejs. You'll find an example for the command line there. If you're using a build profile it will look something like this -
({
baseUrl: "../Scripts",
paths: {
requireLib: 'libs/require'
},
name: "main",
out: "main-built.js",
include: ["requireLib"]
})
Quick fix: use r.js -o build.js instead of node r.js -o build.js
I had the problem when I was trying to call r.js through node:
node r.js -o build.js
Calling r.js directly fixed the problem:
r.js -o build.js
Note: r.js was installed globally with npm install -g requirejs

RequireJS and dependencies of 3rd party libraries eg. Backbone dependent on Underscore and jQuery

I understand that Backbone is dependent on Underscore, jQuery and maybe JSON2. So is it possible to specify that so when I say my module is dependent on Backbone, it will include dependencies of that? Or whats they way around this?
RequireJS makes this easy with the dependencies that you can declare when define a module. For libraries that don't support AMD (Underscore and Backbone being two primary examples) then use of the shim configuration is required.
Here is an example config:
require.config({
baseUrl: 'scripts/',
paths: {
'backbone': 'lib/backbone',
'jquery': 'lib/jquery',
'underscore': 'lib/underscore'
},
shim: {
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
}
}
});
Now if you require Backbone as a dependency in one of your modules underscore and jquery will be available.
A lot of this is also covered in the documentation.

Resources