2008-10-29 12 views
529

Como frameworks de JavaScript como jQuery hacer que las aplicaciones web del lado del cliente más rica y más funcional, he comenzado a notar un problema ...comúnmente aceptado mejores prácticas en torno a la organización del código en JavaScript

Cómo en el mundo Cómo se mantiene esto organizado?

  • Coloque todos sus manipuladores en un lugar y escriba funciones para todos los eventos?
  • ¿Crear funciones/clases para envolver toda su funcionalidad?
  • Escribir como loco y solo espero que funcione para mejor?
  • ¿Renunciar y obtener una nueva carrera?

Menciono jQuery, pero en realidad es cualquier código JavaScript en general. Me doy cuenta de que a medida que las líneas y líneas comienzan a acumularse, es más difícil administrar los archivos de script o encontrar lo que estás buscando. Posiblemente los problemas más grandes que he encontrado es que hay tantas maneras de hacer lo mismo, es difícil saber cuál es la mejor práctica comúnmente aceptada en la actualidad.

¿Hay alguna recomendación general sobre la mejor manera de mantener sus archivos .js tan bonitos y ordenados como el resto de su aplicación? ¿O es solo una cuestión de IDE? ¿Hay una mejor opción por ahí?


EDITAR

Esta pregunta se pretende que sea más acerca de la organización del código y no presentar organización. Ha habido algunos buenos ejemplos de fusión de archivos o división de contenido.

Mi pregunta es: ¿cuál es la mejor forma de práctica actual comúnmente aceptada para organizar su código real? ¿Cuál es tu manera, o incluso una forma recomendada de interactuar con elementos de página y crear código reutilizable que no entre en conflicto?

Algunas personas han enumerado namespaces que es una buena idea. ¿Cuáles son algunas otras formas, más específicamente tratar con elementos en la página y mantener el código organizado y ordenado?

+0

alguien que realmente se tomó el tiempo para hablar sobre la organización del código en sí, no "solo" qué herramienta usa para concatenar y comprimir sus archivos JS: http://stackoverflow.com/questions/16736483/best-way-to -organize-jquery-javascript-code-2013/16760577 # 16760577 –

Respuesta

37

Puede dividir sus scripts en archivos separados para el desarrollo, luego cree una versión de "versión" donde los agrupe y ejecute YUI Compressor o algo similar en él.

+0

A veces hay scripts javascript innecesarios. Es un desperdicio enviarlos al cliente. Creo que es mejor enviar solo lo que se necesita. Por supuesto, para una aplicación web que se usa todo el día, como una aplicación de intranet, sería mejor enviar todo el lote de una vez, en la primera carga de la página. – DOK

+2

La compilación de @DOK debe incluir la escisión de material no utilizado. – aehlke

+0

También hay un concepto de carga diferida para tratar de reducir las necesidades de ancho de banda, donde carga la página inicial y luego carga asíncronamente los archivos de script necesarios (como se menciona en otras respuestas a esta pregunta). Sin embargo, eso puede requerir más solicitudes y en realidad podría ser menos útil. @DOK, si el JS está en la memoria caché, una solicitud mediana puede ser mejor que algunas pequeñas. – jamiebarrow

3

Hace unos días, los chicos en 37Signals released a RTE control, con un giro. Hicieron una biblioteca que agrupa los archivos javascript utilizando una especie de comandos de pre-procesador.

Lo he estado usando desde entonces para separar mis archivos JS y luego, al final, combinarlos como uno solo. De esa forma puedo separar preocupaciones y, al final, tener solo un archivo que pase por el conducto (gzip, nada menos).

En sus plantillas, compruebe si está en modo de desarrollo, e incluya los archivos por separado, y si está en producción, incluya el último (que tendrá que "compilar").

+1

http://getsprockets.org/ es el enlace directo –

0

