561 votes

Actuel communément acceptée meilleures pratiques en matière d'organisation de code en JavaScript

Comme frameworks JavaScript comme jQuery faire côté client les applications web plus riche et plus fonctionnel, j'ai commencé à remarquer un problème...

Comment voulez-vous garder ce organisé?

  • Mettez tous vos gestionnaires dans un endroit et écrire des fonctions pour tous les événements?
  • Créer des fonctions/classes pour l'emballage de tous vos fonctionnalité?
  • Écrire comme un fou et espère juste que cela fonctionne pour le mieux?
  • Donner et de commencer une nouvelle carrière?

Je mentionne jQuery, mais c'est vraiment tout code JavaScript en général. Je suis la recherche que comme des lignes sur les lignes commencent à s'accumuler, il devient plus difficile de gérer les fichiers de script ou de trouver ce que vous cherchez. Très probablement la plus grande propblems j'ai découvert il y a tellement de façons de faire la même chose, il est difficile de savoir lequel est le courant qui est couramment accepté les meilleures pratiques.

Existe-il des recommandations générales sur la meilleure façon de garder votre .js fichiers comme agréable et soigné que le reste de votre application? Ou est-ce juste une question de IDE? Est-il une meilleure option?


MODIFIER

Cette question a été conçu pour être plus sur le code d'organisation et de ne pas l'organisation des fichiers. Il y a eu quelques vraiment bons exemples de fusion de fichiers ou de la séparation du contenu autour.

Ma question est: quel est le courant qui est couramment accepté les meilleures pratiques pour organiser votre code? Quelle est votre façon, ou même un recommandé de la façon d'interagir avec les éléments de la page et de créer réutilisables code qui n'entre pas en conflit les uns avec les autres?

Certaines personnes ont répertorié les espaces de noms qui est une bonne idée. Quelles sont les autres façons, plus précisément sur les éléments sur la page, et garder le code organisé et soigné?

183voto

polarbear Points 2662

Il serait beaucoup plus agréable si javascript avait construit des espaces de noms, mais je trouve que l'organisation des choses comme Dustin Diaz décrit ici m'aide beaucoup.

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

J'ai mis les différents "espaces de noms" et parfois, les classes dans des fichiers séparés. Habituellement, je commence avec un fichier et en tant que classe ou de l'espace devient assez grand pour justifier, je me sépare d'elle dans son propre fichier. À l'aide d'un outil qui permet de combiner tous les fichiers pour la production est une excellente idée.

88voto

Jason Moore Points 2415

J'essaie d'éviter d'inclure le code javascript avec le code HTML. Tout le code est encapsulé dans des classes et chaque classe est dans son propre fichier. Pour le développement, j'ai séparé les balises <script> pour inclure chaque fichier js, mais ils sont fusionnés en un seul ensemble plus vaste de la production pour réduire la surcharge de requêtes HTTP.

Généralement, je vais avoir une seule "main" fichier js pour chaque application. Donc, si j'ai écrit un "sondage" de l'application, je voudrais avoir un fichier js appelé "survey.js". Cela permettrait de contenir le point d'entrée dans le code jQuery. J'ai créer jQuery références lors de l'instanciation, puis à les transmettre dans mes objets en tant que paramètres. Cela signifie que les classes javascript sont "pure" et ne contiennent pas de références à la CSS de l'ids ou les noms de classe.

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

Je trouve aussi convention de nommage pour être important pour des raisons de lisibilité. Par exemple: j'ajoute 'j' pour tous jQuery instances.

Dans l'exemple ci-dessus, il y a une classe appelée DimScreen. (Supposons que ce assombrit l'écran et affiche une boîte d'alerte.) Il a besoin d'un élément div qui il peut agrandir pour couvrir l'écran, puis ajouter une boîte d'alerte, de sorte que je passe dans un objet jQuery. jQuery est un plug-in concept, mais il semblait limiter (par exemple, les instances ne sont pas persistants et ne sont pas accessibles), sans réelle à l'envers. Ainsi, le DimScreen classe serait une norme de classe javascript qui arrive juste à utiliser 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>');
  //...
};

