I have been using requirejs and am having trouble getting the optimization tool to work. All I want to do is optimize my javascript files into one script file with all my dependencies included.
All my file are in the one js/ folder and I have a sub folder vendors/
I have a config file which looks like this(config.js):
requirejs.config({
baseUrl: ".",
out: "main-built.js",
deps: ["main"],
paths: {
jquery: "vendor/jquery", // v.1.10.2
bootstrap: "vendor/bootstrap",
ajaxform: "vendor/ajaxform",
skrollr: "vendor/skrollr",
jqueryform:"vendor/jqueryform"
},
shim: {
bootstrap: {
deps: ["jquery"],
exports: "bootstrap",
},
ajaxform: {
deps: ["jquery"],
exports: "ajaxform",
},
jqueryform: {
deps: ["jquery"],
exports: "jqueryform",
}
}
});
And I have an main javascript file (main.js) which looks like this:
if (typeof jQuery === 'function') {
define('jquery', function () { return jQuery; });
}
define(["jquery","bootstrap", "ajaxform","skrollr"],
function($, bootstrap, ajaxform, skrollr) {
//have other code here
});
I also created a build file:
({
baseUrl: ".",
paths: {
jquery: "vendor/jquery", // v.1.10.2
bootstrap: "vendor/bootstrap",
ajaxform: "vendor/ajaxform",
skrollr: "vendor/skrollr",
jqueryform:"vendor/jqueryform"
},
shim: {
bootstrap: {
deps: ["jquery"],
exports: "bootstrap",
},
ajaxform: {
deps: ["jquery"],
exports: "ajaxform",
},
jqueryform: {
deps: ["jquery"],
exports: "jqueryform",
}
},
name: "main",
out: "main-built.js"
})
All the build file does is compress the main.js file itself and doesn't include all needed files.
I've been trying to get this working on and off for weeks and can't seem to get it right so any help would be REALLY appreciated.
Thanks
Try adding a modules entry to your build file with your main module, as in:
modules: [
{ name: 'main' }
]
You can see all the options for the build file here: https://github.com/requirejs/r.js/blob/master/build/example.build.js
Related
How do you load other extensions for a jquery control called 'fancytree' I'm trying to get fancytee to load or include the fancytree.table.js and other extensions that are needed - below is my config
require.config({
shim: {
underscore: {
exports: '_'
},
backbone: {
deps: [
'underscore',
'jquery'
],
exports: 'Backbone'
},
'jquery-ui': {
exports: "$",
deps: ['jquery']
},
'fancytree': {
deps: ['jquery-ui']
},
'alertify': {
deps: ['jquery']
},
'fancytreetable': {
deps: ['jquery', 'fancytree']
}
},
paths: {
'jquery': '../lib/jquery/jquery',
'underscore': '../lib/underscore/underscore',
'backbone': '../lib/backbone/backbone',
'text': '../lib/text/text',
'jquery-ui': '../vendor/jquery-ui/jquery-ui',
'fancytree': [
'../vendor/fancytree/fancytree',
'../vendor/fancytree/fancytree.table'/* this extension here needs to be added but it's not included */
],
'alertify': '../vendor/alertify/alertify'
},
baseUrl: '/js/app',
});
Nikhil Mehta's comment points you in the right direction. Your paths value for fancytree is wrong. You use an array there when you want to provide fallback values for modules. If you give [A, B, C], for instance, if A fails to load, RequireJS tries B and if this fails, tries C. And if all fail, then that's a load failure.
Based on the configuration you show, you'd need:
fancytree: '../vendor/fancytree/fancytree',
fancytreetable: '../vendor/fancytree/fancytree.table'
You already have a shim that establishes that fancytreetable needs fancytree.
Note that unless you are using fairly old versions of Underscore and Backbone, you do not need to specify shim values for them. RequireJS is probably going to just ignore them but it may confuse people reading your code.
Here is how made it work, requirejs with jquery.fancytree-all and latest jquery-ui with AMD support, since working with individual extensions will require a lot of shimming.
onBuildWrite is optional but i prefer it this way
requirejs.config({
paths: {
'jquery': './js/vendor/jquery',
'jquery-ui': './js/vendor/jquery-ui',
'jquery.fancytree': './js/vendor/fancytree/jquery.fancytree-all'
},
shim: {
'jquery.fancytree': {
deps: ['jquery', 'jquery-ui/core', 'jquery-ui/effect', 'jquery-ui/effects/effect-blind', 'jquery-ui/widgets/draggable', 'jquery-ui/widgets/droppable'],
exports: 'jQuery.fn.fancytree'
}
},
onBuildWrite: function (moduleName, path, contents) {
'use strict';
if (moduleName === 'jquery.fancytree') {
contents = 'define( "jquery.fancytree", ["jquery", "jquery-ui/core", "jquery-ui/effect", "jquery-ui/effects/effect-blind", "jquery-ui/widgets/draggable", "jquery-ui/widgets/droppable"], function(jQuery) { ' + contents + '});';
}
return contents;
}
});
// usage
define([
'jquery',
'jquery.fancytree',
'css!./css/fancytree/skin-custom/ui.fancytree.css',
],
function($) {
'use strict';
//
$('#tree').fancytree({
checkbox: true,
source: [{title: 'Node 1'}, {title: 'Node 2',key: 'id2'}]
});
//
});
//
I recently worked on a web app, and i wanted to separate it into modules.
I searched and found out that RequireJs is the best for this. I read the doc, and some tutorials about it and came up with this
requirejs.config({
baseUrl: "js/lib",
shim: {
'jquery-1.12.1.min': ['jquery-1.12.1.min'],
'materialize.min': ['materialize.min'],
'knockout-3.4.0': ['knockout-3.4.0'],
'pouchdb-5.3.0.min': ['pouchdb-5.3.0.min']
},
waitSeconds: 0,
paths: {
'jquery-1.12.1.min': 'jquery-1.12.1.min',
'materialize.min': 'materialize.min',
'knockout-3.4.0': 'knockout-3.4.0',
'pouchdb-5.3.0.min': 'pouchdb-5.3.0.min',
}
});
require(["jquery-1.12.1.min", "knockout-3.4.0", "materialize.min", "pouchdb-5.3.0.min"], function($, ko) { //My main functions and other stuff ... }
My index has the following:
<script data-main="js/main" src="js/lib/require.js"></script>
<script type="text/javascript" src="js/converter.js"></script>
But it seems that my Jquery, KO, materialize.css and pouchdb aren't loading as i see on my chrome dev tools in Network:
I also read about the shim config how to set up the dependences and i want them in that order. I don't really know what am i missing, any help would really be appreciated.
Folder structure is:
js:
lib:
->jquery-1.12.1.min.js
->knockout-3.4.0.js
->pouchdb-5.3.0.min.js
->materialize.min.js
->require.js
main.js
converter.js
Ok it seems require and materialze.css have a problem with hammer.js, what i recommend is you go and download Hammer.min.js and include it in your lib folder.
Then in your main.js add the following:
requirejs.config({
baseUrl: 'js/lib',
waitSeconds: 0,
paths: {
app: '../app',
jquery: 'jquery-1.12.1.min',
materialize: 'materialize.min',
knockout: 'knockout-3.4.0',
pouchdb: 'pouchdb-5.3.0.min',
hammer: 'hammer.min'
},
shim: {
hammer: {
deps: ['jquery']
},
pouchdb: {
deps: ['jquery']
},
knockout: {
deps: ['jquery'],
exports: 'ko'
},
materialize: {
deps: ['jquery', 'hammer'],
},
jquery: {
exports: '$'
}
}
});
You include you hammer and also the dependency for jquery on it. And i see that you didn't put the PouchDb object in the function:
define(["jquery", "knockout", "pouchdb", "materialize" ], function($, ko, PouchDB) {...
Hope this helps
Using path, requirejs replace module id prefixes (name in config) with the corresponding value.
Using shim you can export a global variable and configure the dependencies ( materialize depends jquery so you have to import jQuery before importing materialize.js )
requirejs.config({
baseUrl: "js/lib",
waitSeconds: 0,
paths: {
'jquery': 'jquery-1.12.1.min',
'materialize': 'materialize.min',
'knockout': 'knockout-3.4.0',
'pouchdb': 'pouchdb-5.3.0.min',
'hammer': 'hammer.min',
},
shim: {
pouchdb: {
deps: ['jquery']
},
knockout: {
exports: 'ko'
},
materialize: {
deps: ['jquery', 'hammer']
},
jquery: {
exports: '$'
}
}
});
require(["jquery", "knockout", "materialize", "pouchdb"], function ($, ko) {
console.log($);
console.log(ko);
});
I'm working with the ngStart Angular seed project and I'm trying to optimize RequireJS for deployment. When I run the grunt job to build the artifact, I end up with an output file that does not include all of the libraries in my main.js file. I've spent most of today trying different things to get this to work. If I explicity list every module in my gruntfile (something I really don't want to do) they all get in there, but seemingly not in the right order as it doesn't work in the browser. I thought that the optimizer was supposed to read the require.config call in my main.js and load everything in the correct order. Below is what I thought should work, but isn't loading all of my modules.
grunt task:
requirejs: {
compile: {
options: {
baseUrl: "<%= pkg.folders.jsSource %>",
name: "main",
include: [
'almond'
],
mainConfigFile: "<%= pkg.folders.jsSource %>/main.js",
out: "<%= pkg.folders.build + pkg.name + '-' + pkg.version %>/modules/main.js",
optimize: "none",
paths: {
'almond': '../../../bower_components/almond/almond',
'config/configuration': 'config/<%=configuration%>'
},
generateSourceMaps: true,
preserveLicenseComments: false,
useSourceUrl: true,
uglify2: {
// TODO - angular.js is already minified, mangling destroys it, so mangling is currently globally disabled
mangle: false
}
}
}
}
main.js:
/*global require */
(function (require) {
"use strict";
require.config({
paths: {
'jquery': '../../../bower_components/jquery/jquery',
'jquery-ui': '../../../bower_components/jquery-ui/ui/jquery-ui',
'jquery.ui.widget': '../../../bower_components/jquery-ui/ui/jquery.ui.widget',
'bootstrap': '../../../bower_components/bootstrap/dist/js/bootstrap',
'angular': '../../../bower_components/angular/angular',
'ngResource': '../../../bower_components/angular-resource/angular-resource',
'angular-route': '../../../bower_components/angular-route/angular-route',
'angular-sanitize': '../../../bower_components/angular-sanitize/angular-sanitize',
'ngUi': '../../../bower_components/angular-ui/build/angular-ui',
'ui.bootstrap': '../external-libs/angular-ui-bootstrap/ui-bootstrap-tpls-0.6.0-SNAPSHOT',
'ngCalendar': '../../../bower_components/angular-ui-calendar/src/calendar',
'uikeypress': '../../../bower_components/angular-ui-utils/modules/keypress/keypress',
'dtPicker': '../../../bower_components/eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min',
'fileUpload': '../../../bower_components/blueimp-file-upload/js/jquery.fileupload',
'fullcalendar': '../../../bower_components/fullcalendar/fullcalendar',
'iframeTransport': '../external-libs/iframetransport/jquery.iframe-transport',
'moment': '../../../bower_components/momentjs/moment'
},
shim: {
'jquery': { deps: [], exports: 'jquery' },
'jquery-ui': { deps: ['jquery'], exports: 'jquery-ui' },
'jquery.ui.widget': { deps: ['jquery'], exports: 'jquery-ui-widget' },
'bootstrap': { deps: ['jquery'], exports: 'bootstrap' },
'angular': { deps: ['jquery'], exports: 'angular' },
'ngResource': { deps: ['angular'], exports: 'ngResource' },
'angular-route': { deps: ['angular'], exports: 'ngRoute' },
'angular-sanitize': { deps: ['angular'], exports: 'ngSanitize' },
'ngUi': { deps: ['angular'], exports: 'ngUi' },
'ui.bootstrap': { deps: ['angular', 'bootstrap', 'ngUi'], exports: 'ui-bootstrap' },
'ngCalendar': { deps: ['jquery', 'jquery-ui', 'fullcalendar', 'angular'], exports: 'ngCalendar' },
'uikeypress': { deps: ['angular', 'ngUi'], exports: 'uikeypress' },
'dtPicker': { deps: ['jquery', 'bootstrap', 'moment'], exports: 'dtPicker' },
'fileUpload': { deps: ['jquery', 'jquery-ui', 'bootstrap', 'iframeTransport'], exports: 'fileUpload' },
'fullcalendar': { deps: ['jquery', 'jquery-ui'], exports: 'fullcalendar' },
'iframeTransport': { deps: ['jquery', 'jquery-ui'], exports: 'iframeTransport' },
'moment': { deps: ['jquery'], exports: 'moment' }
},
priority: ['angular']
});
require(['config/config',
'angular',
'angular-route'],
function (config, angular, routes) {
require(config.standardRequireModules, function (angular) {
angular.bootstrap(document, ["app"]);
});
});
}(require));
When I run the task, I get this:
Running "requirejs:compile" (requirejs) task
Tracing dependencies for: main
/Users/user/dev/project/trunk-angular/target/project-0.1.0/modules/main.js
----------------
/Users/user/dev/project/trunk-angular/bower_components/almond/almond.js
/Users/user/dev/project/trunk-angular/bower_components/jquery/jquery.js
/Users/user/dev/project/trunk-angular/bower_components/angular/angular.js
/Users/user/dev/project/trunk-angular/src/main/modules/config/configuration.js
/Users/user/dev/project/trunk-angular/bower_components/bootstrap/dist/js/bootstrap.js
/Users/user/dev/project/trunk-angular/bower_components/angular-ui/build/angular-ui.js
/Users/user/dev/project/trunk-angular/src/main/external-libs/angular-ui-bootstrap/ui-bootstrap-tpls-0.6.0-SNAPSHOT.js
/Users/user/dev/project/trunk-angular/src/main/modules/config/config.js
/Users/user/dev/project/trunk-angular/bower_components/angular-route/angular-route.js
/Users/user/dev/project/trunk-angular/src/main/modules/main.js
Root of the project is /Users/user/dev/project/trunk-angular.
All of the path variables should be fine (they are in the other tasks and the outputted paths are right). I just don't know what's going on and would greatly appreciate some help.
First, I see, you are using nested require calls, but your build configuration doesn't include
findNestedDependencies: true.
Second, requirejs optimizer includes only those modules from path, that are explicitly required, or defined as a dependency for other modules, that are required later.
I have the following main.js
requirejs.config({
baseUrl: 'js',
paths: {
"jquery": "http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"
},
shim: {
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
'marionette': {
deps: ['jquery', 'underscore', 'backbone'],
exports: 'Marionette'
},
'underscore': {
exports: '_'
}
}
});
The code to require query:
define(['jquery', 'backbone', 'marionette'], function($, Backbone, Marionette) {
Backbone, marionette and underscore all load correctly, but requireJS is ignoring the 'paths' config and trying to load jquery from js/jquery.js, not the CDN.
Using requires 2.1.9
You should exclude the ".js" extension from the CDN URL, just as you would for file paths in your baseUrl directory:
paths: {
"jquery": "http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min"
},
I'm using require.js for the first time and all is working pretty for the moment. However, I started wanting to make a build. The idea is to create one file with ALL my js and templates. However, every time I use r.js it just includes the dependencies of my main module.
here is my app.build.js:
({
appDir: "public/javascripts",
baseUrl: ".",
dir: "build",
paths: {
"hbs": "lib/hbs",
"jquery": "lib/jquery",
"Handlebars": "lib/Handlebars",
"Backbone": "lib/backbone",
"underscore": "lib/underscore",
"bootstrap": "lib/bootstrap.min.js"
},
modules: [{name: "main"}],
shim: {
"bootstrap": {
deps: ["jquery"],
exports: "$.fn.popover"
},
underscore: {
exports: '_'
},
'Handlebars': {
exports: 'Handlebars'
},
Backbone: {
deps: ["underscore", "jquery"],
exports: "Backbone"
}
}})
the beginning of main.js:
require.config({
paths: {
"hbs": "lib/hbs",
"Handlebars": "lib/Handlebars",
"Backbone": "lib/backbone",
"underscore": "lib/underscore",
"jquery": "lib/jquery",
"bootstrap": "lib/bootstrap.min.js"
},
hbs: {
disableI18n: true
},
shim: {
"bootstrap": {
deps: ["jquery"],
exports: "$.fn.popover"
},
underscore: {
exports: '_'
},
'Handlebars': {
exports: 'Handlebars'
},
Backbone: {
deps: ["underscore", "jquery"],
exports: "Backbone"
}
}
});
require(['jquery', 'Backbone', 'videos'], function($, Backbone, Videos) { // Whatever });
In this case the final file created in my build 'main.js' only contains: jquery, underscore, backbone and videos. How can I make sure it also includes the dependencies of the module videos namely: the template 'hbs!template/videos/show'. How can I also make sure that bootstrap.min.js is also added even though it's not required anywhere?
Finally should I remove the require.config as it will define paths that are not supposed to be anymore as all the modules are in the final file?
To have the optimizer include all the nested dependencies, include this option in your build file or command line:
{
findNestedDependencies: true
}
This makes it work as you'd expect, and you won't have to include all your dependencies in your main file. It's kind of a secret ... I never saw this in the docs but I read it on a random blog somewhere.
In you app.build.js include link to your main config file and you can remove specified modules, this should include all dependencies used by main module.
({
...
mainConfigFile: 'main.js',
...
})
You may also skip paths and shim, since that is already specified in main. Bellow is sample config that I'm using in one of my projects and works like a charm:
({
name: 'main',
baseUrl: '../',
// optimize: 'none',
optimize: 'uglify2',
exclude: ['jquery'],
paths: {
requireLib: 'require'
},
mainConfigFile: '../main.js',
out: '../main.min.js',
// A function that if defined will be called for every file read in the
// build that is done to trace JS dependencies.
// Remove references to console.log(...)
onBuildRead: function (moduleName, path, contents) {
return contents;
// return contents.replace(/console.log(.*);/g, '');
}
})