2011-12-22 13 views
14

Estoy construyendo mi primera aplicación JavaScript (no espaguetis) grande. Si bien la introducción de RequireJS y otros marcos de administración de dependencias para JavaScript hace que sea más fácil para dividir archivos, No estoy seguro de cómo empujar un gran código base a la producción. Lo que me gustaría es una forma de agregar y minify/uglify mis JavaScripts para producción, usando algo como Ready.js y UglifyJS. O algún otro enfoque, si tiene sentido.Cómo estructurar aplicaciones de JavaScript en desarrollo y producción

¿Cómo manejan los desarrolladores con grandes aplicaciones de JavaScript en producción su estructura en desarrollo y en producción?

Podría, por ejemplo, usar RequireJS en desarrollo y luego usar Ready/Uglify para agregar/minificar. Pero entonces mi código tendría inútil require()'s esparcido en todas partes. Estoy seguro de que hay un mejor enfoque.

También estoy confundido acerca de incluir jQuery dentro de estos archivos. ¿Debo incluir todos y cada uno de los archivos de jQuery (por ejemplo, vistas de Backbone que usan jQuery) dentro de su propio $(document).ready(function(){...})? Eso parece muy poco seco.

+2

+1 para admitir hacer javascript sin espagueti por primera vez. Para muchos desarrolladores vivir en negación durante demasiado tiempo :) –

Respuesta

2

Puede usar el RequireJS optimizer. Las necesidades no son inútiles, ni siquiera en la aplicación comprimida, porque siempre debe obtener una referencia al módulo. Los documentos Optimizer también dicen, que no incluirá un módulo que se ha cargado con una variable como

var mods = someCondition ? ['a', 'b'], ['c', 'd']; 
require(mods); 

Creo que RequireJS deben esperar hasta que el DOM está listo y todos los módulos se han cargado, por lo que no es necesario que envuelva todos los archivos.

Dicho esto, mi administrador de paquetes favorito sigue siendo StealJS. Puede expulsar llamadas innecesarias en una compilación de producción y un módulo siempre se encapsula en un cierre que pasa el objeto jQuery y espera hasta que el DOM esté listo y se hayan cargado todos los scripts. Lamentablemente, todavía no es compatible con las especificaciones del módulo CommonJS.

manera
+0

Esto es fantástico. StealJS se ve bien, pero me gusta más de lo que RequireJS puede hacer. Me encantaría saber más sobre todo tu proceso de compilación, si no te importa compartirlo. ¿Dónde en su paso de implementación ejecuta su optimizador? ¿Pruebas junto con eso? ¿Probas el JS optimizado? Podría preguntar esto en otra pregunta, pero tengo un historial desagradable de que esas preguntas de "mejores prácticas" se cierren. –

+0