Utilizo una secuencia de comandos personalizada inspirada en el comportamiento de Ben Nolan (no puedo encontrar un enlace actual a esto más, por desgracia) para almacenar la mayoría de mis controladores de eventos. Estos manejadores de eventos son activados por los elementos className o Id, por ejemplo. Ejemplo:

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

    'a.anotherlink': function(element) { 
     element.observe('click', function(event) { ... }); 
    } 

}); 

me gusta incluir la mayor parte de mis librerías Javascript sobre la marcha, a excepción de los que contienen el comportamiento global. Yo uso Zend Framework's headScript() placeholder helper para esto, pero también puede use javascript to load other scripts on the fly con Ajile por ejemplo.

+0

¿Es esto lo que estabas buscando? http://www.koders.com/javascript/fidEBB758A268EBDAB42C72AAA954AA9A3099A1DE67.aspx?s=%22Ben+Nolan%22#L4 – DOK

+0

¡Sí, esa es la única! :) Parece que el código detrás del enlace es bastante más reciente que la versión en la que me inspiré. ¡Gracias por tu esfuerzo! –

9

Mi jefe todavía habla de los tiempos cuando escribieron el código modular (lenguaje C), y se queja de cuán malo es el código hoy en día. Se dice que los programadores pueden escribir ensamblajes en cualquier marco. Siempre hay una estrategia para superar la organización del código. El problema básico es con chicos que tratan el guión java como un juguete y nunca intentan aprenderlo.

En mi caso, escribo archivos js en un tema UI o pantalla de aplicación, con una init_screen() adecuada. Utilizando la convención de nomenclatura de identificación adecuada, me aseguro de que no haya conflictos de espacio de nombres en el nivel del elemento raíz. En el discreto window.load(), relaciono las cosas según el ID de nivel superior.

Uso estrictamente los cierres y los patrones de script java para ocultar todos los métodos privados. Después de hacer esto, nunca se enfrentó a un problema de propiedades conflictivas/definiciones de funciones/definiciones de variables. Sin embargo, cuando se trabaja con un equipo, a menudo es difícil imponer el mismo rigor.

169

Sería mucho más agradable si javascript tuviera espacios de nombres integrados, pero creo que organizar cosas como Dustin Diaz describe here me ayuda mucho.

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

Puse diferentes "espacios de nombres" y, a veces las clases individuales en archivos separados. Por lo general, empiezo con un archivo y, a medida que una clase o espacio de nombres crece lo suficiente como para garantizarlo, lo separo en su propio archivo. Usar una herramienta para combinar todos tus archivos para producción también es una excelente idea.

+19

Normalmente me refiero a eso como "la manera crockford". +1 de mí –

+4

Incluso puede ir un poco más allá. Vea este enlace: http://www.wait-till-i.com/2007/08/22/again-with-the-module-pattern-reveal-something-to-the-world/ – MKroehnert

+3

@MattBriggs, también llamado el ['module pattern'] (http://stackoverflow.com/questions/17776940/javascript-module-pattern-with-example) y está basado en el [' patrón IIFE'] (http://stackoverflow.com/ preguntas/2421911/qué-es-el-propósito-de-envolver-todo-javascript-archivos-en-anónimo-funciones-li/26738969 # 26738969). –

7

Creo singletons para cada cosa. Realmente no necesito crear instancias varias veces en la pantalla, una clase para todo lo demás. Y todos ellos se colocan en el mismo espacio de nombres en el mismo archivo. Todo está comentado, y diseñado con UML, diagramas de estado. El código javascript está libre de html, por lo que no hay javascript en línea y tiendo a usar jquery para minimizar los problemas del navegador cruzado.

+3

buenos comentarios son CLAVE - Me alegro de que lo haya dicho, así que no tuve que hacerlo. Agregaría convenciones de nomenclatura consistentes, algún tipo de estrategia de organización fácilmente comprensible para las funciones de variables &, y como mencionaste, el uso juicioso de las clases frente a los singletons. –

+0

No. Si necesita comentarios, su código generalmente no es lo suficientemente legible. Esfuércese por escribir código que no necesita comentarios. –

+0

Además, si necesita diagramas UML y de estado, eso probablemente significa que su arquitectura no es lo suficientemente clara desde el código. Downvoting. –

0

No menciona cuál es el idioma del lado del servidor. O, lo que es más pertinente, qué marco está utilizando, si lo hay, en el lado del servidor.

IME, organizo cosas en el lado del servidor y dejo que todo se sacuda en la página web. El marco tiene la tarea de organizar no solo JS que cada página tiene que cargar, sino también fragmentos JS que funcionan con el marcado generado. Esos fragmentos que normalmente no desea emitir más de una vez, razón por la cual se abstraen en el marco de ese código para atender ese problema. :-)

