Domanda

Vorrei utilizzare requireJS e sto usando jQuery. Non voglio usare la versione combinata di requireJS e jQuery dal momento che non sto usando l'ultima versione di jQuery. Qual è il modo migliore per me di lavorare con requireJS?

È stato utile?

Soluzione

Questa è la mia domanda esatta troppo! Devo anche usare un vecchio jQuery, ma anche più librerie javascript "tradizionali". Qual è la tecnica migliore per farlo? (Posso modificare la tua domanda per renderlo più ampio, se non ti dispiace.) Ecco quello che ho imparato.

RequireJS autore, James Burke, ha spiegato le vantaggi del file RequireJS + jQuery combinato . È possibile ottenere due cose.

  1. Un modulo, jquery, è disponibile, ed è l'oggetto jQuery. Questo è sicuro:

    // My module depends on jQuery but what if $ was overwritten?
    define(["jquery"], function($) {
      // $ is guaranteed to be jQuery now */
    })
    
  2. jQuery è già caricato prima di qualsiasi roba require() o define(). Tutti i moduli sono garantiti che jQuery è pronto. Non è nemmeno necessario il plugin jQuery require/order.js poiché era fondamentalmente hard-coded per caricare prima.

Per me, 2 # non è molto utile. La maggior parte delle applicazioni reali hanno molti file .js che deve di carico nel giusto ordine, triste ma vero. Non appena avete bisogno di Sammy o Underscore.js, il file RequireJS + jQuery combinato non aiuta.

La mia soluzione è quella di scrivere semplici RequireJS wrapper che caricano i miei script tradizionali utilizzando il plugin "ordine".

Esempio

Supponiamo che la mia applicazione ha queste componenti (da dipendenza).

  • La mia app, Greatapp
    • Greatapp dipende da una personalizzato jquery (vecchia versione devo usare)
    • Greatapp dipende dalla my_sammy (SammyJS più tutti i suoi plugin devo usare). Questi deve essere in ordine
      1. my_sammy dipende dalla jquery (SammyJS è un plugin jQuery)
      2. my_sammy dipende dalla sammy.js
      3. my_sammy dipende dalla sammy.json.js
      4. my_sammy dipende dalla sammy.storage.js
      5. my_sammy dipende dalla sammy.mustache.js

Nella mia mente, tutto sopra che termina con .js è uno script "tradizionale". Tutto senza .js è un plugin RequireJS. La chiave è:. Roba di alto livello (Greatapp, my_sammy) sono moduli, ed a livelli più profondi, cade di nuovo al file .js tradizionali

Avvio

Tutto inizia con un booter dicendo RequireJS come iniziare.

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

In js/boot.js ho messo solo la configurazione e su come avviare l'applicazione.

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

Principali applicazioni

In greatapp.js ho un modulo di ricerca normale.

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 modulo wrapper intorno file tradizionali

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

Altri suggerimenti

Questa domanda è di almeno due anni ormai, ma ho notato che questo è un problema ancora con RequireJS 2.0 (richiede-jquery.js utilizza jQuery 1.8.0, ma l'ultima versione è 1.8.2).

Se vi capita di vedere questa domanda, si noti che require-jquery.js è ormai solo require.js e jquery.js, purè insieme. si può semplicemente modificare richiedere-jQuery. js e sostituire le parti del jQuery con una versione più recente .

Aggiorna (30 maggio 2013) : Ora che RequireJS ha percorsi e spessore, c'è un nuovo modo per importare jQuery e jQuery plugin, e il vecchio metodo non è più necessario né consigliato . Qui è una versione ridotta del metodo corrente:

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

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

http://requirejs.org/docs/jquery.html per maggiori informazioni.

Ho trovato l'approccio migliore è quello di mantenere jQuery di fuori della mia RequireJS compilazione.

Proprio includono jquery.min.js nel codice HTML. Quindi, creare un file jquery.js con qualcosa di simile ...

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

Trovato anwer di Jason Smith estremamente utile, probabilmente più di documentazione del RequireJS.

Tuttavia, non c'è modo per ottimizzare su di esso per evitare di avere richieste AJAX separate per i (piccoli) Moduli definire-dichiarando ( "require_jquery" "require_sammy"). Ho il sospetto r.js lo farebbero in fase di ottimizzazione, ma si può fare prima del tempo al fine di non combattere con il percorso, il sistema 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

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

Questa struttura (liberamente Sostituisce (duplicati?) Ordinare il plugin di RequireJS, ma) consente di potare il numero di file è necessario AJAX, l'aggiunta più controllo per definizione dipende e dipenderà albero.

V'è anche un grande bonus per carico jQuery a parte (che di solito arriva a 100k) - è possibile controllare la memorizzazione nella cache sul server, o di cache di jQuery in localStorage del browser. Date un'occhiata al progetto di AMD-Cache qui https://github.com/jensarps/AMD-cache quindi modificare l'define (dichiarazioni di includere "cache":. e sarà (per sempre :)) bloccato nel browser dell'utente

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

Nota su jQuery 1.7.x + non è più si attacca a oggetto finestra, in modo che il lavoro di cui sopra sarà NON con jQuery non modificato 1.7.x + file. Ci si deve personalizzare il jquery ** js per includere questo prima della chiusura "}) (finestra);".

;window.jQuery=window.$=jQuery

Se si dispone di "jQuery undefined" errori nella console, si tratta di una versione di jQuery segno che si sta utilizzando non si sta collegando alla finestra.

licenza Codice:. Dominio pubblico

Informazioni integrative: JavaScript sopra profuma di "pseudo-codice" in quanto è una parafrasi (mano potatura) del codice di produzione molto più dettagliata. Codice come presentato di cui sopra non è garantito per lavoro e non è stato testato al lavoro così come presentato. Audit, testarlo. Punto e virgola omesso di proposito, in quanto non sono necessari per JS spec e codice è meglio senza di loro.

In aggiunta alla risposta di JHS, vedere le istruzioni più recenti sul richiedere-jquery pagina GitHub dal file README.md. Esso riguarda sia l'approccio più semplice di utilizzare un jquery combinato / require.js di file e anche il modo di utilizzare un jquery.js separate.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top