J'ai construit quelques-uns assez complexe appliations à l'aide de cette approche.

39voto

Greg Points 132247

Vous pouvez diviser vos scripts dans des fichiers séparés pour le développement, puis de créer une "libération" de la version où vous fourrer tous ensemble et exécuter YUI Compressor, ou quelque chose de similaire.

27voto

Damir Zekić Points 7517

Inspiré par les anciens messages, j'ai fait une copie de Rakefile et fournisseur annuaires distribués avec WysiHat (RTE mentionné par changelog) et a fait quelques modifications pour inclure le code de vérification avec JSLint et minification avec YUI Compressor.

L'idée est d'utiliser des Pignons (à partir de WysiHat) de fusionner plusieurs fichiers Javascript en un seul fichier, vérifier la syntaxe du fichier fusionné avec JSLint et rapetisser avec YUI Compressor, avant la distribution.

Conditions préalables

  • Java Runtime
  • le rubis et le râteau gem
  • Vous devez savoir comment mettre un JAR dans le Classpath

Maintenant, ne

  1. Téléchargement Rhino et mettre le POT ("js.jar") à votre classpath
  2. Télécharger YUI Compressor, et mettre le POT (build/yuicompressor-xyz.jar à votre classpath
  3. Télécharger WysiHat et la copie "vendeur" répertoire à la racine de votre projet JavaScript
  4. Télécharger JSLint pour Rhino et le mettre à l'intérieur le "vendeur" répertoire

Maintenant, créez un fichier nommé "Rakefile" dans le répertoire racine du projet JavaScript et ajoutez le contenu suivant:

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 vous avez tout fait correctement, vous devriez être en mesure d'utiliser les commandes suivantes dans la console:

  • rake merge -- à la fusion de différents fichiers JavaScript en un seul
  • rake check -- pour vérifier la syntaxe de votre code (c'est la valeur par défaut de la tâche, de sorte que vous pouvez simplement taper rake)
  • rake minify -- pour préparer version minifiée de votre code JS

Sur la source de la fusion

À l'aide de Pignons, le JavaScript pré-processeur, vous pouvez inclure (ou require) autres fichiers JavaScript. Utilisez la syntaxe suivante pour inclure d'autres scripts à partir de l'initiale du fichier (nommé "main.js" mais vous pouvez changer cela dans 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
})();

Et puis...

Jetez un oeil à Rakefile fourni avec WysiHat pour définir les tests unitaires automatisés. Sympa tout ça :)

Et maintenant pour la réponse

Cela ne répond pas à la question d'origine très bien. Je sais et j'en suis désolé, mais j'ai posté ici parce que, je l'espère, il peut être utile à quelqu'un d'autre pour organiser leur désordre.

Mon approche du problème est de faire autant de l'objet-modélisation orientée que je peux et implémentations séparées en différents fichiers. Ensuite, les gestionnaires doivent être aussi courts que possible. L'exemple avec List singleton est aussi une belle.

Et les espaces de noms... eh bien, ils peuvent être imité par les plus profondes de la structure de l'objet.

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

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

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

Je ne suis pas grand fan des imitations, mais cela peut être utile si vous avez beaucoup d'objets que vous souhaitez déplacer hors de la portée globale.

18voto

Nery Jr Points 1008

Le code de l'organisation nécessite l'adoption de conventions et de normes de documentation:
1. Espace de noms de code pour un fichier physique;

Exc = {};


2. Les cours de groupe dans ces espaces de javascript;
3. Ensemble de Prototypes ou liées à des fonctions ou des classes pour représenter les objets du monde réel;

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


4. Ensemble de conventions pour améliorer le code. Par exemple, le groupe de toutes ses fonctions internes ou de méthodes de sa classe attribut d'un type d'objet.

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


5. Faire de la documentation des espaces de noms, classes, méthodes et variables. Où faut aussi discuter de certaines des code (FIs et Fors, ils implémentent généralement important de la logique du code).

/**
  * 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;
    ...
};


Ce sont juste quelques conseils, mais qui a grandement aidé à organiser le code. Rappelez-vous, vous devez avoir la discipline pour réussir!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X