Para las páginas finales que tienen que emitir su propio JS, generalmente encuentro que hay una estructura lógica en el marcado generado. Tal JS localizado a menudo se puede ensamblar al comienzo y/o al final de dicha estructura.

Tenga en cuenta que nada de esto le absuelve de escribir JavaScript eficiente. :-)

24

Inspirado por los mensajes anteriores I hizo una copia de Rakefile y proveedor directorios distribuido con WysiHat (a RTE mencionado por cambios) e hizo algunas modificaciones para incluir código de comprobación con JSLint y minificación con YUI Compressor .

La idea es usar Sprockets (de WysiHat) para combinar múltiples JavaScripts en un solo archivo, verificar la sintaxis del archivo fusionado con JSLint y minificarlo con YUI Compressor antes de la distribución.

Requisitos previos

  • de ejecución de Java
  • rubí y el rastrillo joya
  • Usted debe saber cómo poner un JAR en Classpath

Ahora haga

  1. Rhino Descargar y poner el JAR ("js.jar") a su ruta de clase
  2. Descargar YUI Compressor y poner el JAR (build/yuicompressor-xyz.jar) a su ruta de clase
  3. Descargar WysiHat y copiar "vendedor" directorio a la raíz del proyecto JavaScript
  4. Descargar JSLint for Rhino y ponerlo dentro del directorio "vendedor"

Ahora cree un archivo llamado "Rakefile" en el directorio raíz del proyecto de JavaScript y añadir el siguiente contenido a it:

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 

Si hecho todo correctamente, usted debería ser capaz de utilizar los siguientes comandos en la consola:

  • rake merge - fusionar diferentes archivos JavaScript en uno
  • rake check - para comprobar la sintaxis de su código (esta es la tarea predeterminada , por lo que puede simplemente escribir rake)
  • rake minify - para preparar la versión reducida de su código JS

sobre la fuente de la fusión de

El uso de ruedas dentadas, el pre-procesador de JavaScript que puede incluir (o require) otros archivos JavaScript. Utilice la siguiente sintaxis para incluir otras secuencias de comandos desde el archivo inicial (llamado "main.js", pero esto se puede cambiar en el 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 
})(); 

Y entonces ...

Tome una mira Rakefile provisto con WysiHat para configurar las pruebas automatizadas de la unidad. Cosas bonitas :)

Y ahora para la respuesta

Esto no responde a la pregunta original muy bien. Lo sé y lo siento, pero lo publiqué aquí porque espero que pueda ser útil para otra persona organizar su desorden.

Mi enfoque al problema es hacer todo el modelado orientado a objetos que pueda y separar las implementaciones en diferentes archivos. Entonces los manejadores deben ser lo más cortos posible. El ejemplo con List singleton también es bueno.

Y espacios de nombres ... bueno, pueden ser imitados por una estructura de objetos más profunda.

if (typeof org === 'undefined') { 
    var org = {}; 
} 

if (!org.hasOwnProperty('example')) { 
    org.example = {}; 
} 

org.example.AnotherObject = function() { 
    // constructor body 
}; 

no soy gran fan de imitaciones, pero esto puede ser útil si tiene muchos objetos que le gustaría a moverse fuera del ámbito global.

12

Pude aplicar con éxito el Javascript Module Pattern a una aplicación Ext JS en mi trabajo anterior. Proporcionó una forma simple de crear código encapsulado.

