565 votos

Actual comúnmente aceptadas como las mejores prácticas en torno a la organización del código en JavaScript

Como frameworks de JavaScript como jQuery hacer de lado de cliente de las aplicaciones web más ricas y más funcional, he empezado a notar un problema...

¿Cómo en el mundo se puede mantener esta organizado?

  • Ponga todos sus controladores en un lugar y escribir funciones para todos los eventos?
  • Create function/clases para envolver toda su funcionalidad?
  • Escribir como un loco y solo espero que salga lo mejor?
  • Dar y obtener una nueva carrera?

Menciono jQuery, pero realmente todo el código JavaScript en general. Me estoy encontrando que a medida que las líneas sobre las líneas empiezan a acumularse, se vuelve más difícil de gestionar los archivos de secuencia de comandos o encontrar lo que usted está buscando. Muy posiblemente la mayor propblems he encontrado es que hay tantas maneras de hacer la misma cosa, es difícil saber cual es la actual comúnmente aceptadas como las mejores prácticas.

Existen recomendaciones generales sobre la mejor manera de mantener su .js archivos tan bonito y limpio como el resto de su aplicación? O se trata simplemente de una cuestión de IDE? Hay una mejor opción que existe?


EDITAR

Esta pregunta estaba destinada a ser más acerca de la organización del código y no la organización de archivos. Ha habido algunos muy buenos ejemplos de la fusión de los archivos o la división de contenidos de todo.

Mi pregunta es: ¿cuál es la actual comúnmente aceptadas como las mejores prácticas para organizar el código real? ¿Cuál es su forma, o incluso una forma recomendada para interactuar con los elementos de la página y crear reutilizables de código que no entre en conflicto el uno con el otro?

Algunas personas han enumerado los espacios de nombres que es una buena idea. ¿Cuáles son algunas otras maneras, por más que traten específicamente de elementos de la página y mantener el código organizada y ordenada?

184voto

polarbear Puntos 2662

Sería mucho más agradable si javascript había construido espacios de nombres, pero me parece que organizar las cosas como Dustin Diaz describe aquí 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 los diferentes "espacios de nombres" y, a veces, clases individuales en archivos separados. Por lo general comienzo con un archivo y como una clase o espacio de nombres se hace tan grande que la justifique, me separe de ella en su propio archivo. El uso de una herramienta para combinar todos los archivos para la producción es una excelente idea.

89voto

Jason Moore Puntos 2415

Yo trato de evitar la inclusión de javascript con el código HTML. Todo el código está encapsulado en clases y cada clase es en su propio archivo. Para el desarrollo, he separar las etiquetas <script> para incluir cada archivo js, sino que se combinan en un solo paquete más grande para la producción para reducir la sobrecarga de las solicitudes HTTP.

Normalmente, voy a tener una sola " principal " archivo js para cada aplicación. Así que, si yo estaba escribiendo una "encuesta" de la aplicación, me gustaría tener un archivo js llamado "survey.js". Este contendría el punto de entrada en el código jQuery. Creo jQuery referencias durante la creación de instancias y, a continuación, pasar a mis objetos como parámetros. Esto significa que las clases de javascript son " puras " y no contiene ninguna referencia a los CSS de los identificadores 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();
});

Me parece también que la convención de nomenclatura a ser importante para mejorar la legibilidad. Por ejemplo: yo anteponer 'j' para todos jQuery instancias.

En el ejemplo anterior, hay una clase que se llama autodesk maya. (Asumir que esto reduce el brillo de la pantalla y aparece un cuadro de alerta.) Se necesita un elemento div que se puede ampliar para cubrir la pantalla y, a continuación, agregue un cuadro de alerta, por lo que yo paso en un objeto jQuery. jQuery tiene un concepto de plug-in, pero parecía que la limitación (por ej. las instancias no son persistentes y no se puede acceder), sin nada de boca. Así que el autodesk maya clase sería un estándar de clase de javascript que 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 construido algunos bastante compleja con aplicaciones que utilizan este enfoque.

39voto

Greg Puntos 132247

Usted puede romper sus scripts en archivos separados para el desarrollo, a continuación, crear una "versión" de la versión donde meter todo junto y ejecutar YUI Compressor o algo similar.

27voto

Damir Zekić Puntos 7517

Inspirada en anteriores posts he hecho una copia de Rakefile y proveedor de directorios distribuidos con WysiHat (RTE mencionado por changelog) y de hecho un par de modificaciones para incluir el código de comprobación con JSLint y minificación con YUI Compressor.

La idea es utilizar Piñones (de WysiHat) para combinar múltiples archivos Javascript en un archivo, la revisión de la sintaxis del archivo combinado con JSLint y minify con YUI Compressor antes de la distribución.

Requisitos previos

  • Tiempo De Ejecución De Java
  • ruby y el rastrillo de la gema
  • Usted debe saber cómo poner un JAR en el Classpath

Ahora

  1. Descargar Rhino y poner el FRASCO ("js.jar") a su classpath
  2. Descargar YUI Compressor y poner el FRASCO (build/yuicompressor-xyz.jar) a su classpath
  3. Descargar WysiHat y copia de "el proveedor" directorio raíz de su proyecto de JavaScript
  4. Descargar JSLint para Rhino y lo puso dentro del "proveedor" directorio

Ahora crea un archivo llamado "Rakefile" en el directorio raíz del proyecto de JavaScript y agregue el siguiente contenido:

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 has hecho todo correctamente, usted debería ser capaz de usar los siguientes comandos en la consola:

  • rake merge -- a combinar diferentes archivos de JavaScript en una
  • rake check -- a comprobar la sintaxis del código (este es el valor predeterminado de la tarea, así que usted puede simplemente escriba rake)
  • rake minify -- a preparar record de la versión de su código JS

En el origen de la fusión de

El uso de Piñones, el JavaScript pre-procesador puede incluir (o require) otros ficheros JavaScript. Utilice la siguiente sintaxis para incluir otras secuencias de comandos desde el archivo inicial (denominado "main.js"pero usted puede cambiar esto en la 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 luego...

Echa un vistazo a Rakefile siempre con WysiHat para establecer las pruebas unitarias automatizadas. Cosas bonitas :)

Y ya por la respuesta

Esto no responde a la pregunta original, muy bien. Lo sé, y lo lamento, pero he publicado aquí porque tengo la esperanza de que pueda ser útil para alguien más para organizar sus líos.

Mi enfoque del problema es que hacer como mucho orientada a objetos modelado puedo y implementaciones independientes en diferentes archivos. A continuación, los controladores deben ser tan cortas como sea posible. El ejemplo con List singleton es también agradable.

Y los espacios de nombres... así que puede ser imitado por los más profunda de la estructura del objeto.

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

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

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

Yo no soy gran fan de las imitaciones, pero esto puede ser útil si tienes muchos objetos que desea mover fuera del alcance mundial.

18voto

Nery Jr Puntos 1008

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

Exc = {};


2. Clases de grupo en estos espacios de nombres javascript;
3. Conjunto de Prototipos o relacionadas con las funciones o clases para la representación de 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, el grupo de todos los internos de funciones 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 discutir algunos de los código (algunos FIs y Fors, suelen implementar importante de la lógica 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, sino que ha ayudado en la organización del código. Recuerde que debe tener disciplina para tener éxito!

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X