How can I use requireJS and jQuery together?

I would like to use requireJS and I am using jQuery. I do not want to use a combined version of requireJS and jQuery, since I do not use the latest version of jQuery. What is the best way to work with requireJS?

+80
jquery requirejs
Dec 26 2018-10-12-26
source share
5 answers

This is also my exact question! I should also use older jQuery, but also more "traditional" javascript libraries. What is the best technique for this? (I can change your question to make it wider if you don't mind.) Here's what I learned.

RequireJS + jQuery combined the requirements of JS by James Burke. You get two things.

  • The jquery module is available, and it is a jQuery object. It's safe:

     // My module depends on jQuery but what if $ was overwritten? define(["jquery"], function($) { // $ is guaranteed to be jQuery now */ }) 
  • jQuery is already loaded before any require() or define() tags. All modules ensure jQuery is ready. You don't even need the require/order.js , since jQuery was basically hard-coded to load.

To me, # 2 is not very helpful. Most real applications have many .js files that should load in the correct order, but true. Once you need Sammy or Underscore.js, the combined RequireJS + jQuery file will not help.

My solution is to write simple RequireJS shells that load my traditional scripts using the "order" plugin.

Example

Suppose my application has these components (depending).

  • My greatapp app
    • greatapp depends on custom jquery (old version I have to use)
    • greatapp depends on my_sammy (SammyJS plus all of its plugins I have to use). These should be fine
      • my_sammy depends on jquery (SammyJS is a jQuery plugin)
      • my_sammy depends on sammy.js
      • my_sammy depends on sammy.json.js
      • my_sammy depends on sammy.storage.js
      • my_sammy depends on sammy.mustache.js

In my opinion, everything above that ends with .js is a "traditional" script. All without .js is a RequireJS plugin. Key: high-level stuff (greatapp, my_sammy) is modules, and at deeper levels, it goes back to traditional .js files.

Loading

It all starts with the booter telling RequireJS how to get started.

 <html> <head> <script data-main="js/boot.js" src="js/require.js"></script> </head> </html> 

In js/boot.js I put only the configuration and how to start the application.

 require( // The "paths" maps module names to actual places to fetch the file. // I made modules with simple names (jquery, sammy) that will do the hard work. { paths: { jquery: "require_jquery" , sammy : "require_sammy" } } // Next is the root module to run, which depends on everything else. , [ "greatapp" ] // Finally, start my app in whatever way it uses. , function(greatapp) { greatapp.start(); } ); 

Main application

In greatapp.js I have a normal module.

 define(["jquery", "sammy"], function($, Sammy) { // At this point, jQuery and SammyJS are loaded successfully. // By depending on "jquery", the "require_jquery.js" file will run; same for sammy. // Those require_* files also pass jQuery and Sammy to here, so no more globals! var start = function() { $(document).ready(function() { $("body").html("Hello world!"); }) } return {"start":start}; } 

Required module modules around traditional files

require_jquery.js :

 define(["/custom/path/to/my/jquery.js?1.4.2"], function() { // Raw jQuery does not return anything, so return it explicitly here. return jQuery; }) 

require_sammy.js :

 // These must be in order, so use the "order!" plugin. define([ "order!jquery" , "order!/path/to/custom/sammy/sammy-0.6.2-min.js" , "order!/path/to/custom/sammy/plugins/sammy.json-0.6.2-min.js" , "order!/path/to/custom/sammy/plugins/sammy.storage-0.6.2-min.js" , "order!/path/to/custom/sammy/plugins/sammy.mustache-0.6.2-min.js" ] , function($) { // Raw sammy does not return anything, so return it explicitly here. return $.sammy; } ); 
+126
Dec 29 '10 at 6:58
source share

This question is at least two years old, but I noticed that this is a problem with RequireJS 2.0 (require-jquery.js uses jQuery 1.8.0, but the latest version is 1.8.2).

If you come across this question, note that require-jquery.js now just requires .js and jquery.js aligned together. You can simply edit require-jquery.js and replace the parts of jQuery with a newer version .

Update (May 30, 2013) : Now that RequireJS has paths and shims, there is a new way to import jQuery and jQuery plugins, and the old method is no longer needed, but recommended . The following is an abridged version of the current method:

 requirejs.config({ "paths": { "jquery": "//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min" } }); define(["jquery"], function($) { $(function() { }); }); 

See http://requirejs.org/docs/jquery.html for more details.

+32
Sep 25 '12 at 23:21
source share

I found a better approach - keep jQuery outside the RequireJS assembly.

Just include jquery.min.js in your HTML. Then create a jquery.js file with something like this ...

 define([], function() { return window.$; }); 
+6
Apr 28 '14 at 9:16
source share

Found JasonSmith anwer extremely useful, perhaps more than RequireJS documentation.

However, it is possible to optimize it to avoid separate AJAX requests for (tiny) declaration-of-declaration modules ("require_jquery" "require_sammy"). I would suggest that r.js will do this at the optimization stage, but you can do it ahead of time so as not to battle Path, the BaseURI system.

index.html

 <html> <head> <script data-main="js/loader.js" src="js/require.js"></script> </head> </html> 

loader.js:

 // We are going to define( dependencies by hand, inline. // There is one problem with that through (inferred from testing): // Dependencies are starting to load (and execute) at the point of declaring the inline // define, not at the point of require( // So you may want to nest the inline-defines inside require( // this is, in a way, short replacement for Order plug in, but allows you to use // hand-rolled defines, which the Order plug in, apparently does not allow. var jQueryAndShims = ['jquery'] if(window.JSON == null){ jQueryAndShims.push('json2') define( 'json2' , ['js/libs/json2.min.js'] , function() { return window.JSON } ) } // will start loading the second we define it. define( 'jquery' , ['js/libs/jquery_custom.min.js'] , function() { // we just pick up global jQuery here. // If you want more than one version of jQuery in dom, read a more complicated solution discussed in // "Registering jQuery As An Async-compatible Module" chapter of // http://addyosmani.com/writing-modular-js/ return window.jQuery } ) // all inline defines for resources that don't rely on other resources can go here. // First level require( // regardless of depends nesting in 'myapp' they will all start downloading // at the point of define( and exec whenever they want, // async in many browsers. Actually requiring it before the nested require makes // sure jquery had *executed and added jQuery to window object* before // all resolved depends (jquery plugins) start firing. require(jQueryAndShims, function($) { // will start loading the second we define it. define( 'sammy_and_friends' , ['jquery','js/libs/jquery_pluginone.min.js','js/libs/jquery_plugintwo.min.js','js/libs/sammy.min.js'] , function($) { // note, all plugins are unaltered, as they are shipped by developers. // in other words, they don't have define(.. inside. // since they augment global $ (window.jQuery) anyway, and 'jquery' define above picks it up // , we just keep on returning it. // Sammy is attached to $ as $.sammy, so returning just Sammy makes little sense return $ } ) // second level require - insures that Sammy (and other jQuery plugins) - 'sammy_and_friends' - is // loaded before we load Sammy plugins. I normally i would inline all sammy plugins i need // (none, since i use none of them preferring jQuery direct templating API // and no other Sammy plug in is really of value. ) right into sammy.js file. // But if you want to keep them separate: require(['sammy_and_friends'], function() { // will start loading the second we define it. define( 'sammy_extended' , ['sammy_and_friends','js/libs/sammy_pluginone.min.js','js/libs/sammy_plugintwo.min.js'] , function($) { // as defined above, 'sammy_and_friends' actually returns (globall) jQuery obj to which // Sammy is attached. So we continue to return $ return $ } ) // will start loading the second we define it. define( 'myapp' , ['sammy_extended', 'js/myapplication_v20111231.js'] , function($, myapp_instantiator) { // note, myapplication may, but does not have to contain RequireJS-compatible define // that returns something. However, if it contains something like // "$(document).ready(function() { ... " already it MAY fire before // it depends - 'sammy_extended' is fully loaded. // Insdead i recommend that myapplication.js returns a generator // (app-object-generating function pointer) // that takes jQuery (with all loaded , applied plugins) // The expectation is that before the below return is executed, // all depends are loaded (in order of depends tree) // You would init your app here like so: return myapp_instantiator($) // then "Run" the instance in require( as shown below } ) // Third level require - the one that actually starts our application and relies on // dependency pyramid stat starts with jQuery + Shims, followed by jQuery plugins, Sammy, // followed by Sammy plugins all coming in under 'sammy_extended' require(['jquery', 'myapp'], function($, myappinstance) { $(document).ready(function() {myappinstance.Run()}) }) }) // end of Second-level require }) // end of First-level require 

finally myapplication.js:

 // this define is a double-wrap. // it returns application object instantiator that takes in jQuery (when it available) and , then, that // instance can be "ran" by pulling .Run() method on it. define(function() { // this function does only two things: // 1. defines our application class // 2. inits the class and returns it. return function($) { // 1. defining the class var MyAppClass = function($) { var me = this this._sammy_application = $.sammy(function() { this.raise_errors = true this.debug = true this.run_interval_every = 300 this.template_engine = null this.element_selector = 'body' // .. }) this._sammy_application.route(...) // define your routes ets... this.MyAppMethodA = function(blah){log(blah)} // extend your app with methods if you want // ... // this one is the one we will .Run from require( in loader.js this.Run = function() { me._sammy_application.run('#/') } } // 2. returning class instance return new MyAppClass($) // notice that this is INITED app, but not started (by .Run) // .Run will be pulled by calling code when appropriate } }) 

This structure (freely replaces (duplicates?) The RequireJS Order plugin, but) allows you to reduce the number of files you need for AJAX by adding more control to the definition of the tree of dependent and dependent.

There is also a big bonus to downloading jQuery separately (usually at 100k) - you can control caching on the server or cache jQuery in the localStorage browser. Take a look at the AMD-Cache project here https://github.com/jensarps/AMD-cache , then change the definition (instructions that include "cache!": And it will (forever :)) stuck in the user browser.

 define( 'jquery' , ['cache!js/libs/jquery_old.min.js'] , function() { // we just pick up global jQuery here. // If you want more than one version of jQuery in dom, read a more complicated solution discussed in // "Registering jQuery As An Async-compatible Module" chapter of // http://addyosmani.com/writing-modular-js/ return window.jQuery } ) 

A note on jQuery 1.7.x + It no longer attaches to the window object, so it will NOT work with the unchanged jQuery 1.7.x + file above. There you should configure jquery **. Js to enable this before closing "}) (window);":

 ;window.jQuery=window.$=jQuery 

If you have jQuery undefined errors in the console, then the version of the jQuery icon you are using does not snap to the window.

License Code: Public domain.

Disclosure: JavaScript over the odors of "pseudo-code", as it is a rephrasing (manual trimming) of a much more detailed production code. The code presented above is not guaranteed to work and has NOT been tested to work as presented. Audit, test it. The semicolons are omitted specifically, since they are not required for the JS specification, and the code looks better without them.

+3
Dec 14 '11 at 19:15
source share

In addition to the jhs answer, see more recent instructions on the require-jquery github page from the README.md file. It covers both the simplest approach to using a jquery / require.js combined file, and how to use a separate jquery.js.

+1
Jul 05 2018-11-11T00:
source share



All Articles