83

Intento evitar incluir cualquier javascript con el HTML. Todo el código está encapsulado en clases y cada clase está en su propio archivo. Para el desarrollo, tengo etiquetas de script <separadas> para incluir cada archivo js, ​​pero se fusionan en un solo paquete más grande para producción para reducir la sobrecarga de las solicitudes HTTP.

Normalmente, tendré un único archivo 'principal' js para cada aplicación. Entonces, si estuviera escribiendo una aplicación de "encuesta", tendría un archivo js llamado "survey.js". Esto contendría el punto de entrada en el código jQuery. Creo referencias de jQuery durante la creación de instancias y luego las paso a mis objetos como parámetros. Esto significa que las clases de JavaScript son 'puras' y no contienen ninguna referencia a identificadores de CSS o nombres de clases.

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

También encuentro que la convención de nomenclatura es importante para la legibilidad. Por ejemplo: antepongo 'j' a todas las instancias de jQuery.

En el ejemplo anterior, hay una clase llamada DimScreen. (Supongamos que atenúa la pantalla y aparece un cuadro de alerta.) Necesita un elemento div que se pueda agrandar para cubrir la pantalla, y luego agregue un cuadro de alerta, así que paso un objeto jQuery. jQuery tiene un concepto de complemento, pero parecía limitado (por ejemplo, las instancias no son persistentes y no se puede acceder) sin una ventaja real. Entonces la clase DimScreen sería una clase javascript estándar que simplemente usa 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('<div>'+msg+'</div>'); 
    //... 
}; 

He creado algunas aplicaciones bastante complejas con este enfoque.

+15

Encuentro que usar '$' como prefijo de nombre de variable es una práctica más común, pero podría estar equivocado. Entonces, '$ s = $ ('...')' en lugar de 'jS = $ ('...')', solo una cuestión de preferencia, supongo. Sin embargo, es interesante, ya que se cree que la notación húngara es un olor codificado. Es extraño lo diferentes que son algunas de mis convenciones/convenciones de código JavaScript para mis convenciones de codificación C#/Java. – jamiebarrow

+9

@jamie No es un olor a código en este caso, es precisamente uno de los pocos casos en que el húngaro es * bueno *. Es posible que desee leer [esto] (http://www.joelonsoftware.com/articles/Wrong.html). –

+3

@DanAbramov gracias por el enlace. Realmente debo leer todos los blogs de Joel, él explica las cosas muy bien. Definitivamente merece la fama/reputación que tiene. Me referiré a 'Systems Hungarian' como un olor a código y' Apps Hungarian' como una práctica a partir de ahora :) – jamiebarrow

13

Seguir los buenos principios de diseño y patrones de diseño de OO hace que su código sea fácil de mantener y comprender. Pero una de las mejores cosas que he descubierto recientemente son señales y ranuras también conocidas como publicar/suscribir. Eche un vistazo a http://markdotmeyer.blogspot.com/2008/09/jquery-publish-subscribe.html para una implementación simple de jQuery.

La idea es muy utilizada en otros lenguajes para el desarrollo de GUI. Cuando sucede algo significativo en algún lugar de su código, publica un evento sintético global al que otros métodos en otros objetos pueden suscribirse. Esto proporciona una excelente separación de objetos.

Creo que Dojo (y Prototype?) Tienen una versión incorporada de esta técnica.

consulta What are signals and slots?

+0

He hecho esto en jQuery. JS tiene un modelo de evento incorporado, por lo que realmente no necesita mucho soporte de framework. –

11

Dojo tenía el sistema de módulos desde el primer día.De hecho, se considera que es una piedra angular de Dojo, el pegamento que lo mantiene todo junto:

