RequireJS optimize !text Dynamic load not allowed - requirejs

I use the plugin !text, and want that after optimization by r.js, user to edit their own templates. But after optimization I get an error: Dynamic load not allowed.
build.js
{
baseUrl: "f/app",
appDir: "..",
dir: "dist",
modules: [
{
name: "catalog"
}
],
stubModules: ['text'],
optimizeAllPluginResources: false,
inlineText: false,
paths: {
app: '../libs',
jquery: 'empty:',
underscore: 'empty:',
backbone: 'empty:',
marionette: 'empty:',
JSON: 'empty:',
// Plugins
text: '../libs/rjs-text',
},
exclude: ["jquery","underscore","backbone","marionette", 'JSON', 'text']
}
This is generally how it is possible to implement?

Without any example code this is virtually impossible to answer (as I said in my comment). However, just to take a shot in the dark, perhaps your problem is that you're using variables for your require imports, and that is annoying the require optimizer. Using literal arrays should solve that; in other words don't do:
var myDependencies = ['foo', 'bar'];
define(myDependencies, function(...
do:
define(['foo', 'bar'], function(...
See this link on the Require site for more info:
http://requirejs.org/docs/optimization.html

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
});

Confused between modules and bundles property in RequireJS / r.js build files

I am very confused at to what the difference is between the "bundles" property and the "modules" property in a r.js build file that might look something like:
({
"allowSourceOverwrites": false,
"preserveLicenseComments": false,
"findNestedDependencies": false,
"optimizeAllPluginResources": true,
"dir":"../public/bundles",
"baseUrl": "../public/static",
"optimize":"none",
"mainConfigFile": "../public/static/app/js/main.js",
"normalizeDirDefines": "all",
"paths" :{
requireLib : 'vendor/require',
jqueryUI: "empty:",
jqueryUICSS: "empty:"
},
"modules": [
{
name: "shared",
include: [
'jquery',
'async',
'backbone'
],
exclude:[]
}
],
"bundles": {
'shared': [],
'secondary': []
},
"stubModules":['text']
})
I am having a lot of trouble finding good information on how to create multiple bundles for a RequireJS project. When I just use the modules property and eliminate the bundles property, r.js goes looking for a file called shared.js - and I am not sure why.
r.js creates bundles, but the bundles option is not an option that r.js recognizes. If you look in the file that lists all r.js options, you won't find bundles there. If you remove it from your configuration, you'll get the same behavior.
When I just use the modules property and eliminate the bundles property, r.js goes looking for a file called shared.js - and I am not sure why.
r.js looks for shared.js because your modules specifies a module named "shared". r.js will do this unless you tell it that you want to create this module from scratch, and you do this by adding the create: true option to this module's build configuration:
"modules": [
{
name: "shared",
create: true, // <<<--- add this!
include: [
'jquery',
'async',
'backbone'
],
exclude:[]
}
],

RequireJS - Performance difference with define vs require

I'm trying to understand if there are any potential downsides to the way I am using requirejs. I am fan of using the commonjs syntax, a typical module will look like:
define(function(require) {
"use strict";
var Backbone = require('backbone');
var Templates = require('templates');
var User = require('accounts/models').User;
...
I then compile my application down to a single JS file. My build config looks like so:
name: 'main',
mainConfigFile: '<%= build_dir %>/<%= main_app %>',
out: '<%= build_dir %>/app.min.js',
optimize: 'none',
include: ['main'],
insertRequire: ['main'],
almond:true,
cjsTranslate: true,
findNestedDependencies: true,
preserveLicenseComments: false
My question is, does using this commonjs format pose any performance or optimisation issues that I would avoid if using a define array instead? As I understand it, the cjsTranslate argument converts it to a define call anyway, but I wasn't sure if there was something I was missing? Is it purely a preference / code readability thing?
For reference, my config file (main.js):
require.config({
paths: {
// Libraries
jquery: '../../vendor/jquery/jquery',
underscore: '../../vendor/underscore/underscore',
backbone: '../../vendor/backbone/backbone',
handlebars: '../../vendor/handlebars.js/dist/handlebars',
modernizr: '../../vendor/modernizr/modernizr',
templates: '../templates'
},
shim: {
"underscore":{
exports: "_"
},
"backbone": {
deps: ["underscore", "jquery", "modernizr", "moment"],
exports: "Backbone"
},
"handlebars": {
exports: "Handlebars"
}
}
});
Is it purely a preference / code readability thing?
Yes absolutely. Once you build, R.js convert Commonjs to plain AMD.
The only performance hit would be when using unbuilded project. But for development it is fast enough (I see no clear difference myself).

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