Related
I am new working with requirejs, I have an old Asp.net Webform application that I am trying to apply some javascript module loading using requirejs. In this app I am using a jquery plugin named Time Entry, but is not working if I use requirejs, only works if I added the reference the old way. Here is my requirejs configuration and declaration.
In the aspx file:
<script src="../../scripts/require.js"></script>
<script>
require(["../../app/shared/require.config"],
function (config) {
require(["appIncidentTracking/incident-type-init"]);
});
</script>
My require.config file is like this:
require.config({
baseUrl: '../../scripts',
paths: {
app: '../../app/utilization-management',
appIncidentTracking: '../../app/incident-tracking',
jquery: 'jquery-3.1.1.min',
jqueryui: 'jquery-ui-1.12.1.min',
jqueryplugin: '../../js/jquery.plugin.min',
timeentry:'../../js/jquery.timeentry.min',
handlebars: 'handlebars.amd.min',
text: 'text',
moment: 'moment.min',
datatable: 'DataTables/jquery.dataTables.min',
blockUI: 'jquery.blockUI.min',
shared: '../../app/shared',
bootstrap: 'bootstrap.min',
'bootstrap-datepicker': 'bootstrap-datepicker.min',
'bootstrap-multiselect': '../js/bootstrap-multiselect/bootstrap-multiselect'
},
shim: {
bootstrap: {
deps: ['jquery']
},
'bootstrap-multiselect': {
deps: ['bootstrap']
},
timeentry: {
deps:['jquery', 'jqueryplugin']
}
}
});
and in my incident-type-init.js I only call the plugin:
/**
* Incident Type Init page
* #module incident-type-init
*/
define(function (require) {
var $ = require('jquery'),
jqueryplugin = require('jqueryplugin'),
timeentry = require('timeentry'),
bootstrap = require('bootstrap');
/**
* Jquery ready function
*/
$(function () {
$('.js-timeentry').timeEntry();
});
});
but when the application runs I got this error:
$.JQPlugin.createPlugin is not a function, it is like does not find the jquery.plugin.js
I checked the network tab in chrome and both files are loaded, jquery.plugin.js and jquery.timeentry.js
UPDATE: In our application, we are using Asp.net MasterPages, and there we are loading an old jquery version, 1.5.1, and I use that MasterPage in my page, but when I check the network tab in chrome, is loading the MasterPage scripts first,then all the requirejs stuff.
and the funniest part is that sometimes work, sometimes not.
Any clue?
The module jqueryplugin needs to have jQuery already loaded for it. It is not an AMD module because it does not call define. So you need an additional entry in shim for it:
jqueryplugin: ["jquery"]
The above is short for:
jqueryplugin: {
deps: ["jquery"]
}
I don't think your code is syntactically correct.
Try this:
1. Your script should refer to the require.config in data-main.
<script data-main="PATH_TO_CONFIG_FILE" src="../../scripts/require.js"></script>
2. Quotes are missing in paths of the config file. Instead it should be like this
require.config({
baseUrl: '../../scripts',
paths: {
"app": '../../app/utilization-management',
"appIncidentTracking": '../../app/incident-tracking',
"jquery": 'jquery-3.1.1.min',
"jqueryui": 'jquery-ui-1.12.1.min',
"jqueryplugin": '../../js/jquery.plugin.min',
"timeentry":'../../js/jquery.timeentry.min',
"handlebars": 'handlebars.amd.min',
"text": 'text',
"moment": 'moment.min',
"datatable": 'DataTables/jquery.dataTables.min',
"blockUI": 'jquery.blockUI.min',
"shared": '../../app/shared',
"bootstrap": 'bootstrap.min',
"bootstrap-datepicker": 'bootstrap-datepicker.min',
"bootstrap-multiselect": '../js/bootstrap-multiselect/bootstrap-multiselect'
},
shim: {
"bootstrap": {
deps: ["jquery"]
},
"bootstrap-multiselect": {
deps: ["bootstrap"]
},
"timeentry": {
deps:["jquery", "jqueryplugin"],
exports:"timeentry"
}
}
});
3. Since your module has dependencies, list them like this:
define(["jqueryplugin","timeentry","bootstrap"],function(jqueryplugin,timeentry,bootstrap) {
$(function () {
$('.js-timeentry').timeentry();
});
});
I am having a lot of trouble wrapping my head around requireJS dependancy management. I've read the docs and all online resources plenty of times but I can't seem to get it working correctly.
End scenario: I have an embeddable widget that eventually will attach a responsive iFrame to a page. The outer page is assumed to have some version of jQuery, but to be safe I am including my own jQuery.
I am using a library called responsiveIframe, which depends on jQuery.
Basically, when I call $('#responsive-frame').responsiveIframe({xdomain: '*'}); from inside the require function, I get an undefined function error. When I change $ to jQuery it works because it is able to use the existing library on the page (not what I want).
Here is the code (assume paths all work):
require.config({
baseUrl: 'http://localhost:4000/assets',
paths: {
'jquery': 'jquery-1.11.1.min',
'responsiveIframe': 'jquery.responsiveiframe'
},
map: {
'*': {'jquery': 'jquery-lc'},
'jquery-lc': {'jquery': 'jquery'}
}
});
require(['jquery', 'responsiveIframe'], function($) {
$('#responsive-frame').responsiveIframe({
xdomain: '*'
});
});
I've tried using various shims like so:
shim: {
responsiveIframe: {
init: function() {
return this.responsiveIframe
}
}
}
,
shim: {
'responsiveIframe': ['jquery']
}
,
shim: {
'responsiveIframe': {
'deps': 'jquery',
'exports': 'ResponsiveIframe'
'init': function() {
return this.responsiveIframe.noConflict()
}
}
I feel like I'm missing something fundamental about requireJS. Any help would be greatly appreciated, please let me know if you need more information :)
edit
Also, wrapping my responsiveiframe.js lib in this:
define(['responsiveIframe', 'jquery'], function(ri, jQuery) {
Seems to work... but this seems 'hacky'.
edit #2
I was able to get this to work by wrapping the responsiveIframe lib like this:
define(['jquery'], function(jQuery) {
//library code here
}
I was able to remove all shims:
require.config({
baseUrl: 'http://localhost:4000/assets',
paths: {
jquery: 'jquery-1.11.1.min',
responsiveIframe: 'jquery.responsiveiframe'
},
map: {
'*': {'jquery': 'jquery-lc'},
'jquery-lc': {'jquery': 'jquery'}
}
});
... and call like so:
require(['jquery','responsiveIframe'], function($) {
$('#responsive-frame').responsiveIframe({xdomain: '*'});
});
However, I am always a fan of doing things the 'right' way and modifying libraries rubs me the wrong way.
I feel like I should be able to use shim to properly apply this wrap code...
The last shim you tried was close, but the values of deps should be an array rather than a string. Try:
shim: {
'responsiveIframe': {
deps: ['jquery']
}
}
This is ensure jquery is loaded before the responseIframe script is loaded and run.
You should set shim like this:
shim: {
'responsiveIframe': {
deps: ['jquery'],
exports: '$'
}
}
And change your module definition to this
define(['responsiveIframe'], function($) {
$('#responsive-frame').responsiveIframe({xdomain: '*'});
}
That should do the trick
UPD.
If exports returns different jquery then you should modify shim to this:
shim: {
'responsiveIframe': {
deps: ['jquery'],
init: function(jquery) {
return jquery;
}
}
}
I'm using require.js and have a page with an from that used jquery.fileupload. After introducing the plugin I now see some files fail to be imported before the define call back is executed. This causes random errors where the libraries can't find their dependencies. It's as though require.js is moving on before all the dependencies can be resolved.
I've followed these instructions:
https://github.com/blueimp/jQuery-File-Upload/wiki/How-to-use-jQuery-File-Upload-with-RequireJS
But beyond that it's a very vanilla install. I'm using the minified versions of libraries where possible. Any insight is welcome.
here's the main.js:
(function () {
'use strict';
require.config({
baseUrl: '/js',
waitSeconds: 800,
paths: {
jquery: ['//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min',
'lib/jquery/jquery-2.0.3.min'],
'jquery.fileupload': 'lib/jquery.fileupload/jquery.fileupload',
'jquery.fileupload-ui': 'lib/jquery.fileupload/jquery.fileupload-ui',
'jquery.fileupload-image': 'lib/jquery.fileupload/jquery.fileupload-image',
'jquery.fileupload-validate': 'lib/jquery.fileupload/jquery.fileupload-validate',
'jquery.fileupload-video': 'lib/jquery.fileupload/jquery.fileupload-video',
'jquery.fileupload-audio': 'lib/jquery.fileupload/jquery.fileupload-audio',
'jquery.fileupload-process': 'lib/jquery.fileupload/jquery.fileupload-process',
'jquery.ui.widget': 'lib/jquery.ui/jquery.ui.widget',
'jquery.iframe-transport': 'lib/jquery.iframe-transport/jquery.iframe-transport',
'load-image': 'lib/load-image/load-image.min',
'load-image-meta': 'lib/load-image/load-image-meta',
'load-image-exif': 'lib/load-image/load-image-exif',
'load-image-ios': 'lib/load-image/load-image-ios',
'canvas-to-blob': 'lib/canvas-to-blob/canvas-to-blob.min',
tmpl: 'lib/tmpl/tmpl.min',
bootstrap: 'lib/bootstrap/bootstrap',
bootstrapTab: 'lib/bootstrap/bootstrap-tab',
EventEmitter: 'lib/event_emitter/EventEmitter',
linkedin: ['//platform.linkedin.com/in.js?async=true',
'http://platform.linkedin.com/in.js?async=true'],
skinny: 'lib/skinny/skinny',
selectize: 'lib/selectize/selectize.min',
sifter: 'lib/sifter/sifter',
microplugin: 'lib/microplugin/microplugin.min'
},
shim: {
bootstrap: {
deps: ['jquery'],
},
bootstrapTab: {
deps: ['jquery', 'bootstrap'],
},
linkedin: {
exports: 'IN'
},
selectize: {
deps: ['jquery', 'sifter', 'microplugin']
},
'jquery.iframe-transport': {
deps: ['jquery']
}
}
});
require(['app'], function (App) {
App.initialize();
});
}());
And the from code:
define([], function () {
'use strict';
return function () {
require(['jquery', 'tmpl', 'load-image', 'canvas-to-blob',
'jquery.iframe-transport', 'jquery.fileupload-ui'], function ($) {
$('#product').fileupload({
url: '/products/create'
});
});
};
});
The module gets called after the page has been loaded.
It's also worth noting that all files are downloaded successfully. No 404's, etc.
It turns out there is a flaw in the minified version of load-image.js that breaks how the dependencies load. I don't have exact proof as to why, it could be the smaller size causes a race condition, or it could be something weird in that particular file. What I do know is the minified version causes the random errors and the normal version does not (this is off master so I suppose I was taking a risk).
I raised a flag here
EDIT: it turns out the minified version of the plugin includes all the extensions which explains the odd dependency behavior.
The Answer from matt is the best solution in this case. Thanks a million, it save us a lot of time.
In requirejs.config, you have to add the load-image dependecies separatly - file by file.
For example:
require.config({
'jquery.ui.widget' : 'lib/jQuery-File-Upload-9.9.2/js/vendor/jquery.ui.widget',
'jquery.fileupload':'lib/jQuery-File-Upload-9.9.2/js/jquery.fileupload',
'jquery.fileupload-ui': 'lib/jQuery-File-Upload-9.9.2/js/jquery.fileupload-ui',
'jquery.fileupload-image': 'lib/jQuery-File-Upload-9.9.2/js/jquery.fileupload-image',
'jquery.fileupload-validate':'lib/jQuery-File-Upload-9.9.2/js/jquery.fileupload-validate',
'jquery.fileupload-audio':'lib/jQuery-File-Upload-9.9.2/js/jquery.fileupload-audio',
'jquery.fileupload-video':'lib/jQuery-File-Upload-9.9.2/js/jquery.fileupload-video',
'jquery.fileupload-process': 'lib/jQuery-File-Upload-9.9.2/js/jquery.fileupload-process',
'jquery.fileupload-jquery-ui': 'lib/jQuery-File-Upload-9.9.2/js/jquery.fileupload-jquery-ui',
'jquery.iframe-transport': 'lib/jQuery-File-Upload-9.9.2/js/jquery.iframe-transport',
'load-image':'lib/load-image-1.10.0',
'load-image-meta':'lib/load-image-meta-1.10.0',
'load-image-ios':'lib/load-image-ios-1.10.0',
'load-image-exif':'lib/load-image-exif-1.10.0',
'canvas-to-blob':'lib/canvas-to-blob-2.0.5',
'tmpl':'lib/tmpl.2.4.1'
}
});
call in html site:
requirejs(['jquery',
'jquery.ui.widget',
'tmpl',
'load-image',
'jquery.iframe-transport',
'jquery.fileupload-ui'], function () {
$('#fileupload').fileupload({
url: 'photo-upload.html'
});
}
);
One possibility modify the shim:
shim: {
bootstrap: {
deps: ['jquery'],
},
bootstrapTab: {
deps: ['jquery', 'bootstrap'],
},
linkedin: {
exports: 'IN'
},
selectize: {
deps: ['jquery', 'sifter', 'microplugin']
},
'jquery.iframe-transport': {
deps: ['jquery']
},
'jquery.fileupload-ui':{
deps: ['jquery']
}
Another option downgrade jquery to 1.X (this is because the sample page is using jquery 1.X)
I'm looking for a way to use TimelineJS with RequireJS's implementation of AMD. I can get things partially working, e.g.
define(["storyjs", "timelinejs", ...], function(storyjs, timelinejs, ...) {
createStoryJS({
type: 'timeline',
width: '800',
height: '600',
source: { ... }, // sample JSON
embed_id: 'timeline-embed'
});
});
The above produces a timeline, but storyjs (which exports VMM in my RequireJS config) always attempts to perform its own loading of the TimelineJS libraries, which invariably produces errors in the Firebug/developer tools console.
I'm either looking for a way to programmatically build the TimelineJS object (which I couldn't find any examples of), tell StoryJS to not bother loading libs using its mechanism (because I've already provided them) and in general integrate TimelineJS with an AMD solution.
Any suggestions?
UPDATE:
RequireJS configuration used, below. For my own personal use I have a tendency to rename JS libraries and append their version numbers.
var require = {
waitSeconds: 5,
paths: {
"app": "../js/app"
// ** Libraries
,"backbone": "../js/lib/backbone-1.1.0.min"
,"bootstrap": "../js/lib/bootstrap-3.0.2.min"
,"jquery": "../js/lib/jquery-1.10.2.min"
,"jquery-ui": "../js/lib/jquery-ui-1.10.3.min"
,"json2": "../js/lib/json2"
,"underscore": "../js/lib/underscore-1.5.2.min"
// ** TimelineJS
,"storyjs": "../js/lib/storyjs-embed-2.0.3.min"
,"timelinejs": "../js/lib/timeline-2.26.3.min"
// ** RequireJS Plugins
,"domready": "../js/lib/plugins/requirejs/requirejs-plugin-domready-2.0.1"
,"i18n": "../js/lib/plugins/requirejs/requirejs-plugin-i18n-2.0.4"
,"text": "../js/lib/plugins/requirejs/requirejs-plugin-text-2.0.10"
},
shim: {
'backbone': { deps: ['underscore'], exports: 'Backbone' }
,'bootstrap': { deps: ['jquery'] }
,'jquery': { exports: '$' }
,'json2': { exports: 'JSON' }
,'storyjs': { exports: 'VMM' }
,'timelinejs': { deps: ['storyjs'] }
,'underscore': { exports: '_' }
}
};
It took digging into the TimelineJS source a bit to see what exactly createStoryJS was actually doing and then looking at some of the other source code, but I finally answered my own question. In fact, it is relatively straightforward and very similar to my early attempts to make this work before posting my question above to StackOverflow.
RequireJS Config:
// RequireJS config
var require = {
waitSeconds: 5,
paths: {
...
// ** TimelineJS
,"storyjs": "../js/lib/plugins/jquery/storyjs-embed-2.0.3.min"
,"timelinejs": "../js/lib/plugins/jquery/timeline-2.26.3.min"
...
},
shim: {
...
,'storyjs': { deps: ['jquery'], exports: 'VMM' }
,'timelinejs': { deps: ['jquery', 'storyjs'] }
...
}
};
Module instantiating TimelineJS object:
define([ "json2", "timelinejs"], function(JSON, timelinejs) {
var js_version = "2.24",
config = {
version: "2.24", // DEFAULT: 2.x
debug: true,
type: 'timeline',
source: {...} // Sample JSON
};
var timeline = new VMM.Timeline("timeline-embed", 800, 600);
timeline.init(config);
});
This is, at the very least, one example for handling the TimelineJS instantiation using RequireJS/AMD; it is also how I've decided to solve my original issue.
This is what my config.js file looks like:
require.config({
baseUrl: '../',
paths: {
jQuery: 'js/jquery-1.10.2.min',
uiEffectsCore: 'js/jQueryUIEffectsCore',
//Handlebars: 'js/handlebars',
SyntaxHighlighter: 'js/syntaxhighlighter/scripts/shCore',
shXml: 'js/syntaxhighlighter/scripts/shBrushXml'
},
shim: {
jQuery: {
exports: 'jQuery'
},
uiEffectsCore: {
deps: ['jQuery']
},
shXml: {
deps: ['SyntaxHighlighter']
}
}
});
require(['js/main']);
Then my main.js looks like this:
define(function(require){
require('jQuery');
require('uiEffectsCore');
require('SyntaxHighlighter');
require('shXml');
});
I think the problem is that there is no define(...) wrapper around my shXml file... I am wondering if I can make this work without having to use that wrapper. Maybe an export shim would do it.
As it stands now, i get this error every time.
This question has also been asked here on github.
Check out this article, also from github. I tested this, and it works great, but you have to replace the first line of your brush.js files (inside syntaxhighlighter) with this line here:
SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
I don't even know why that fixes the issue, but it does, and you can load your scripts like this:
define(function(require){
require('jQuery');
require('uiEffectsCore');
require('SyntaxHighlighter');
require('shXml');
require('shCss');
require('shJs');
require('Raphael');
And you need a shim in your config for dependencies:
paths: {
SyntaxHighlighter: 'js/syntaxhighlighter/scripts/shCore',
shXml: 'js/syntaxhighlighter/scripts/shBrushXml',
shCss: 'js/syntaxhighlighter/scripts/shBrushCss',
shJs: 'js/syntaxhighlighter/scripts/shBrushJScript'
},
shim: {
shXml: {
deps: ['SyntaxHighlighter']
},
shCss: {
deps: ['SyntaxHighlighter']
},
shJs: {
deps: ['SyntaxHighlighter']
}
}