El uso de módulos Dojo logra siguientes objetivos:

  • espacios de nombres para el código de Dojo y código personalizado (dojo.declare()) — no contaminan el espacio global, coexistir con otras bibliotecas y código no Dojo-conscientes de usuario .
  • Cargando módulos de forma síncrona o asincrónica por nombre (dojo.require()).
  • Crea propiedades personalizadas analizando las dependencias de los módulos para crear un solo archivo o un grupo de archivos interdependientes (las denominadas capas) para incluir solo lo que necesita tu aplicación web. Las versiones personalizadas también pueden incluir módulos Dojo y módulos proporcionados por el cliente.
  • Acceso transparente basado en CDN a Dojo y el código del usuario. Tanto AOL como Google llevan Dojo de esta manera, pero algunos clientes también lo hacen por sus aplicaciones web personalizadas.
0

Lazy Carga el código que necesitas bajo demanda. Google hace algo como esto con su google.loader

6

En mi último proyecto -Viajeros.com- he usado una combinación de varias técnicas. No sabría cómo organizar una aplicación web: Viajeros es un sitio de redes sociales para viajeros con secciones bien definidas, por lo que es fácil separar el código para cada área.

Utilizo la simulación del espacio de nombres y la carga diferida de los módulos de acuerdo con la sección del sitio. En cada carga de página declaro un objeto "vjr", y siempre cargo un conjunto de funciones comunes (vjr.base.js). A continuación, cada página HTML decide qué módulos necesitan con un simple:

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

Vjr.base.js obtiene cada uno gzip desde el servidor y los ejecuta.

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

Cada "módulo" tiene esta estructura:

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

Dado mi conocimiento limitado Javascript, sé que debe haber mejores maneras de manejar esto, pero hasta ahora está funcionando muy bien para nosotros.

8

"¿Escribir como loco y solo espero que funcione de la mejor manera?", He visto un proyecto como este, desarrollado y mantenido por solo 2 desarrolladores, una gran aplicación con muchos códigos JavaScript. Además de eso, había diferentes atajos para cada función de jquery posible que se pueda imaginar. Sugerí que organizaran el código como complementos, ya que ese es el equivalente de jquery de clase, módulo, espacio de nombres ... y todo el universo. Pero las cosas empeoraron, ahora comenzaron a escribir complementos reemplazando cada combinación de 3 líneas de código utilizadas en el proyecto. Personalmente, creo que jQuery es el demonio y no debería usarse en proyectos con muchos javascript porque te anima a ser flojo y no pensar en organizar el código de ninguna manera. Prefiero leer 100 líneas de javascript que una línea con 40 funciones jQuery encadenadas (no estoy bromeando). Contrario a la creencia popular, es muy fácil organizar código JavaScript en equivalentes a espacios de nombres y clases. Eso es lo que hacen YUI y Dojo.Puede enrollar fácilmente el suyo si quiere. Encuentro el enfoque de YUI mucho mejor y más eficiente. Pero normalmente necesita un buen editor con soporte para fragmentos para compensar las convenciones de nombres de YUI si quiere escribir algo útil.

+3

Estoy de acuerdo con usted acerca de comandos realmente largos y encadenados, pero una de las mejores partes de jQuery es que mantiene todo el Javascript fuera de HTML. Puede configurar controladores de eventos para todos sus elementos sin "necesitar" agregar IDs o eventos en sus elementos. Como siempre, el uso excesivo de cualquier herramienta es malo ... – Hugoware

+0

He trabajado en proyectos grandes y bien organizados en jQuery. No sé por qué crees que se interpone en el camino de la organización. –

+1

Buenos párrafos. – Alistair

2

Creo que esto se relaciona, tal vez, con el DDD (Domain-Driven Design). La aplicación en la que estoy trabajando, a pesar de que carece de una API formal, da pistas de eso a través del código del lado del servidor (nombres de clase/archivo, etc.). Armado con eso, creé un objeto de nivel superior como contenedor para todo el dominio del problema; a continuación, añadí espacios de nombres en donde sea necesario:

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'); 
6

organizar el código de una manera centrada NameSpace Jquery puede ser similar al siguiente ... y no entrará en conflicto con otros Javascript API es como prototipo, ya sea Ext.

