Best practice comunemente accettate in merito all’organizzazione del codice in JavaScript

Poiché i framework JavaScript come jQuery rendono le applicazioni web lato client più ricche e più funzionali, ho iniziato a notare un problema …

Come diavolo mantieni questo organizzato?

  • Metti tutti i tuoi gestori in un punto e scrivi le funzioni per tutti gli eventi?
  • Creare funzioni / classi per avvolgere tutte le tue funzionalità?
  • Scrivi come un matto e spera solo che funzioni per il meglio?
  • Rinunciare e ottenere una nuova carriera?

Menziono jQuery, ma in realtà è un codice JavaScript in generale. Sto scoprendo che quando le linee su linee iniziano ad accumularsi, diventa più difficile gestire i file di script o trovare quello che stai cercando. Molto probabilmente i più grandi elementi che ho trovato è che ci sono così tanti modi per fare la stessa cosa, è difficile sapere qual è l’attuale best practice comunemente accettata.

Ci sono raccomandazioni generali sul modo migliore per mantenere i tuoi file .js belli e ordinati come il resto della tua applicazione? O è solo una questione di IDE? C’è un’opzione migliore là fuori?


MODIFICARE

Questa domanda era intesa per essere più sull’organizzazione di codice e non sull’organizzazione di file. Ci sono stati alcuni ottimi esempi di unione di file o di suddivisione del contenuto.

La mia domanda è: qual è l’attuale metodo di best practice comunemente accettato per organizzare il tuo codice attuale? Qual è il tuo modo, o anche un modo consigliato per interagire con gli elementi della pagina e creare codice riutilizzabile che non sia in conflitto tra loro?

Alcune persone hanno elencato spazi dei nomi che è una buona idea. Quali sono altri modi, più specificamente di trattare gli elementi sulla pagina e mantenere il codice organizzato e ordinato?

Sarebbe molto più carino se javascript avesse gli spazi dei nomi integrati, ma trovo che organizzare cose come Dustin Diaz qui mi aiuti molto.

