Con i moduli di stile AMD in JavaScript c'è qualche vantaggio per gli spazi dei nomi?

2

Provenendo da C ++ originariamente e vedendo molti programmatori Java fare lo stesso, abbiamo portato gli spazi dei nomi in JavaScript. Vedi la biblioteca di chiusura di Google come esempio in cui hanno uno spazio dei nomi principale, goog e sotto che molti altri spazi dei nomi come < a href="http://docs.closure-library.googlecode.com/git/namespace_goog_async.html"> goog.async , goog.graphics

Ma ora, dopo aver imparato lo stile AMD di richiedere moduli sembra che gli spazi dei nomi siano praticamente inutili in JavaScript. Non solo inutile ma anche discutibilmente un anti-modello.

Che cos'è AMD? È un modo di definire e includere moduli che rimuovono tutte le dipendenze dirette. Effettivamente lo fai

// some/module.js
define([
    'name/of/needed/module',
    'name/of/someother/needed/module',
  ], function(
     RefToNeededModule,
     RefToSomeOtherNeededModule) {

  ...code...

  return object or function
});

Questo formato consente al codice di supporto AMD di sapere che questo modulo ha bisogno di name/of/needed/module.js e name/of/someother/needed/module.js caricato. Il codice AMD può caricare tutti i moduli e quindi, supponendo che non ci siano dipendenze circolari, chiamare la funzione define su ciascun modulo nell'ordine corretto, registrare l'oggetto / funzione restituita dal modulo mentre li chiama e quindi chiamare qualsiasi altro modulo ' define funzione con riferimenti a quei moduli.

Questo sembra rimuovere qualsiasi necessità per gli spazi dei nomi. Nel tuo codice puoi chiamare il riferimento a qualsiasi altro modulo tutto ciò che desideri. Ad esempio, se si dispone di 2 librerie di stringhe, anche se definiscono funzioni simili, purché seguano il pattern AMD, è possibile utilizzarle facilmente nello stesso modulo. Non c'è bisogno di spazi dei nomi per risolverlo.

Significa anche che non ci sono dipendenze hard coded. Ad esempio, nella chiusura di Google qualsiasi modulo potrebbe fare riferimento direttamente a un altro modulo con qualcosa come var value = goog.math.someMathFunc(otherValue) e se sei sfortunato funzionerà magicamente dove, come con lo stile AMD, dovresti includere esplicitamente la libreria matematica altrimenti il modulo non avrebbe un riferimento ad esso in quanto non ci sono globali con AMD.

Oltre a questa dipendenza, l'iniezione per i test diventa facile. Nessuno del codice nel modulo AMD fa riferimento a elementi per namespace, quindi non ci sono percorsi di namespace con hardcoded, puoi facilmente prendere in giro le classi al momento del test.

C'è qualche altro punto per gli spazi dei nomi o è qualcosa che i programmatori C ++ / Java stanno portando a JavaScript che probabilmente non appartiene veramente?

    
posta gman 27.05.2014 - 07:12
fonte

2 risposte

2

Riepilogo esecutivo di seguito.

I should actually start a blog instead of writing it here, but hey. live with it ;) this is also a opinion, everything in this 'answer' is how I program, and what I think is best. Don't aggree? feel free to send and email to /dev/null or comment :)

Personalmente ritengo che JavaScript e gli spazi dei nomi non dovrebbero essere usati insieme. JavaScript è un linguaggio JIT. E questo ci dà un sacco di cose buone con cui lavorare.

I più grandi siti web per i problemi di velocità sono richieste HTTP aggiuntive che ottengono risorse extra dal server. Tutto dentro e rallenta la velocità di caricamento. I Webdevelopers tendono quindi a caricare solo le librerie critiche in testa (modernizr, ...) e caricare l'altro JS nella parte inferiore del tag.

Funziona nei browser moderni dal momento in cui iniziano il rendering dopo aver letto la prima riga del documento. La pagina tuttavia non ha completato il caricamento fino a quando non è stato caricato tutto il file JS. Quindi gli utenti visivi avranno un tempo di risposta migliore, ma questo è semplicemente perché abbiamo rinviato il caricamento.

