Browserify jQuery is not defined? - javascript

So I know how to manually fix this but it's annoying!
I included bootstrap dropdown.js and at the end of the function is
}(jQuery);
Inside my shim I set jquery as a dependency
'bootstrap': {
"exports": 'bootstrap',
"depends": {
"jquery": '$'
}
},
It seems like this is the only way to use $, but since the dropdown has jQuery at the end the console shows
ReferenceError: jQuery is not defined
}(jQuery);
Changing it to }($); works.
So my question is does anyone have any idea to better do this without manually doing it, or is manually editing the script the best?

You can use global.jQuery = require("jquery")
This is my shim :
},
"plugin": {
"exports": "plugin",
"depends": [
"jquery: $",
"bootstrap: bootstrap"
]
}
and inside of plugin.js :
var $ = require('jquery')(window);
global.jQuery = require("jquery");
var bootstrap = require('bootstrap');
var plugin = require('plugin');
plugin();
it solve my problem. Hope it helps. :)

Shim
"./node_modules/jquery/dist/jquery.js": {
"exports": "$"
}
requiring
var jQuery = $ = require('$');
This should cover both plugins that use
(function($){
$.fn.function_name = function(x){};
})($);
as well as
(function($){
$.fn.function_name = function(x){};
})(jQuery);

I don't think my solution is anywhere near optimal or ideal and it doesn't answer my question but if anyone has this issue just do it this way, you can get it working possibly as a temporary solution to get things going without stagnating on your project.
Most if not all jQuery plugins are written with a self invoking function like this.
(function($){
$.fn.function_name = function(x){};
})(jQuery);
I simply went into the plugin itself and changed (jQuery) to ($)
(function($){
$.fn.function_name = function(x){};
})($);
If you're still having problems, make sure you have a shim defined in your package.json file and you are including the jQuery plugin with a require statement.

Related

RequireJS and local bootstrap.js file not working

I'm trying to use Bootstrap with RequireJS, setting RequireJS' config like this:
js/
bootstrap.min.js
app.js
require.js
scripts.js
This is the app.js file:
requirejs.config({
"shim": {
"bootstrap": {deps : 'jquery' }
},
"paths": {
"jquery": "//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min",
"bootstrap" : "bootstrap.min"
},
enforceDefine : true
});
// Load the main app module to start the app
requirejs(["scripts"]);
This is the scripts.js file:
define(["jquery", "bootstrap"], function($) {
console.log(jQuery);
$('#video').click(function () {
var src = 'http://www.youtube.com/v/FSi2fJALDyQ&autoplay=1';
$('#myModal').modal('show');
$('#myModal iframe').attr('src', src);
});
$('#myModal button').click(function () {
$('#myModal iframe').removeAttr('src');
});
});
This doesn't work and on the console says Bootstrap needs jQuery to work. The weird thing is if I change Bootstrap's path to load it from a CDN, it works.
Your shim for Bootstrap should use an array to specify dependencies:
shim: {
"bootstrap": {
deps : ['jquery'] // Use an array even with a single dependency.
}
}
The way it is now RequireJS does not get the dependency you specify. (It might interpret the string as an array and look for modules j, q, etc. I'm not sure about this...) So it loads Bootstrap irrespective of whether jQuery is loaded.
It works when you use a CDN probably because of a timing difference: it takes long enough to fetch from the CND that jQuery is loaded before Bootstrap loads. When you do it locally, Boostrap loads too fast and jQuery is not loaded yet. At any rate, using the array as I show above should solve the problem.
thanks for your help, When I downloaded RequireJS i never realized what version I was using.
I thought I had the latest but I was using 1.0.8, I upgraded and now I have 2.1.14, that solved the problem.
There's no need of using an export on the shim object as many entries say
shim: {
"bootstrap": {
deps : ['jquery'], // Use an array even with a single dependency.
export : '$.fn.modal'
}
}
Thanks for your help :D

Using knockout.simpleGrid.3.0.js with Require.js

I am using require.js with knockout on a website and would like to use the simpleGrid example from this link http://knockoutjs.com/examples/grid.html however I cannot include kncokout.simpleGrid.3.0.js with Require.
I have tried wrapping the plugin with
define(['jQuery', 'knockout'], // Require knockout
function($, ko) {
});
This does not work it seems the problem occurs with the templates.
Any help appreciated
In your require config, you should create a path to the simpleGrid library and use the shim to tell it that it depends on Knockout so that your libraries are loaded in the correct order. Here's an example:
var require = {
paths: {
'jquery': 'lib/vendor/jquery-2.0.3',
'ko': 'lib/vendor/knockout-3.0.0',
'koSimpleGrid': 'lib/vendor/knockout.simpleGrid.3.0'
},
shim: {
'koSimpleGrid': {
deps: ['ko']
},
}
};
And then you could copy paste the view model code from the example inside of a define like this:
define(['jquery', 'ko', 'koSimpleGrid'], function ($, ko) {
// VIEW MODEL GOES HERE
});
I agree the problem seems to be with the code that writes the grid template. Essentially, because requirejs loads modules asynchronously, document.write() can't be used - writing of the document has finished by the time a module executes. This StackOverflow answer explains it well I think.
I got round it by instead creating and appending the required script tag templates using dom methods:
templateEngine.addTemplate = function(templateName, templateMarkup) {
var scriptTag = document.createElement('script');
scriptTag.type = 'text/html';
scriptTag.id = templateName;
scriptTag.text = templateMarkup;
document.getElementsByTagName('body')[0].appendChild(scriptTag);
};
My amd version is in this gist.

browserify Using JQuery globally and in Module

I have been given a template to work from by a client that has some 28 different jquery plugins that the client wants to use (e.g. ditching them not an option).
However I really want to use browserify to modularise my code, but short of trying to shim all 28 plugin and thir dependancy I can't work out how I would do that and not have to load JQuery for browserify and globally.
I tried doing this:
window.JQuery = require('jquery')
window.$ = window.JQuery
And this:
var globals = function(){
window.JQuery = require('jquery')
window.$ = window.JQuery
}
globals();
But neither seem to work and all the plugins throw an error. Does anyone now how I might make it work?
This is a pretty good way to do it, I think.
npm install jquery
npm install browserify-shim
Put this line in your package.json:
browserify-shim" : {
"./node_modules/jquery/dist/jquery.js" : "$"
}
So on the server, your usual require('jquery') will point to the node_modules spot. When you run browserify, it will set window.$ to the same code (you could also use jQuery). Also, if you did want to shim those plugins, just add them like this:
"browserify-shim" : {
"./node_modules/jquery/dist/jquery.js" : "jQuery",
"./plugins/bs_modal.js" : {
"depends": [ "./node_modules/jquery/dist/jquery.js" ]
}
}
or, cleaner:
"browser" : {"jquery": "./node_modules/jquery/dist/jquery.js"},
"browserify-shim" : {
"jquery" : "jQuery",
"./plugins/bs_modal.js" : {
"depends": [ "jquery" ]
}
}
I have been using the line below, to get bootstrap and jquery to be browserified:
window.$ = window.jQuery = require('jquery');

