Can requirejs be used for this? - requirejs

I have a simple index page that uses a handful of js files, including jquery and underscore from a CDN.
To learn, I want to set up requirejs to manage the scripts.
Folder structure:
exampleApp
-js
-foo.js
-main.js
-require.js
-index.html
index, note foo() is a function in foo.js:
<script data-main="js/main" src="js/requirejs-2.1.9.js"></script>
<body>
<button onclick='foo()'>Click me</button>
</body>
main.js:
requirejs.config({
baseUrl: 'js',
paths: {
jquery : '//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js',
underscore : '//cdn.jsdelivr.net/underscorejs/1.5.2/underscore-min.js',
foo : 'foo'
},
shim: {
jquery: {
exports: '$'
},
underscore: {
exports: '_'
}
}
});
requirejs(['jquery', 'underscore', 'foo'], function($, _, foo){
});
In my foo.js, I use jquery using "$" and underscore using "_", so I want to maintain those symbols if possible.

Related

Bootstrap library with requirejs

I am trying to use bootstrap with require js. So far jquery, underscore and boostrap are loading fine, but I am having issues with one library not loading: bootstrap-tagsinput. How can I debug requirejs and see whether this library is loading or not?
Here is my common.js
requirejs.config({
shim: {
'jquery': {
exports: '$'
},
'underscore': {
exports: '_'
},
'bootstrap': {
deps: [ "jquery" ]
},
'bootstrap-tagsinput': {
deps: [ "bootstrap" ]
}
},
baseUrl: "/",
paths: {
'jquery': [
'//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min',
'jquery/jquery.min'
],
'underscore': [
'//underscorejs.org/underscore-min',
'underscore/underscore-min'
],
'bootstrap': [
'//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min',
'bootstrap/dist/js/bootstrap.min'
],
'bootstrap-tagsinput': 'bootstrap-tagsinput/dist/bootstrap-tagsinput.min'
}
});
Require.js is invented to handle dependencies between modules, so it is quite clear that you specify those dependencies in the modules where you use it like you said in your own answer already. The function given as the second parameter to define() gets handles to those modules in the order they are given.
As $ is normally used for jQuery library, it is not a good idea to use $ for something else, because this would create a lot of confusion. But normally you need jQuery in a module as well, so your define() call will most probably look like
define['jquery', 'bootstrap-tagsinput'], function($) {
...
});
In this case $ is bound to jQuery, not to bootstrap-tagsinput. It is instead called via the jQuery mechanisms, so you don't need a second parameter in the function.
I figured out that 'bootstrap-tagsinput' needs to be defined where it's being used. For example, in a page that makes use of this library:
define(['bootstrap-tagsinput'], function() {
// js for the page here
});
And in order to auto-load modules that should always be available (eg. bootstrap or jquery) we can do the same.
define(['bootstrap'], function() {
// main.js contents
});

Using non-modular scripts in Typescript

I'm using Typescript AMD and Requirejs in Visual Studio 2013 and I want to use a non-modular script in my Typescript class.
How can I achieve this:
define(["require", "exports", 'slickgrid'], function(require, exports, slickgrid){
...
});
I can't use the following syntax:
import slickgrid = require('slickgrid');
export class myClass {
...
}
When I do I get 2 errors
Unable to resolve external module '"slickgrid"
Module cannot be aliased to a non-module type.
Config looks like this
require.config({
baseUrl: 'scripts',
paths: {
jquery: 'jquery-1.10.2',
jqueryui: 'jquery-ui-1.10.4',
dragevent: 'jquery.event.drag',
slickcore: 'SlickGrid/slick.core',
slickgrid: 'SlickGrid/slick.grid',
},
shim: {
jquery: { exports: '$' },
jqueryui: ['jquery'],
dragevent: ['jquery'],
slickcore: ['jqueryui'],
slickgrid: {
deps: ['slickcore', 'dragevent'],
exports: 'Slick'
},
}
});
Use this definition file : https://github.com/borisyankov/DefinitelyTyped/blob/master/slickgrid/SlickGrid.d.ts
And add the following in some .d.ts file to tell typescript about your requirejs config:
declare module 'slickgrid'{
export = Slick
}
This will allow you to do:
import slickgrid = require('slickgrid');