Bueno, aunque funciona muy bien por sí mismo, StealJS es parte del framework JavaScriptMVC (http://javascriptmvc.com/), que es lo que uso para estructurar, construir y probar mis aplicaciones y se encarga de todas estas cosas bonitas mucho por sí mismo (y es la única solución totalmente contenida para JavaScript que conozco). – Daff

1

He encontrado YUI Builder funciona bien para mí. No estoy seguro de lo útil que es si no estás usando YUI 3, pero hay una gran posibilidad de que puedas adaptarlo a tus necesidades.

Por otro lado, ¿ha echado un vistazo a RequireJS Optimizer?

Con respecto a document.ready manipulación; Creo que es una buena práctica no permitir que el código en los módulos haga nada hasta que se inicialicen o se llamen. Así que tendría un solo $(document).ready() en una etiqueta <script> en la parte inferior de la página, que "pega" los módulos que se necesitan en esa página.

0

Anti-espaguetis

Para desarrollar con eficacia y mantener fácilmente una aplicación de JavaScript, en contraposición a una serie de secuencias de comandos ad hoc o la automatización no transparente insatisfactorio, puede utilizar native Qooxdoo application. Es imposible cubrir Qooxdoo sin escribir demasiado, pero en caso de aplicación nativa (no confundir el término con C o Java, Qooxdoo es puro JavaScript) se describe como:

Para aplicaciones utilizando HTML personalizada/GUI basadas en CSS en lugar de la capa de widget de qooxdoo.

Por lo tanto, dicha aplicación no utiliza capas de interfaz de usuario de Qooxdoo, sino solo herramientas de estructura de código y herramientas de compilación. Código en Qooxdoo organizado en clases, uno por archivo como en Java. Puedo parecer así:

/** 
* @use(website.library.MosaicFlow) 
*/ 
qx.Class.define('website.controller.Gallery', { 

    extend : website.controller.Abstract, 

    members : { 

    _baseUrl : 'https://picasaweb.google.com/data/feed/api', 


    _render : function(photos) 
    { 
     q('.preloader').remove(); 

     q.template.get('gallery-template', {'photos': photos}).appendTo('#gallery-container'); 
     var gallery = window.jQuery('#gallery-container .gallery').mosaicflow({ 
     'minItemWidth' : 256, 
     'itemSelector' : '.photo', 
     'autoCalculation' : false 
     }); 
     gallery.trigger('resize'); 
    }, 

    _convert : function(item, index) 
    { 
     try 
     { 
     return { 
      'url'  : item.content.src, 
      'summary' : item.summary.$t, 
      'thumb' : item.media$group.media$thumbnail[0] 
     }; 
     } 
     catch(ex) 
     { 
     this.debug('failed to convert', index, item); 
     return null; 
     } 
    }, 

    _onLoadSuccess : function(event) 
    { 
     var request = event.getTarget(); 
     var response = request.getResponse(); 
     if(!qx.lang.Type.isObject(response) || !('feed' in response)) 
     { 
     request.debug('Malformed response received'); 
     } 
     else 
     { 
     this._render(response.feed.entry.map(this._convert, this).filter(function(item) 
     { 
      return !!item; 
     })); 
     } 
    }, 

    _onLoadFail : function() 
    { 
     this.debug('Picasa search failed'); 
    }, 

    main : function() 
    { 
     var query = /^\/gallery\/(\w+)$/.exec(window.location.pathname); 
     var request = new qx.io.request.Jsonp(qx.lang.String.format('%1/all', [this._baseUrl])); 
     request.setRequestData({ 
     'q'   : query[1], 
     'thumbsize' : 300, 
     'max-results' : 20, 
     'alt'   : 'json' 
     }); 
     request.setTimeout(16000); 
     request.setCache(false); 
     request.addListener('fail', this._onLoadFail, this); 
     request.addListener('success', this._onLoadSuccess, this); 
     request.send(); 
    } 

    } 

}); 

El modelo de objeto Qooxdoo aprovecha ambos mundos. En tiene cualidades de plataformas maduras como Java, al mismo tiempo es moderno y dinámico, brinda clases, herencia, interfaces, mixins, eventos, propiedades, enlace de datos y más. Como cada clase tiene un nombre definido y se encuentra en un árbol de espacio de nombres, el generador de Qooxdoo puede aprovecharlo. Analiza tus clases y construye sus árboles de sintaxis. Luego resuelve las dependencias. Es decir. cuando te refieres a otra clase, como website.controller.Abstract. Esto lleva al gráfico de dependencia, que se usa para cargar scripts en el orden correcto. Tenga en cuenta que todo es automático y transparente para un desarrollador, y los archivos se cargan como están. No hay aprocessing como en el caso de CommonJS, no hay una repetición fea para envolver tu código como con AMD.

Como puede ver en el ejemplo anterior, es posible tratar con bibliotecas externas que no son de qooxdoo. Solo necesita escribir un contenedor ficticio para una biblioteca para incluirlo en el proceso de compilación.

entornos de desarrollo y producción

Usted desarrolla la construcción de su aplicación (build que se necesita sólo cuando se introduce nueva dependencia en el código) con la llamada origen destino. Los archivos de la aplicación se cargan en orden de dependencia, uno por uno. Los archivos de Framework se pueden cargar uno a uno, o cuál es la mejor opción, están integrados en varios fragmentos grandes. En el entorno de producción, el código de la aplicación se genera con el objetivo de compilación. Tiene la opción de producir un solo archivo de salida, o tener una compilación parcial, donde el código se fragmenta en grandes archivos (puede controlar su tamaño). acumulación parcial puede tener este aspecto (optimizado/gzip):

├── [127/64kB] website.f6ffa57fc541.js 
├── [100/33kB] website.f86294b58d1a.js 
└── [361/110kB] website.js 

Tenga en cuenta que las piezas se cargan bajo demanda en las páginas que lo requieran.

http://example.com/ 
└── website.js 
http://example.com/article 
└── website.js 
http://example.com/form 
└── website.js 
    └── website.f86294b58d1a.js 
http://example.com/gallery 
└── website.js 
    └── website.f6ffa57fc541.js 
http://example.com/geo 
└── website.js 

Debido Qooxdoo no se dirige el sitio web en toda regla se basa todavía, pero sólo está proporcionando una plataforma de tipo de aplicación nativa, es necesario codificar la entrada a la aplicación y algunos conceptos básicos, como el arranque, el enrutamiento de URL, etc. Intenté abordar esto con qooxdoo-website-skeleton, que pertenecen a los ejemplos anteriores. Eres libre de usarlo o escribir el tuyo.

Finalmente, tenga en cuenta que puede no ser tan fácil comenzar como con la biblioteca de JavaScript promedio, pero la complejidad es proporcional al beneficio final.

Cuestiones relacionadas