<script src="jquery/1.3.2/jquery.js" type="text/javascript"></script> 
<script type="text/javascript"> 

var AcmeJQ = jQuery.noConflict(true); 
var Acme = {fn: function(){}}; 

(function($){ 

    Acme.sayHi = function() 
    { 
     console.log('Hello'); 
    }; 

    Acme.sayBye = function() 
    { 
     console.log('Good Bye'); 
    }; 
})(AcmeJQ); 

// Usage 
//   Acme.sayHi(); 
// or 
// <a href="#" onclick="Acme.sayHi();">Say Hello</a> 


</script> 

Espero que esto ayude.

+0

Esto me parece una pequeña aventura de carga. 'jQuery.fn' es un puntero a' jQuery.prototype', porque '$()' en realidad devuelve una nueva instancia de la función del constructor jQuery. Agregar un 'complemento' a jQuery significa simplemente extender su prototipo. Pero lo que estás haciendo no es eso, y hay formas más limpias de lograr lo mismo. –

+0

Creo que simplemente está creando funciones estáticas. Recuerdo haber visto en los documentos de jQuery que esta forma de declarar funciones estáticas es aceptable. –

3

Crea clases falsas, y asegúrate de que todo lo que se pueda incluir en una función separada tenga sentido. También asegúrese de comentar mucho, y no escribir código spagghetti, más bien mantenerlo todo en secciones. Por ejemplo, un código sin sentido que representa mis ideales. Obviamente en la vida real también escribo muchas bibliotecas que básicamente abarcan su funcionalidad.

$(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. 
    } 
}; 
5

utilizo gestión de Dojo paquete (dojo.require y dojo.provide) y el sistema de clases (dojo.declare que también permite una sencilla herencia múltiple) modularizar todas mis clases/widgets en archivos separados. No solo dosifique esto, mantenga organizado su código, sino que también le permita cargar clases/widgets de forma lenta y perezosa.

9

Echa un vistazo JavasciptMVC.

Puede:

  • dividir el código en el modelo, la vista y el controlador capas.

  • compresa todo el código en un único archivo de producción

  • generar automáticamente código

  • crear y pone a prueba unidad de ejecución

  • y mucho más ...

Lo mejor de todo es que usa jQuery, por lo que puede aprovechar otros plugins de jQuery también.

+0

Sí, he usado jmvc y es bastante bueno. Sin embargo, docs podría ser mejor que – meouw

2

Para la organización JavaScript estado utilizando la siguiente carpeta

  1. por toda su javascript
  2. nivel de página Javascript obtiene su propio archivo con el mismo nombre de la página. ProductDetail.aspx sería ProductDetail.js
  3. Dentro de la carpeta javascript para archivos de biblioteca Tengo una carpeta lib
  4. Coloque funciones de biblioteca relacionadas en una carpeta lib que desee usar en toda su aplicación.
  5. Ajax es el único javascript que muevo fuera de la carpeta javascript y obtiene su propia carpeta. Luego agrego dos subcarpetas cliente y servidor
  6. La carpeta del cliente obtiene todos los archivos .js mientras que la carpeta del servidor obtiene todos los archivos del lado del servidor.
+0

Bueno para la organización de archivos. Lo hago con código. Pero al final compilo mi código en un ... digamos dll. Lo necesita con javascript también o terminará solicitando 15 js archivos por página. – graffic

+0

No hay nada de malo en solicitar 15 archivos JS por página. Su navegador los almacenará en caché para solicitudes posteriores de todos modos. –

+0

@ MarnenLaibow-Koser El único problema con la solicitud de 15 archivos JS en una página es cuántas solicitudes HTTP puede manejar el navegador a la vez. Así que agruparlos en un archivo permite que el navegador solicite otros archivos necesarios al mismo tiempo. – iwasrobbed

2

Estoy usando esta pequeña cosa. Le da la directiva 'incluir' tanto para plantillas JS como HTML. Completa el desastre por completo.

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