glMatrix 2.2.0 with RequireJS

All definitions of glMatrix 2.2.0 seem to be undefined when included with RequireJS. However, on page inspection, it is being included in the HTML as a script tag.
However the same setup does work with glMatrix 1.3.7.
The require configuration is as follows:
require.config({
baseUrl: 'js/app',
paths: {
jquery: '../lib/jquery',
glm: '../lib/gl-matrix'
}
});
require(['main']);
And main.js looks like (jquery works in this instance):
define(function (require) {
var $ = require('jquery');
require('glm');
$(function () {
var a = mat4.create();
$('body').html("hello: " + a);
});
});
I also have the same problem with other global-namespace libraries like stats.js.
Although defining the scripts in HTML works, I would preferably like it to work with RequireJS for minimisation/concatenation.
<script src="js/lib/stats.js"></script>
<script src="js/lib/gl-matrix-min.js"></script>
Hopefully I'm missing something obvious with this one, as I'm tearing my hair.
Thanks in advance for any suggestions.
I use glmatrix too with require.js, the most recent version has require.js support and for me it seems to work fine.
I have however I slightly different usage with require.js, my modules usually start like this:
define(['lib/glmatrix/gl-matrix'],
function(glmatrix) {
var myModule = function() {};
// use glmatrix.vec3, etc here
return myModule;
});
Does this work for you?

Loading Highcharts via shim using RequireJS and maintaining jQuery dependency