require js beginner - dependency injection

I'm a beginner with require js and I have a doubt here.
My files are structured like below:
root
|____assets
|____bootstrap-3.0.1
|________dist
|____________js
|____________bootstrap.min.js
|________js
|________angulajs.min.js
|________app.js
|________jquery.min.js
|________underscorejs-min.js
|____________app
|________________main.js
My app.js file is like below:
requirejs.config({
"baseUrl": "assets/js",
"paths": {
": "app",
"jquery": "jquery.min",
"jquery-migrate": "jquery-migrate.min",
"twitter-bootstrap": "../bootstrap-3.1.0/dist/js/bootstrap.min",
"underscore": "underscore-min"
},
"shim": {
"twitter-bootstrap": {
deps: [ "jquery" ]
}
}
});
requirejs(["app/main"]);
My main.js is like below:
define([ "jquery", "twitter-bootstrap" ], function($) {
$(function() {
$("#teste").tooltip();
});
});
My question is about the main file and the dependency jquery in the case of bootstrap. If I had declare that the Bootstrap depends on jQuery I still have to include "jquery" in define function?
I tried to remove "jquery" declaration but the dependency was not injected and I received a undefined error.
Thanks for any help!
Doing it like this is really the way to go:
define([ "jquery", "twitter-bootstrap" ], function($) {
$(function() {
$("#teste").tooltip();
});
});
In the code above, it is clear that $ should be bound to the jquery module. If you do this:
define(["twitter-bootstrap" ], function($) {
$(function() {
$("#teste").tooltip();
});
});
You are binding $ to the twitter-bootstrap module. This won't work without further configuration because twitter-bootstrap exports nothing. (It installs itself as a jQuery plugin.) You could work around it by setting your shim like this:
"shim": {
"twitter-bootstrap": {
deps: [ "jquery" ],
exports: '$.fn.tooltip',
init: function ($) { return $; }
}
}
However, I don't recommend this since someone who comes across the code without knowing the context (that is, not knowing the relationship between the jquery and twitter-bootstrap modules) won't readily know what is going on.
In the shim above the exports field is not absolutely necessary but it help RequireJS know when Bootstrap has been loaded. It should be a symbol that does not exist prior to Bootstrap being loaded but exists after it is loaded.

RequireJS Optimizer throws ReferenceError: text is not defined