Su pregunta es una que me plagado a finales del año pasado. La diferencia: entregar el código a nuevos desarrolladores que nunca habían oído hablar de métodos privados y públicos. Tuve que construir algo simple.

El resultado final fue un marco pequeño (alrededor de 1 KB) que traduce los literales de objeto en jQuery. La sintaxis es visualmente más fácil de escanear, y si su js crece realmente grande puede escribir consultas reutilizables para encontrar cosas como selectores usados, archivos cargados, funciones dependientes, etc.

Publicar un pequeño marco aquí no es práctico, así que escribí a blog post with examples (Mi primero. ¡Eso fue una aventura!). Puedes echar un vistazo.

Para cualquier otro aquí con unos minutos para verlo, ¡le agradecería mucho los comentarios!

Se recomienda Firefox ya que es compatible con toSource() para el ejemplo de consulta de objeto.

¡Salud!

Adam

9

Me sorprende que nadie mencionó marcos MVC. He estado usando Backbone.js para modularizar y desacoplar mi código, y ha sido invaluable.

Existen bastantes de estos tipos de frameworks, y la mayoría también son muy pequeños. Mi opinión personal es que si va a escribir más que solo un par de líneas de jQuery para cosas llamativas de UI, o si quiere una aplicación Ajax muy completa, un framework MVC le hará la vida mucho más fácil.

2

Puede usar jquery mx (utilizado en javascriptMVC) que es un conjunto de scripts que le permite usar modelos, vistas y controladores. Lo he usado en un proyecto y me ayudó a crear javascript estructurado, con tamaños de script mínimos debido a la compresión. Este es un ejemplo de controlador:

$.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("<li class='todo'>New Todo</li>"); 
    } 
}) 

new Todos($('#todos')); 

También puede utilizar only the controller lado de jquerymx si no está interesado en la vista y el modelo partes.

6

El buen principal de OO + MVC definitivamente sería muy útil para administrar una aplicación compleja de JavaScript.

Básicamente estoy organizando mi aplicación y javascript para el siguiente diseño familiar (que existe desde los días de programación de mi escritorio a la Web 2).0)

JS OO and MVC

Descripción de los valores numéricos en la imagen:

  1. Reproductores representan los puntos de vista de mi solicitud. Esto debe ser extensible y separado, lo que resulta en una buena separación que MVC intenta lograr en lugar de convertir mi widget en un código de espagueti (equivalente en la aplicación web de poner un gran bloque de Javascript directamente en HTML). Cada widget se comunica a través de otros escuchando el evento generado por otros widgets, reduciendo así el fuerte acoplamiento entre widgets que podría llevar a un código inmanejable (¿recuerdas el día de agregar onclick en todas partes apuntando a funciones globales en la etiqueta de script? Urgh ...)
  2. Modelos de objetos que representan los datos que quiero completar en los widgets y que pasan de ida y vuelta al servidor. Al encapsular los datos en su modelo, la aplicación se convierte en agnóstico de formato de datos. Por ejemplo: mientras Naturalmente en Javascript, estos modelos de objetos están mayormente serializados y deserializados en JSON, si de alguna manera el servidor usa XML para la comunicación, todo lo que necesito cambiar es cambiar la capa de serialización/deserialización y no necesariamente cambiar todas las clases de widgets .
  3. Clases de controlador que gestionan la lógica de negocio y la comunicación con el servidor + ocasionalmente capa de almacenamiento en caché. Esta capa controla el protocolo de comunicación del servidor y coloca los datos necesarios en los modelos de objetos
  4. Las clases se envuelven ordenadamente en sus espacios de nombres correspondientes. Estoy seguro de que todos sabemos lo desagradable que puede ser el espacio de nombre global en Javascript.