I'm attempting to load the Highcharts library using a shim in RequireJS. However, when Highcharts loads, it throws an exception because it can't access the jQuery methods it depends on.
The require config looks like so:
require.config({
baseUrl: "js",
shim: {
'libs/highcharts/highcharts.src.js': {
deps: ['jquery'],
exports: function(jQuery)
{
this.HighchartsAdapter = jQuery;
return this.Highcharts;
}
}
}
});
The exception that is thrown is:
Uncaught TypeError: undefined is not a function
and is in regards to this line:
dataLabels: merge(defaultLabelOptions, {
The issue is the merge call, which eventually maps itself back to jQuery (or some other adapter that Highcharts supports; but I'm just using jQuery).
I'm not sure exactly how to make sure Highcharts gets access to jQuery using RequireJS and shim.
Has anyone used RequireJS and Highcharts together before? I guess the issue isn't specific to highcharts, but any library that has other sorts of dependencies.
Thanks in advance for any advice or points to the correct direction!
To add further context, in hopes that someone who is familiar with require.js or shims will be able to help without having to be too intimately familiar with highcharts, here's some source that sets up this merge method in Highcharts
var globalAdapter = win.HighchartsAdapter,
adapter = globalAdapter || {},
// Utility functions. If the HighchartsAdapter is not defined,
// adapter is an empty object
// and all the utility functions will be null. In that case they are
// populated by the
// default adapters below.
// {snipped code}
merge = adapter.merge
// {snipped code}
if (!globalAdapter && win.jQuery) {
var jQ = win.jQuery;
// {snipped code}
merge = function () {
var args = arguments;
return jQ.extend(true, null, args[0], args[1], args[2], args[3]);
};
// {snipped code}
}
The win object is a reference set up to window at the beginning of the script. So, I thought adding window.jQuery = jQuery; to the export method on the shim would result in highcharts picking up the jQuery reference; but it didn't.
Again, any insight, info, advice, or heckles would be appreciated at this point - I'm at a complete loss, and starting to question whether trying to implement and AMD package system in browser javascript is even worth it.
After accepting the answer from pabera below I thought it appropriate to update my question to reflect how his answer helped my solution (though, it's basically his answer).
RequireJS uses "paths" to find libs that aren't "AMD" supported and loads them on your page. the "shim" object allows you to define dependencies for the libraries defined in paths. The dependencies must be loaded before requirejs will try to load the dependent script.
The exports property provides a mechanism to tell requirejs how to determine if the library is loaded. For core libs like jquery, backbone, socketio, etc they all export some window level variable (Backbone, io, jQuery and $, etc). You simply provide that variable name as the exports property, and requirejs will be able to determine when the lib is loaded.
Once your definitions are done, you can use requirejs' define function as expected.
Here's my example require.config object:
require.config({
baseUrl: "/js/",
paths: {
jquery: 'jquery',
socketio: 'http://localhost:8000/socket.io/socket.io', //for loading the socket.io client library
highcharts: 'libs/highcharts/highcharts.src',
underscore: 'libs/underscore',
backbone: 'libs/backbone'
},
shim: {
jquery: {
exports: 'jQuery'
},
socketio: {
exports: 'io'
},
underscore: {
exports: '_'
},
backbone: {
deps: ['jquery', 'underscore'],
exports: 'Backbone'
},
highcharts: {
deps: ['jquery'],
exports: 'Highcharts'
}
}
});
As pabera mentioned before, this is for Require.JS version 2.0.1.
I hope someone gets some use out of this; I know it road blocked me for a little while; so hopefully we kept you from banging your head into the same spot in the wall that we did, by posting this.
I had the exact same problem and I was struggling around many hours until I saw your entry here. Then I started over from scratch and now it works for me at least.
requirejs.config({
baseUrl:'/js/',
paths:{
jquery:'vendor/jquery',
handlebars: 'vendor/handlebars',
text: 'vendor/require-text',
chaplin:'vendor/chaplin',
underscore:'vendor/underscore',
backbone:'vendor/backbone',
highcharts: 'vendor/highcharts'
},
shim: {
backbone: {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
underscore: {
exports: '_'
},
highcharts: {
exports: 'Highcharts'
}
},
});
Since I use Chaplin on top of Backbone, I am including some more files in my paths attribute. Highcharts has a similar structure to Backbone so I thought I could load it the same way. It works for me now. As you can see, I am introducing highcharts in the paths attribute already to export it as a shim afterwords.
Maybe this helps, otherwise let's try to contribute on it even more to solve your problem.
Although jQuery can be used as an AMD module it will still export itself to the window anyway so any scripts depending on the global jQuery or $ will still work as long as jQuery has loaded first.
Have you tried setting a path? jQuery is an interesting one because although you're encoruaged not to name your modules by the RequireJS documentation, jQuery actually does.
From the jQuery source
if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
define( "jquery", [], function () { return jQuery; } );
}
What that means is you will need to tell RequireJS where to find 'jquery'. So:
require.config({
paths: {
'jquery': 'path/to/jquery'
}
});
If you're interested in why jQuery registers itself this way then there is a pretty large comment in the source which goes into more detail

Categories

Resources