var DED = (function() { var private_var; function private_method() { // do stuff here } return { method_1 : function() { // do stuff here }, method_2 : function() { // do stuff here } }; })(); 

Ho messo diversi “namespace” e talvolta singole classi in file separati. Di solito parto da un file e siccome una class o uno spazio dei nomi diventano abbastanza grandi da giustificarlo, lo separo nel suo stesso file. Usare uno strumento per combinare tutti i file per la produzione è un’ottima idea.

Cerco di evitare di includere qualsiasi javascript con l’HTML. Tutto il codice è incapsulato in classi e ogni class è nel proprio file. Per lo sviluppo, ho tag

In genere, avrò un singolo file js 'principale' per ogni applicazione. Quindi, se stavo scrivendo un'applicazione "sondaggio", avrei un file js chiamato "survey.js". Ciò conterrebbe il punto di ingresso nel codice jQuery. Creo riferimenti jQuery durante l'istanziazione e poi li passo come parametri ai miei oggetti. Ciò significa che le classi javascript sono "pure" e non contengono riferimenti a ID o nomi di classi CSS.

 // file: survey.js $(document).ready(function() { var jS = $('#surveycontainer'); var jB = $('#dimscreencontainer'); var d = new DimScreen({container: jB}); var s = new Survey({container: jS, DimScreen: d}); s.show(); }); 

Trovo anche che la convenzione di denominazione sia importante per la leggibilità. Ad esempio: aggiungo "j" a tutte le istanze di jQuery.

Nell'esempio sopra, c'è una class chiamata DimScreen. (Supponiamo che oscuri lo schermo e apra una finestra di avviso.) Ha bisogno di un elemento div che possa ingrandire per coprire lo schermo e quindi aggiungere una finestra di avviso, così passo in un object jQuery. jQuery ha un concetto di plug-in, ma sembrava limitativo (ad esempio, le istanze non sono persistenti e non possono essere consultate) senza un reale vantaggio. Quindi la class DimScreen sarebbe una class javascript standard che capita di usare jQuery.

 // file: dimscreen.js function DimScreen(opts) { this.jB = opts.container; // ... }; // need the semi-colon for minimizing! DimScreen.prototype.draw = function(msg) { var me = this; me.jB.addClass('fullscreen').append('
'+msg+'
'); //... };

Ho sviluppato alcune applicazioni abbastanza complesse usando questo approccio.

È ansible suddividere gli script in file separati per lo sviluppo, quindi creare una versione di “rilascio” in cui riunirli tutti insieme ed eseguire YUI Compressor o qualcosa di simile su di esso.

Ispirato ai post precedenti ho realizzato una copia di Rakefile e delle directory dei produttori distribuite con WysiHat (un RTE menzionato da changelog) e ho apportato alcune modifiche per includere il controllo del codice con JSLint e il minification con YUI Compressor .

L’idea è di usare Sprockets (da WysiHat) per unire più JavaScripts in un unico file, controllare la syntax del file unito con JSLint e ridurlo a YUI Compressor prima della distribuzione.

Prerequisiti

  • Java Runtime
  • gem di ruby e rastrello
  • Dovresti sapere come inserire un JAR in Classpath

Adesso fallo

  1. Scarica Rhino e metti il ​​JAR (“js.jar”) nel classpath
  2. Scarica YUI Compressor e metti il ​​JAR (build / yuicompressor-xyz.jar) sul classpath
  3. Scarica WysiHat e copia la directory “fornitore” nella radice del tuo progetto JavaScript
  4. Scarica JSLint per Rhino e inseriscilo nella directory “fornitore”

Ora crea un file chiamato “Rakefile” nella directory root del progetto JavaScript e aggiungi ad esso il seguente contenuto:

 require 'rake' ROOT = File.expand_path(File.dirname(__FILE__)) OUTPUT_MERGED = "final.js" OUTPUT_MINIFIED = "final.min.js" task :default => :check desc "Merges the JavaScript sources." task :merge do require File.join(ROOT, "vendor", "sprockets") environment = Sprockets::Environment.new(".") preprocessor = Sprockets::Preprocessor.new(environment) %w(main.js).each do |filename| pathname = environment.find(filename) preprocessor.require(pathname.source_file) end output = preprocessor.output_file File.open(File.join(ROOT, OUTPUT_MERGED), 'w') { |f| f.write(output) } end desc "Check the JavaScript source with JSLint." task :check => [:merge] do jslint_path = File.join(ROOT, "vendor", "jslint.js") sh 'java', 'org.mozilla.javascript.tools.shell.Main', jslint_path, OUTPUT_MERGED end desc "Minifies the JavaScript source." task :minify => [:merge] do sh 'java', 'com.yahoo.platform.yui.compressor.Bootstrap', '-v', OUTPUT_MERGED, '-o', OUTPUT_MINIFIED end 

Se hai fatto tutto correttamente, dovresti essere in grado di utilizzare i seguenti comandi nella tua console:

  • rake merge – per unire file JavaScript diversi in uno solo
  • rake check – per verificare la syntax del tuo codice (questa è l’attività di default , quindi puoi semplicemente digitare rake )
  • rake minify – per preparare la versione minificata del tuo codice JS

Sulla fusione di origine

Utilizzando Sprockets, il pre-processore JavaScript è ansible includere (o require ) altri file JavaScript. Utilizzare la seguente syntax per includere altri script dal file iniziale (denominato “main.js”, ma è ansible modificarlo nel Rakefile):

 (function() { //= require "subdir/jsfile.js" //= require "anotherfile.js" // some code that depends on included files // note that all included files can be in the same private scope })(); 

E poi…

Dai un’occhiata a Rakefile fornito con WysiHat per impostare il test dell’unità automatica. Bella roba 🙂

E ora per la risposta

Questo non risponde alla domanda originale molto bene. Lo so e mi dispiace, ma l’ho postato qui perché spero possa essere utile a qualcun altro per organizzare il loro casino.

Il mio approccio al problema è quello di fare la stessa modellazione orientata agli oggetti che posso e separare le implementazioni in file diversi. Quindi i conduttori dovrebbero essere il più corti ansible. L’esempio con List singleton è anche bello.

E i namespace … beh, possono essere imitati da una struttura dell’object più profonda.

 if (typeof org === 'undefined') { var org = {}; } if (!org.hasOwnProperty('example')) { org.example = {}; } org.example.AnotherObject = function () { // constructor body }; 

Non sono un grande fan delle imitazioni, ma questo può essere utile se hai molti oggetti che vorresti uscire dall’ambito globale.

L’organizzazione del codice richiede l’adozione di convenzioni e standard di documentazione:
1. Codice spazio dei nomi per un file fisico;

 Exc = {}; 

2. Classi di gruppo in questi spazi dei nomi javascript;
3. Impostare prototipi o funzioni o classi correlate per rappresentare oggetti del mondo reale;

 Exc = {}; Exc.ui = {}; Exc.ui.maskedInput = function (mask) { this.mask = mask; ... }; Exc.ui.domTips = function (dom, tips) { this.dom = gift; this.tips = tips; ... }; 

4. Impostare le convenzioni per migliorare il codice. Ad esempio, raggruppa tutte le sue funzioni o metodi interni nel suo attributo di class di un tipo di object.

 Exc.ui.domTips = function (dom, tips) { this.dom = gift; this.tips = tips; this.internal = { widthEstimates: function (tips) { ... } formatTips: function () { ... } }; ... }; 

5. Realizza documentazione di spazi dei nomi, classi, metodi e variabili. Se necessario, discutete anche di parte del codice (alcuni FI e Fors, di solito implementano una logica importante del codice).

 /** * Namespace  Example  created to group other namespaces of the "Example". */ Exc = {}; /** * Namespace  ui  created with the aim of grouping namespaces user interface. */ Exc.ui = {}; /** * Class  maskdInput  used to add an input HTML formatting capabilities and validation of data and information. * @ Param {String} mask - mask validation of input data. */ Exc.ui.maskedInput = function (mask) { this.mask = mask; ... }; /** * Class  domTips  used to add an HTML element the ability to present tips and information about its function or rule input etc.. * @ Param {String} id - id of the HTML element. * @ Param {String} tips - tips on the element that will appear when the mouse is over the element whose identifier is id  . */ Exc.ui.domTips = function (id, tips) { this.domID = id; this.tips = tips; ... }; 

Questi sono solo alcuni consigli, ma ciò ha aiutato molto nell’organizzazione del codice. Ricorda che devi avere la disciplina per avere successo!

Seguire i principi di progettazione OO e gli schemi di progettazione di buona qualità è molto importante per semplificare la manutenzione e la comprensione del codice. Ma una delle cose migliori che ho scoperto di recente sono i segnali e le slot aka publish / subscribe. Dai un’occhiata a http://markdotmeyer.blogspot.com/2008/09/jquery-publish-subscribe.html per una semplice implementazione jQuery.

L’idea è ben utilizzata in altre lingue per lo sviluppo di GUI. Quando qualcosa di significativo accade da qualche parte nel tuo codice pubblichi un evento sintetico globale a cui altri metodi in altri oggetti possono iscriversi. Ciò offre un’eccellente separazione degli oggetti.

Penso che Dojo (e Prototype?) Abbiano una versione integrata di questa tecnica.

vedi anche Cosa sono i segnali e le slot?

Sono stato in grado di applicare correttamente il Pattern Module Javascript a un’applicazione Ext JS al mio precedente lavoro. Ha fornito un modo semplice per creare codice ben incapsulato.

Dojo ha avuto il sistema del modulo dal primo giorno. In realtà è considerato una pietra angular del Dojo, la colla che tiene tutto insieme:

  • dojo.require – il documento ufficiale .
  • Comprensione dojo.declare, dojo.require e dojo.provide .
  • Presentazione di Dojo .

Utilizzando i moduli Dojo raggiunge i seguenti obiettivi:

  • Namespace per codice Dojo e codice personalizzato ( dojo.declare() ): non inquinano lo spazio globale, coesistono con altre librerie e il codice utente non compatibile con Dojo.
  • Caricamento dei moduli in modo sincrono o asincrono per nome ( dojo.require() ).
  • Le build personalizzate analizzano le dipendenze dei moduli per creare un singolo file o un gruppo di file interdipendenti (i cosiddetti livelli) per includere solo ciò di cui ha bisogno l’applicazione web. Le build personalizzate possono includere anche moduli Dojo e moduli forniti dal cliente.
  • Accesso basato su CDN trasparente a Dojo e codice utente. Sia AOL che Google portano Dojo in questo modo, ma alcuni clienti lo fanno anche per le loro applicazioni web personalizzate.

Controlla JavasciptMVC .

Puoi :

  • suddividere il codice in livelli di modello, visualizzazione e controller.

  • comprimi tutto il codice in un unico file di produzione

  • codice auto-generato

  • creare ed eseguire test unitari

  • e molto altro…

Meglio ancora, usa jQuery, quindi puoi sfruttare anche altri plugin jQuery.

Il mio capo parla ancora delle volte in cui hanno scritto il codice modulare (linguaggio C) e si lamenta di quanto sia orribile il codice al giorno d’oggi! Si dice che i programmatori possano scrivere assembly in qualsiasi framework. C’è sempre una strategia per superare l’organizzazione del codice. Il problema di base è con ragazzi che trattano il java script come un giocattolo e non provano mai ad impararlo.

Nel mio caso, scrivo i file js su un tema dell’interfaccia utente o sullo schermo dell’applicazione, con una corretta init_screen (). Usando una corretta convenzione di denominazione degli ID, mi assicuro che non vi siano conflitti di nomi nello spazio al livello dell’elemento radice. Nella finestra non ostruttiva window.load (), lego le cose in base all’ID di livello superiore.

Uso rigorosamente chiusure e schemi di script java per hide tutti i metodi privati. Dopo aver fatto ciò, non si è mai verificato un problema di proprietà / definizioni di funzioni / definizioni di variabili in conflitto. Tuttavia, quando si lavora con una squadra è spesso difficile applicare lo stesso rigore.

Sono sorpreso che nessuno abbia menzionato i framework MVC. Sto usando Backbone.js per modulare e disaccoppiare il mio codice, ed è stato inestimabile.

Ci sono un bel po ‘di questi tipi di quadri là fuori, e la maggior parte di essi sono abbastanza piccoli. La mia opinione personale è che se stai scrivendo più di un paio di righe di jQuery per roba da UI appariscente, o vuoi una ricca applicazione Ajax, un framework MVC ti renderà la vita molto più facile.

“Scrivi come un matto e spero solo che funzioni per il meglio?”, Ho visto un progetto come questo che è stato sviluppato e gestito da soli 2 sviluppatori, una grande applicazione con un sacco di codice javascript. Inoltre, c’erano scorciatoie diverse per ogni ansible funzione jquery a cui si possa pensare. Ho suggerito che organizzino il codice come plugin, poiché questo è l’equivalente jquery di class, modulo, spazio dei nomi … e dell’intero universo. Ma le cose sono andate molto peggio, ora hanno iniziato a scrivere plugin per sostituire ogni combinazione di 3 linee di codice utilizzate nel progetto. Personalmente penso che jQuery sia il diavolo e non dovrebbe essere usato su progetti con un sacco di javascript perché ti incoraggia a essere pigro e non pensare di organizzare il codice in alcun modo. Preferisco leggere 100 righe di javascript piuttosto che una riga con 40 funzioni jQuery concatenate (non sto scherzando). Contrariamente alla credenza popolare è molto facile organizzare il codice javascript in equivalenti a domini e classi. Questo è ciò che fanno YUI e Dojo. Puoi facilmente arrotolare il tuo se vuoi. Trovo l’approccio di YUI molto migliore ed efficiente. Ma di solito hai bisogno di un buon editor con supporto per gli snippet per compensare le convenzioni di denominazione YUI se vuoi scrivere qualcosa di utile.

Creo singleton per ogni cosa che non ho bisogno di istanziare più volte sullo schermo, una lezione per tutto il resto. E tutti sono messi nello stesso spazio dei nomi nello stesso file. Tutto è commentato e progettato con UML, diagrammi di stato. Il codice javascript è chiaro di html, quindi nessun javascript inline e io tendo a utilizzare jquery per ridurre al minimo i problemi del browser incrociato.

Nel mio ultimo progetto -Viajeros.com- ho usato una combinazione di diverse tecniche. Non saprei come organizzare un’app Web: Viajeros è un sito di social networking per i viaggiatori con sezioni ben definite, quindi è facile separare il codice per ciascuna area.

Io uso la simulazione dello spazio dei nomi e il caricamento lazy dei moduli in base alla sezione del sito. Su ogni caricamento di pagina dichiaro un object “vjr” e carico sempre un set di funzioni comuni (vjr.base.js). Quindi ogni pagina HTML decide quali moduli necessitano con un semplice:

 vjr.Required = ["vjr.gallery", "vjr.comments", "vjr.favorites"]; 

Vjr.base.js prende ognuno uno gzip dal server e li esegue.

 vjr.include(vjr.Required); vjr.include = function(moduleList) { if (!moduleList) return false; for (var i = 0; i < moduleList.length; i++) { if (moduleList[i]) { $.ajax({ type: "GET", url: vjr.module2fileName(moduleList[i]), dataType: "script" }); } } }; 

Ogni "modulo" ha questa struttura:

 vjr.comments = {} vjr.comments.submitComment = function() { // do stuff } vjr.comments.validateComment = function() { // do stuff } // Handlers vjr.comments.setUpUI = function() { // Assign handlers to screen elements } vjr.comments.init = function () { // initialize stuff vjr.comments.setUpUI(); } $(document).ready(vjr.comments.init); 

Data la mia conoscenza limitata di Javascript, so che ci devono essere modi migliori per gestirlo, ma fino ad ora funziona benissimo per noi.

Organizzare il tuo codice in un modo NameSpace di Jquery centric può apparire come segue … e non si scontrerà con altre API di Javascript come Prototype, Ext.

   

Spero che questo ti aiuti.

Il buon principio di OO + MVC farebbe sicuramente molto per gestire una complessa applicazione javascript.

Fondamentalmente sto organizzando la mia app e javascript sul seguente design familiare (che esiste già dai miei giorni di programmazione desktop a Web 2.0)

JS OO e MVC

Descrizione per i valori numerici sull’immagine:

  1. Widget che rappresentano le viste della mia applicazione. Questo dovrebbe essere estensibile e separato in modo ordinato risultando in una buona separazione che MVC cerca di ottenere piuttosto che trasformare il mio widget in un codice spaghetti (equivalente nell’applicazione web di mettere un grande blocco di Javascript direttamente in HTML). Ogni widget comunica tramite gli altri ascoltando l’evento generato da altri widget riducendo così il forte accoppiamento tra i widget che potrebbero portare a un codice ingestibile (ricorda il giorno in cui aggiungi onclick ovunque indicando funzioni globali nel tag dello script? Urgh …)
  2. Modelli di oggetti che rappresentano i dati che voglio inserire nei widget e passare avanti e indietro sul server. Incapsulando i dati nel modello, l’applicazione diventa agnostica del formato dei dati. Ad esempio: mentre naturalmente in Javascript questi modelli di oggetti sono per lo più serializzati e deserializzati in JSON, se in qualche modo il server utilizza XML per la comunicazione, tutto ciò che devo cambiare sta cambiando il livello di serializzazione / deserializzazione e non necessariamente ha bisogno di cambiare tutte le classi di widget .
  3. Classi di controller che gestiscono la logica aziendale e la comunicazione al server + occasionalmente il livello di memorizzazione nella cache. Questo strato controlla il protocollo di comunicazione verso il server e inserisce i dati necessari nei modelli object
  4. Le classi sono impacchettate ordinatamente nei corrispondenti spazi dei nomi. Sono sicuro che tutti sappiamo quanto possa essere brutto lo spazio dei nomi globale in Javascript.

In passato, avrei separato i file in js e usato la pratica comune per creare principi OO in Javascript. Il problema che ho scoperto presto è che ci sono molti modi per scrivere JS OO e non è necessariamente che tutti i membri del team abbiano lo stesso approccio. Con l’aumentare della squadra (nel mio caso più di 15 persone), questo si complica poiché non esiste un approccio standard per Javascript orientato agli oggetti. Allo stesso tempo, non voglio scrivere il mio schema e ripetere parte del lavoro che sono sicuramente più intelligente di quello che ho risolto.

jQuery è incredibilmente bello come Javascript Framework e lo adoro, tuttavia quando il progetto diventa più grande, ho chiaramente bisogno di una struttura aggiuntiva per la mia app web, in particolare per facilitare la standardizzazione della pratica OO. Per me stesso, dopo diversi esperimenti, trovo che l’infrastruttura YUI3 Base e Widget ( http://yuilibrary.com/yui/docs/widget/ e http://yuilibrary.com/yui/docs/base/index.html ) fornisce esattamente quello di cui ho bisogno Poche ragioni per cui li uso

  1. Fornisce supporto per Namespace. Un vero bisogno di OO e organizzazione ordinata del tuo codice
  2. Supporta la nozione di classi e oggetti
  3. Fornisce un mezzo standard per aggiungere variabili di istanza alla class
  4. Supporta ordinatamente l’estensione di class
  5. Fornisce costruttore e distruttore
  6. Fornisce il rendering e l’associazione degli eventi
  7. Ha un framework per widget di base
  8. Ogni widget ora è in grado di comunicare tra loro utilizzando un modello basato su eventi standard
  9. Soprattutto, offre a tutti gli ingegneri uno standard OO per lo sviluppo di Javascript

Contrariamente a molti punti di vista, non devo necessariamente scegliere tra jQuery e YUI3. Questi due possono coesistere pacificamente. Mentre YUI3 fornisce il modello OO necessario per la mia app Web complessa, jQuery fornisce al mio team l’astrazione JS facile da usare che tutti noi amiamo e conosciamo.

Utilizzando YUI3, sono riuscito a creare pattern MVC separando le classi che estendono Base come Model, classi che ampliano Widget come View e, naturalmente, sono presenti classi di controller che eseguono le chiamate logiche e server side necessarie.

Il widget può comunicare tra loro utilizzando il modello basato su eventi e ascoltando l’evento e svolgendo l’attività necessaria in base all’interfaccia predefinita. In poche parole, mettere la struttura OO + MVC in JS è una gioia per me.

Solo un disclaimer, non lavoro per Yahoo! e semplicemente un architetto che sta cercando di affrontare lo stesso problema posto dalla domanda originale. Penso che se qualcuno troverà un framework OO equivalente, funzionerebbe altrettanto bene. Principalmente, questa domanda si applica anche ad altre tecnologie. Grazie a Dio per tutte le persone che hanno ideato OO Principles + MVC per rendere i nostri giorni di programmazione più gestibili.

Uso la gestione dei pacchetti di Dojo ( dojo.require e dojo.provide ) e il sistema di classi ( dojo.declare che consente anche l’ereditarietà multipla semplice) per modulare tutte le mie classi / widget in file separati. Non solo dosa, mantieni il codice organizzato, ma ti consente anche di caricare pigro / in tempo reale di classi / widget.

Qualche giorno fa, i ragazzi di 37Signals hanno rilasciato un controllo RTE , con una svolta. Hanno creato una libreria che raggruppa i file javascript usando una sorta di comandi pre-processore.

L’ho usato da quando ho separato i miei file JS e alla fine li ho uniti come uno solo. In questo modo posso separare le preoccupazioni e, alla fine, avere solo un file che passa attraverso la pipe (gzip, non meno).

Nei tuoi modelli, controlla se sei in modalità sviluppo e includi i file separati e, se in produzione, includi quello finale (che dovrai “build” tu stesso).

Crea classi false e assicurati che tutto ciò che può essere gettato in una funzione separata che abbia senso sia fatto così. Assicurati anche di commentare molto e di non scrivere il codice spagghetti, piuttosto di tenerlo tutto in sezioni. Ad esempio, qualche codice senza senso che descrive i miei ideali. Ovviamente nella vita reale scrivo anche molte librerie che fondamentalmente comprendono la loro funzionalità.

 $(function(){ //Preload header images $('a.rollover').preload(); //Create new datagrid var dGrid = datagrid.init({width: 5, url: 'datalist.txt', style: 'aero'}); }); var datagrid = { init: function(w, url, style){ //Rendering code goes here for style / width //code etc //Fetch data in $.get(url, {}, function(data){ data = data.split('\n'); for(var i=0; i < data.length; i++){ //fetching data } }) }, refresh: function(deep){ //more functions etc. } }; 

Utilizza i modelli di ereditarietà per organizzare grandi applicazioni jQuery.

Penso che questo sia legato, forse, al DDD (Domain-Driven Design). L’applicazione su cui sto lavorando, anche se manca un’API formale, fornisce alcuni suggerimenti in merito al codice lato server (nomi di classi / file, ecc.). Armato di ciò, ho creato un object di livello superiore come contenitore per l’intero dominio del problema; poi, ho aggiunto spazi dei nomi dove necessario:

 var App; (function() { App = new Domain( 'test' ); function Domain( id ) { this.id = id; this.echo = function echo( s ) { alert( s ); } return this; } })(); // separate file (function(Domain) { Domain.Console = new Console(); function Console() { this.Log = function Log( s ) { console.log( s ); } return this; } })(App); // implementation App.Console.Log('foo'); 

Per l’organizzazione JavaScript è stato utilizzato il seguente

  1. Cartella per tutti i tuoi javascript
  2. Livello di pagina javascript ottiene il proprio file con lo stesso nome della pagina. ProductDetail.aspx sarebbe ProductDetail.js
  3. All’interno della cartella javascript per i file della libreria ho una cartella lib
  4. Mettere le relative funzioni della libreria in una cartella lib che si desidera utilizzare nell’applicazione.
  5. Ajax è l’unico javascript che mi muovo fuori dalla cartella javascript e ottiene la sua cartella personale. Quindi aggiungo due client e server delle sottocartelle
  6. La cartella client ottiene tutti i file .js mentre la cartella del server ottiene tutti i file sul lato server.

I’m using this little thing. It gives you ‘include’ directive for both JS and HTML templates. It eleminates the mess completely.

https://github.com/gaperton/include.js/

 $.include({ html: "my_template.html" // include template from file... }) .define( function( _ ){ // define module... _.exports = function widget( $this, a_data, a_events ){ // exporting function... _.html.renderTo( $this, a_data ); // which expands template inside of $this. $this.find( "#ok").click( a_events.on_click ); // throw event up to the caller... $this.find( "#refresh").click( function(){ widget( $this, a_data, a_events ); // ...and update ourself. Yep, in that easy way. }); } }); 

You can use jquery mx (used in javascriptMVC) which is a set of scripts that allows you to use models, views, and controllers. I’ve used it in a project and helped me create structured javascript, with minimal script sizes because of compression. This is a controller example:

 $.Controller.extend('Todos',{ ".todo mouseover" : function( el, ev ) { el.css("backgroundColor","red") }, ".todo mouseout" : function( el, ev ) { el.css("backgroundColor","") }, ".create click" : function() { this.find("ol").append("
  • New Todo
  • "); } }) new Todos($('#todos'));

    You can also use only the controller side of jquerymx if you aren’t interested in the view and model parts.

    Your question is one that plagued me late last year. The difference – handing the code off to new developers who had never heard of private and public methods. I had to build something simple.

    The end result was a small (around 1KB) framework that translates object literals into jQuery. The syntax is visually easier to scan, and if your js grows really large you can write reusable queries to find things like selectors used, loaded files, dependent functions, etc.

    Posting a small framework here is impractical, so I wrote a blog post with examples (My first. That was an adventure!). You’re welcome to take a look.

    For any others here with a few minutes to check it out, I’d greatly appreciate feedback!

    FireFox recommended since it supports toSource() for the object query example.

    Saluti!

    Adamo

    I use a custom script inspired by Ben Nolan’s behaviour (I can’t find a current link to this anymore, sadly) to store most of my event handlers. These event handlers are triggered by the elements className or Id, for example. Esempio:

     Behaviour.register({ 'a.delete-post': function(element) { element.observe('click', function(event) { ... }); }, 'a.anotherlink': function(element) { element.observe('click', function(event) { ... }); } }); 

    I like to include most of my Javascript libraries on the fly, except the ones that contain global behaviour. I use Zend Framework’s headScript() placeholder helper for this, but you can also use javascript to load other scripts on the fly with Ajile for example.

    You don’t mention what your server-side language is. Or, more pertinently, what framework you are using — if any — on the server-side.

    IME, I organise things on the server-side and let it all shake out onto the web page. The framework is given the task of organising not only JS that every page has to load, but also JS fragments that work with generated markup. Such fragments you don’t usually want emitted more than once – which is why they are abstracted into the framework for that code to look after that problem. 🙂

    For end-pages that have to emit their own JS, I usually find that there is a logical structure in the generated markup. Such localised JS can often be assembled at the start and/or end of such a structure.

    Note that none of this absolves you from writing efficient JavaScript! 🙂

    Lazy Load the code you need on demand. Google does something like this with their google.loader