En el pasado, separaba los archivos en su propio js y uso la práctica común para crear principios de OO en Javascript. El problema es que pronto descubrí que hay varias formas de escribir JS OO y que no necesariamente todos los miembros del equipo tienen el mismo enfoque. A medida que el equipo se hizo más grande (en mi caso, más de 15 personas), esto se complica ya que no existe un enfoque estándar para Javascript orientado a objetos. Al mismo tiempo, no quiero escribir mi propio marco y repetir algunos de los trabajos que estoy seguro que son personas más inteligentes de las que he resuelto.

jQuery es muy agradable como marco Javascript y me encanta, sin embargo, como el proyecto se hace más grande, necesito claramente la estructura adicional para mi aplicación web especial para facilitar la práctica OO estandarizado. En cuanto a mí, después de varios experimentos, me parece que la base YUI3 y Widget (http://yuilibrary.com/yui/docs/widget/ y http://yuilibrary.com/yui/docs/base/index.html) infraestructura proporciona exactamente lo que necesito. Pocas razones por las que los uso.

  1. Proporciona compatibilidad con Namespace.Una necesidad real de OO y organización ordenada de su código
  2. Soporta noción de clases y objetos
  3. Da una estandarizar significa añadir variables de instancia a la clase
  4. Soporta extensión de clase cuidadosamente
  5. Proporciona constructor y destructor
  6. proporciona render y vinculante evento
  7. tiene marco widget de base de
  8. cada widget ahora capaces de comunicarse entre sí utilizando el modelo basado en eventos estándar
  9. que es más importante, da a todos los ingenieros de una Norma para el desarrollo OO Javascript

Contrariamente a muchos puntos de vista, que no necesariamente tienen que elegir entre jQuery y YUI3. Estos dos pueden coexistir pacíficamente. Si bien YUI3 proporciona la plantilla de OO necesaria para mi aplicación web compleja, jQuery aún proporciona a mi equipo una abstracción JS fácil de usar que todos conocemos y amamos.

Usando YUI3, he logrado crear un patrón MVC separando las clases que extienden la Base como el Modelo, clases que amplían Widget como una Vista y por supuesto usted tiene clases de Controlador que hacen las llamadas lógicas y de servidor necesarias.

El widget se puede comunicar entre sí utilizando el modelo basado en eventos y escuchando el evento y realizando las tareas necesarias en función de la interfaz predefinida. En pocas palabras, poner la estructura OO + MVC a JS es una alegría para mí.

Solo un descargo de responsabilidad, no trabajo para Yahoo! y simplemente un arquitecto que intenta lidiar con el mismo problema planteado por la pregunta original. Creo que si alguien encuentra un marco OO equivalente, esto también funcionaría. Principalmente, esta pregunta también se aplica a otras tecnologías. Gracias a Dios por todas las personas que diseñaron OO Principles + MVC para que nuestros días de programación sean más manejables.

18

La organización de códigos requiere la adopción de convenciones y estándares de documentación:
1. Código de espacio de nombres para un archivo físico;

Exc = {}; 


2. clases de grupo en estos espacios de nombres javascript;
3. Establecer prototipos o funciones o clases relacionadas para representar objetos del mundo real;

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


4. Establecer convenios para mejorar el código. Por ejemplo, agrupe todas sus funciones internas o métodos en su atributo de clase de un tipo de objeto.

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


5. Realizar la documentación de espacios de nombres, clases, métodos y variables. Cuando sea necesario, también discuta parte del código (algunas IF y Fors, generalmente implementan una lógica importante del código).

/** 
    * Namespace <i> Example </i> created to group other namespaces of the "Example". 
    */ 
Exc = {}; 
/** 
    * Namespace <i> ui </i> created with the aim of grouping namespaces user interface. 
    */ 
Exc.ui = {}; 

/** 
    * Class <i> maskdInput </i> 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 <i> domTips </i> 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 <i> </i>. 
    */ 
    Exc.ui.domTips = function (id, tips) { 
    this.domID = id; 
    this.tips = tips; 
    ... 
}; 


Estos son sólo algunos consejos, pero que ha ayudado mucho en la organización del código. Recuerde que debe tener disciplina para tener éxito.

Cuestiones relacionadas