Quindi abbiamo aggiunto tecniche di caricamento asincrone. Invece di aggiungere un tag, aggiungiamo un piccolo script che scrive un tag sul DOM. Il piccolo script che crea il tag viene caricato in modo sincrono, ma il caricamento dello stesso avviene in modo asincrono e non rallenta il tempo di caricamento della pagina (ad esempio, l'evento domready non attende il caricamento). Ma poi c'è il problema delle dipendenze. Non abbiamo alcun controllo sull'ordine in cui questi script vengono caricati ora. (Un buon esempio di questo è lo script asincrono GA).

Arriva AMD. Invece di caricare tutti i file JS di cui potremmo aver bisogno da qualche parte nell'applicazione (uno potrebbe aggiungere qualche ottimizzazione nelle viste / CMS ma semplicemente sbaglia) non cariciamo nulla (solo il caricatore AMD) e rimandiamo il caricamento di tutto il resto per dopo.

Quindi, spesso su un evento domready o simile (tag bottom) iniziamo la nostra applicazione. per esempio:.

var myFancyStartUpModule = require('my/fancy/boot/module');
myFancyStartUpModule.init();

Ora, diciamo per qualche motivo, abbiamo bisogno di una seconda istanza del nostro fantastico modulo di avvio. Quindi si farebbe:

var mySecondFancyStartUpModule = new FancyStartUpModule();

Questo errore di corso. Quindi proviamo questo:

var mySecondFancyStartUpModule = new my\Fancy\boot\Module();

Ancora, errore di sintassi. Ofcourse, dimenticato. I namespace non esistono realmente. Ciò che esiste è un oggetto mio, che ha l'oggetto di fantasia, quindi usiamolo.

var mySecondFancyStartUpModule = new my.fancy.boot.Module();

Quindi stiamo usando object to namespace (ieuk) e questo sarà ancora un errore perché my.fancy.boot.Module non esiste nello scope della finestra. E questa è la roba buona su javascript.

Perché tutto il mio modulo di fantasia è definito all'interno di quella funzione define che non esiste nello scope della finestra. Significa che tutto ciò che vuole usare quel pezzo di codice, deve usare require() (o impostare dipendenze in define() ). Questo ti dà le parti dolci di javascript come la creazione di oggetti al volo, il binding di this , la prototipazione ma la robustezza di uno stile di programmazione simile a IOC.

Tendo sempre ad usare uno stile di programmazione simile ad Adattatore nei miei script AMD. Invece di scrivere

require('vendor/fancy/module/for/pdf');

Ho un adattatore pdf:

require('app/adapter/pdf');

Ora, trovo questa libreria pdf davvero dolce non scritta da Fancy incontrata da ultraFancy. Semplicemente cambio una riga di codice nel mio adattatore, e all'improvviso tutto nella mia applicazione utilizza la nuova libreria pdf di ultraFancy.

Sommario esecutivo:

Per rispondere alla tua domanda. I namespace in JS si sentono davvero stupidi. Perché gli spazi dei nomi non esistono in JS. Tuttavia, abbiamo oggetti con argomenti pubblici. E questi argomenti possono essere anche oggetti. E possiamo aggiungere roba agli oggetti al volo (davvero bella). Ma scrivere new namespaced.module.inside.an.object(); non sembra proprio giusto. Semplicemente perché non solo abbiamo molestato questi begli oggetti, c'è anche un oggetto inutilizzato nell'oggetto window . Tutto il codice è accessibile e, oh mio Dio, non mi fido di me stesso con quel potere. A I'll just do a quick fix for now diventa I'll just add this code to the previous fix codebase e diventa rapidamente require('app/fixes/all.min') .

Quindi, non usare namespace in JS, non ne hai bisogno. Pensa a tutti quegli oggetti molestati: (

    
risposta data 27.05.2014 - 07:59
fonte
-1

Per le richieste HTTP, usa un combohandler amico mio. :) Molto semplice in PHP / NodeJS e rende banale il caching. La maggior parte dei framework di caricamento dei moduli AMD ne ha uno disponibile, è quasi un dato di fatto.

Ad esempio: link

È solo per mancanza di conoscenza che le app AMD (o qualsiasi altra cosa) non hanno cose come i combohandler lato server (o anche quelli lato client, se dovevano essere abbastanza patch per scimmia).

Inoltre, la maggior parte delle librerie di stili AMD (ad es. Dojo) consentono lo spazio dei nomi in particolare per il beneficio di correggere i problemi sopra menzionati in cui è possibile creare una configurazione del caricatore che rinomina queste cose.

    
risposta data 31.01.2015 - 02:46
fonte

Leggi altre domande sui tag