Question

Je voudrais utiliser requireJS et je suis en utilisant jQuery. Je ne veux pas utiliser la version combinée de requireJS et jQuery depuis que je ne suis pas en utilisant la dernière version de jQuery. Quelle est la meilleure façon pour moi de travailler avec requireJS?

Était-ce utile?

La solution

C'est ma question exacte aussi! Je dois aussi utiliser un jQuery plus, mais aussi plus de bibliothèques javascript « traditionnelles ». Quelle est la meilleure technique pour le faire? (Je modifier votre question pour le rendre plus large si vous ne me dérange pas.) Voici ce que j'appris.

auteur RequireJS, James Burke, a expliqué les avantages du combiné RequireJS + fichier jQuery . Vous obtenez deux choses.

  1. Un module, jquery, est disponible, et il est l'objet jQuery. Ceci est sûr:

    // My module depends on jQuery but what if $ was overwritten?
    define(["jquery"], function($) {
      // $ is guaranteed to be jQuery now */
    })
    
  2. jQuery est déjà chargé avant toute substance de require() ou define(). Tous les modules sont garantis que jQuery est prêt. Vous ne même pas besoin du plugin require/order.js depuis jQuery était essentiellement codé en dur pour charger d'abord.

Pour moi, # 2 est pas très utile. La plupart des applications réelles ont beaucoup fichiers .js que doit charge dans le bon ordre triste mais vrai. Dès que vous avez besoin Sammy ou Underscore.js, le combiné RequireJS + fichier jQuery ne l'aide.

Ma solution est d'écrire des emballages simples de RequireJS qui charge mes scripts traditionnels en utilisant le plug-in "de commande".

Exemple

Supposons que mon application a ces composants (par la dépendance).

  • Mon application, Greatapp
    • Greatapp dépend d'une mesure jquery (ancienne version que je dois utiliser)
    • Greatapp dépend de my_sammy (SammyJS plus tous ses plug-ins je dois utiliser). Ces doit être en ordre
      1. my_sammy dépend de jquery (SammyJS est un plugin jQuery)
      2. my_sammy dépend de sammy.js
      3. my_sammy dépend de sammy.json.js
      4. my_sammy dépend de sammy.storage.js
      5. my_sammy dépend de sammy.mustache.js

Dans mon esprit, tout ce qui précède qui se termine par .js est un script « traditionnel ». Tout sans .js est un plugin RequireJS. La clé est:. Substance de haut niveau (Greatapp, my_sammy) sont des modules et à des niveaux plus profonds, il retombe aux fichiers .js traditionnels

Amorçage

Tout commence par un booter dire RequireJS comment démarrer.

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

En js/boot.js je mets que la configuration et la façon de démarrer l'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(); }
       );

Application principale

Dans greatapp.js J'ai un module recherche normal.

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

RequireJS Module wrappers autour des fichiers traditionnels

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

Autres conseils

Cette question est au moins deux ans, mais je remarque cela est un problème encore avec RequireJS 2.0 (nécessite-jquery.js utilise jQuery 1.8.0, mais la dernière version est 1.8.2).

Si vous arrive de voir cette question, notez que require-jquery.js est maintenant juste require.js et jquery.js, brassés ensemble. Vous pouvez simplement modifier require-jquery. js et remplacer les pièces du jQuery avec une version plus récente .

Mise à jour (le 30 mai 2013) : Maintenant que RequireJS a des chemins et Shim, il y a une nouvelle façon d'importer jQuery et plugins jQuery, et l'ancienne méthode est plus nécessaire ni recommandé . Voici une version abrégée de la méthode actuelle:

requirejs.config({
    "paths": {
      "jquery": "//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min"
    }
});

define(["jquery"], function($) {
    $(function() {
    });
});

Voir http://requirejs.org/docs/jquery.html pour plus d'informations.

J'ai trouvé la meilleure approche est de garder jQuery en dehors de ma construction de RequireJS.

Il suffit d'inclure jquery.min.js dans votre code HTML. Ensuite, faire un fichier jquery.js avec quelque chose comme ça ...

define([], function() {
    return window.$;
});

Trouvé le anwer de Jason Smith extrêmement utile, probablement plus que la documentation des RequireJS.

Cependant, il y a moyen d'optimiser sur elle pour éviter que des demandes d'AJAX distinctes pour les (petites) modules définissent-déclarant ( « require_jquery » « require_sammy »). Je suppose r.js le feraient à l'étape d'optimisation, mais vous pouvez le faire à l'avance afin de ne pas se battre avec le chemin, le système baseURI.

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's 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's 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's 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

enfin, myapplication.js:

// this define is a double-wrap.
// it returns application object instantiator that takes in jQuery (when it's 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's instance
        return new MyAppClass($) // notice that this is INITED app, but not started (by .Run) 
        // .Run will be pulled by calling code when appropriate
    }
})

Cette structure (lâchement (doublons? Remplace) le plugin Order RequireJS, mais) vous permet d'élaguer le nombre de fichiers dont vous avez besoin pour AJAX, en ajoutant plus de contrôle à la définition de dépend et dépendent arbre.

Il y a aussi un grand bonus à chargement jQuery séparément (ce qui est habituellement à 100k) - vous pouvez contrôler la mise en cache au serveur ou jQuery cache dans localStorage du navigateur. Jetez un oeil à projet AMD-Cache ici https://github.com/jensarps/AMD-cache puis modifiez les define (déclarations d'inclure « cache! ». et il sera (toujours :)) coincé dans le navigateur de l'utilisateur

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

Note à propos de jQuery 1.7.x + Elle ne se fixe à l'objet de la fenêtre, de sorte que ce qui précède ne fonctionnera pas avec jQuery sans modification de fichier 1.7.x +. Il vous devez personnaliser votre jquery ** js d'inclure ce avant la fermeture « }) (fenêtre); ».

;window.jQuery=window.$=jQuery

Si vous avez « jQuery non défini » erreurs dans la console, il est une version jQuery signe que vous utilisez n'est pas de se fixer à la fenêtre.

Code de licence:. Domaine public

Informations à fournir: JavaScript sent au-dessus de « pseudo-code », comme il est une paraphrase (main-taille) du code de production beaucoup plus détaillée. Code tel que présenté ci-dessus n'est pas garanti au travail et n'a pas été testé au travail tel que présenté. Audit, le tester. Omis des points-virgules sur le but, car ils ne sont pas tenus par spec JS et code semble mieux sans eux.

En plus de la réponse de JHS, consultez les instructions les plus récentes sur le require-jquery github à partir du fichier README.md. Il couvre à la fois l'approche la plus simple d'utiliser un combiné jquery / fichier require.js et aussi comment utiliser un jquery.js séparés.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top