I have been using r.js to attempt to minify a fairly large project and I'm having trouble with the text plugin. I am using node.js and a build file that goes as follows:
Build File
({
name: '../main',
baseUrl: '../../js/app',
appDir: "./app",
dir: 'build',
paths: {
jquery: '../lib/jquery/jquery-1.10.2.min',
underscore: '../lib/underscore/underscore-min',
backbone: '../lib/backbone/backbone-min',
text: '../lib/require/text',
picker: '../lib/pickadate/picker',
pickerDate: '../lib/pickadate/picker.date',
pickerLegacy: '../lib/pickadate/legacy'
},
mainConfigFile : '../js/main.js'
})
Main Config File
requirejs.config({
baseUrl: 'js/app',
paths: {
jquery: '../lib/jquery/jquery-1.10.2.min',
underscore: '../lib/underscore/underscore-min',
backbone: '../lib/backbone/backbone-min',
text: '../lib/require/text',
picker: '../lib/pickadate/picker',
pickerDate: '../lib/pickadate/picker.date',
pickerLegacy: '../lib/pickadate/legacy'
},
shim: {
picker: ['jquery', 'pickerLegacy'],
pickerDate: {
deps: ['jquery', 'picker'],
exports: 'DatePicker'
},
backbone: {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
underscore: {
exports: '_'
},
text : {
exports : 'text'
}
}
});
The references above are all verified correct. Whenever I try to compile this, I get the following output in the console:
node r.js -o app.build.js
Tracing dependencies for: ../main
ReferenceError: text is not defined
In module tree:
../main
app
router
views/pages/home
views/panel/allStoresPanel
text
Error: ReferenceError: text is not defined
In module tree:
../main
app
router
views/pages/home
views/panel/allStoresPanel
text
at eval (eval at <anonymous> (C:\code\Web\DixonsDashboard\deploy\_compiler\r.js:23699:64), <anonymous>:1:1)
I have no idea why it finds text to be undefined. The path to it is definitely correct - the site works like a charm in it's current expanded format. I have tried all of the options available to r.js and none of them seem to make any difference.
If I delete the file, I get a "No such file or directory" error, so it looks like it's finding the file OK.
Can anybody point out what I'm missing here?
You only configure shim for plugins that are not AMD compatible. The "text" plugin is already AMD compatible so running it through the shim mechanism actually breaks it.
I've just tested with a simplified version of your code: including text in the shim section does show "ReferenceError: text is not defined", removing it makes the build work fine.

RequireJS + Optimizer Include modules defined on the main file

I'm using Optimizer for the first time and I am running in some issues or questions.
I'm trying to optimize a main file and it puts, like I've expected, the jQuery, Backbone and Require modules ( and uses then across the whole navigation). But let's say I have a jQuery Plugin that I use on several views. I've tried to add it in the main file using the "include" option on the build.js file. It adds it ( e.g jQuery Slides ) but as I have a view with define("jquery-slides") ( again, an example ) the browser loads the file of the plugin again. Even if it is on the main built file.
Is this suppose to happen? Can I fix this?
Thanks.
Here is some code. Hope it helps =)
build.js
{
baseUrl: "javascripts/",
appDir: "..",
dir: "dist",
name: "main-site",
include: ['libs/requirejs/require', jquery-slides'],
insertRequire: ['main-site'],
paths: {
"main-site": 'main-site',
'jquery': 'libs/jquery/jquery',
'jquery-slides': 'libs/jquery/plugins/slides.min.jquery'
}
}
main-site.js
require.config({
baseUrl: "/javascripts/",
paths: {
'jquery': 'libs/jquery/jquery',
'underscore': 'libs/underscore/underscore',
'bootstrap': 'libs/bootstrap/bootstrap.min',
'datepicker': 'libs/bootstrap/plugins/bootstrap-datepicker',
'backbone': 'libs/backbone/backbone.max',
'backbone-paginator': 'libs/backbone/plugins/backbone.paginator',
'backbone-validation': 'libs/backbone/plugins/backbone.validation',
'text': 'libs/requirejs/text',
'templates': '/templates/site',
'views': 'views/site',
'jquery-cookie': 'libs/jquery/plugins/jquery.cookie',
'jquery-raty': 'libs/jquery/plugins/jquery.raty.min',
'jquery-slides': 'libs/jquery/plugins/slides.min.jquery'
},
shim: {
'backbone-paginator': ['backbone'],
'bootstrap': ['jquery'],
'datepicker': ['bootstrap'],
'jquery-cookies': ['jquery'],
'jquery-raty': ['jquery'],
'jquery-slides': ['jquery'],
'backbone-validation': ['backbone']
}
});
require([
'app-site'
], function(App) {
$(function(){
App.initialize();
});
});
Instead of using include I recommend you to declare the modules you want to build. In this way requirejs will package the module and all its dependencies in the optimized bundle.
{
baseUrl: "javascripts/",
appDir: "..",
dir: "dist",
paths: {
"main-site": 'main-site',
'jquery': 'libs/jquery/jquery',
'jquery-slides': 'libs/jquery/plugins/slides.min.jquery'
},
modules : [
{
name : 'main-site',
}
]
}
Further considerations:
If you have jquery-slides included as a dependency in any of your modules define(['jquery-slides'], function() {... } you don't need to use the include directive since all the dependencies of that module will be included in the optimized file
See the documentation of the modules property in this link
https://github.com/jrburke/r.js/blob/master/build/example.build.js#L330
Use the property mainConfigFile to avoid duplications https://github.com/jrburke/r.js/blob/master/build/example.build.js#L35
Good luck and I hope this helps you

Resources