Praktik terbaik yang diterima umum di sekitar organisasi kode dalam JavaScript [ditutup]

561

Karena kerangka kerja JavaScript seperti jQuery membuat aplikasi web sisi klien lebih kaya dan lebih fungsional, saya mulai memperhatikan satu masalah ...

Bagaimana Anda mengaturnya?

  • Letakkan semua penangan Anda di satu tempat dan tulis fungsi untuk semua acara?
  • Buat fungsi / kelas untuk membungkus semua fungsionalitas Anda?
  • Menulis seperti orang gila dan hanya berharap itu berhasil untuk yang terbaik?
  • Menyerah dan mendapatkan karier baru?

Saya menyebutkan jQuery, tetapi sebenarnya ini adalah kode JavaScript pada umumnya. Saya menemukan bahwa ketika baris demi baris mulai menumpuk, semakin sulit untuk mengelola file skrip atau menemukan apa yang Anda cari. Sangat mungkin masalah terbesar yang saya temukan adalah ada begitu banyak cara untuk melakukan hal yang sama, sulit untuk mengetahui mana yang merupakan praktik terbaik yang saat ini diterima secara umum.

Apakah ada rekomendasi umum tentang cara terbaik untuk menjaga file .js Anda tetap bagus dan rapi seperti aplikasi lainnya? Atau ini hanya masalah IDE? Apakah ada opsi yang lebih baik di luar sana?


EDIT

Pertanyaan ini dimaksudkan untuk lebih tentang organisasi kode dan bukan organisasi file. Ada beberapa contoh penggabungan file atau pemisahan konten yang sangat bagus.

Pertanyaan saya adalah: apa cara praktik terbaik yang saat ini diterima secara umum untuk mengatur kode Anda yang sebenarnya? Apa cara Anda, atau bahkan cara yang disarankan untuk berinteraksi dengan elemen halaman dan membuat kode yang dapat digunakan kembali yang tidak saling bertentangan?

Beberapa orang telah mendaftarkan ruang nama yang merupakan ide bagus. Apa beberapa cara lain, lebih khusus berurusan dengan elemen pada halaman dan menjaga kode terorganisir dan rapi?

Hugoware
sumber
seseorang yang benar-benar meluangkan waktu untuk berbicara tentang organisasi kode itu sendiri, bukan "hanya" alat apa yang dia gunakan untuk menggabungkan & mengompresi file JS-nya: stackoverflow.com/questions/16736483/…
Adrien Be

Jawaban:

183

Akan jauh lebih baik jika javascript memiliki ruang nama terpasang, tetapi saya menemukan bahwa mengatur hal-hal seperti yang dijelaskan Dustin Diaz di sini sangat membantu saya.

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

Saya menempatkan "ruang nama" yang berbeda dan kadang-kadang kelas individu dalam file terpisah. Biasanya saya mulai dengan satu file dan sebagai kelas atau namespace menjadi cukup besar untuk menjaminnya, saya pisahkan menjadi file sendiri. Menggunakan alat untuk menggabungkan semua file Anda untuk produksi adalah ide yang bagus juga.

polarbear
sumber
24
Saya biasanya menyebutnya sebagai "cara crockford". +1 dari saya
Matt Briggs
4
Anda bahkan bisa melangkah lebih jauh. Lihat tautan ini: wait-till-i.com/2007/08/22/…
MKroehnert
4
@MattBriggs atau disebut module patterndan didasarkan pada IIFE pattern.
Adrien Be
Apakah Anda tidak perlu mengekspor kelas entah bagaimana? Bagaimana suatu objek dapat dibuat dari luar modul seperti itu? Atau haruskah ada metode createNewSomething()dalam objek kembali, sehingga penciptaan objek terjadi hanya dalam modul? Hm ... Saya berharap bahwa kelas (konstruktor) terlihat dari luar.
robsch
@robsch Teladannya tidak mengambil parameter apa pun, tetapi sebagian besar akan melakukannya. Lihat contoh saya di sini untuk mengetahui bagaimana hal ini biasanya dilakukan (TypeScript, tetapi 99% sama): repl.it/@fatso83/Module-Pattern-in-TypeScript
oligofren
88

Saya mencoba untuk menghindari memasukkan javascript dengan HTML. Semua kode dirangkum ke dalam kelas-kelas dan masing-masing kelas di file sendiri. Untuk pengembangan, saya memiliki tag <script> terpisah untuk memasukkan setiap file js, tetapi mereka digabung menjadi satu paket yang lebih besar untuk produksi untuk mengurangi overhead permintaan HTTP.

Biasanya, saya akan memiliki satu file js 'utama' untuk setiap aplikasi. Jadi, jika saya sedang menulis aplikasi "survei", saya akan memiliki file js yang disebut "survey.js". Ini akan berisi titik masuk ke dalam kode jQuery. Saya membuat referensi jQuery selama instantiation dan kemudian meneruskannya ke objek saya sebagai parameter. Ini berarti bahwa kelas javascript 'murni' dan tidak mengandung referensi ke id CSS atau nama kelas.

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

Saya juga menemukan konvensi penamaan menjadi penting untuk keterbacaan. Sebagai contoh: Saya menambahkan 'j' ke semua instance jQuery.

Pada contoh di atas, ada kelas yang disebut DimScreen. (Asumsikan ini meredupkan layar dan memunculkan kotak peringatan.) Perlu elemen div yang dapat diperbesar untuk menutupi layar, dan kemudian menambahkan kotak peringatan, jadi saya meneruskan objek jQuery. jQuery memiliki konsep plug-in, tetapi tampaknya membatasi (mis. instance tidak persisten dan tidak dapat diakses) tanpa terbalik nyata. Jadi kelas DimScreen akan menjadi kelas javascript standar yang kebetulan menggunakan 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>');
  //...
};

Saya telah membangun beberapa aplikasi yang cukup rumit menggunakan pendekatan ini.

Jason Moore
sumber
15
Saya menemukan bahwa menggunakan $sebagai awalan nama variabel adalah praktik yang lebih umum, tetapi saya bisa saja salah. Jadi, $s = $('...')alih-alih jS = $('...'), hanya masalah preferensi, kurasa. Namun menarik, karena notasi Hongaria dianggap bau kode. Sungguh aneh betapa berbedanya beberapa konvensi / preferensi kode JavaScript saya dengan konvensi pengkodean C # / Java saya.
jamiebarrow
9
@ Jamie Ini bukan bau kode dalam kasus ini, justru salah satu dari beberapa kasus di mana Hongaria bagus . Anda mungkin ingin membaca ini .
Dan Abramov
3
@DanAbramov terima kasih atas tautannya. Saya benar-benar harus membaca semua blog Joel, dia menjelaskan semuanya dengan sangat baik. Pasti pantas ketenaran / reputasi yang dimilikinya. Saya akan menyebutnya Systems Hungariansebagai kode bau dan Apps Hungariansebagai praktik mulai sekarang :)
jamiebarrow
Saya kira di dunia C #, itu juga bisa menjadi artikel yang bagus untuk mempromosikan penggunaan var, sekarang saya memikirkannya. Sebagian besar argumen yang menentang penggunaan varadalah di mana Anda tidak akan yakin dengan 'tipe' dari apa yang dikembalikan, tapi saya kira argumennya lebih baik menentang tidak mengetahui 'kelas' dari apa yang dikembalikan. Jika menggunakan Apps Hungarian, Anda seharusnya tidak perlu khawatir ... menarik.
jamiebarrow
3
@Marnen: Saya mengerti maksud Anda, tetapi itu tidak berguna sebagai panduan untuk programmer. $ Awalan mengingatkan saya apa itu ketika membaca kode saya nanti, dan dengan demikian membantu pemahaman lebih cepat.
Sean
39

Anda dapat memecah skrip Anda menjadi file-file terpisah untuk pengembangan, kemudian membuat versi "rilis" di mana Anda menjejalkan semuanya dan menjalankan Kompresor YUI atau yang serupa dengannya.

Greg
sumber
Terkadang ada skrip javascript yang tidak dibutuhkan. Akan sia-sia mengirimkannya ke klien. Saya pikir hanya untuk mengirim apa yang dibutuhkan. Tentu saja, untuk aplikasi web yang digunakan sepanjang hari, seperti aplikasi intranet, mungkin lebih baik untuk mengirim seluruh batch sekaligus, pada pemuatan halaman pertama.
DOK
2
Kompilasi @DOK harus mencakup eksisi barang yang tidak digunakan.
aehlke
Ada juga konsep pemuatan malas untuk mencoba dan mengurangi kebutuhan bandwidth, di mana Anda memuat halaman awal, dan kemudian melakukan pemuatan asinkron file skrip yang diperlukan (seperti disebutkan dalam jawaban lain untuk pertanyaan ini). Padahal, itu mungkin membutuhkan lebih banyak permintaan dan sebenarnya bisa kurang bermanfaat. @DOK, jika JS di-cache, satu permintaan sedang mungkin lebih baik daripada beberapa permintaan kecil.
jamiebarrow
27

Terinspirasi oleh posting sebelumnya saya membuat salinan Rakefile dan direktori vendor yang didistribusikan dengan WysiHat (RTE yang disebutkan oleh changelog) dan membuat beberapa modifikasi untuk memasukkan pengecekan kode dengan JSLint dan minifikasi dengan YUI Compressor .

Idenya adalah untuk menggunakan Sprockets (dari WysiHat) untuk menggabungkan beberapa JavaScripts menjadi satu file, periksa sintaksis file yang digabungkan dengan JSLint dan minify dengan YUI Compressor sebelum didistribusikan.

Prasyarat

  • Java Runtime
  • permata ruby ​​dan rake
  • Anda harus tahu cara memasukkan JAR ke dalam Classpath

Sekarang lakukan

  1. Unduh Badak dan masukkan JAR ("js.jar") ke classpath Anda
  2. Unduh YUI Compressor dan masukkan JAR (build / yuicompressor-xyz.jar) ke classpath Anda
  3. Unduh WysiHat dan salin direktori "vendor" ke root proyek JavaScript Anda
  4. Unduh JSLint untuk Rhino dan letakkan di dalam direktori "vendor"

Sekarang buat file bernama "Rakefile" di direktori root proyek JavaScript dan tambahkan konten berikut ke dalamnya:

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

Jika Anda melakukan semuanya dengan benar, Anda harus dapat menggunakan perintah berikut di konsol Anda:

  • rake merge - untuk menggabungkan berbagai file JavaScript menjadi satu
  • rake check- untuk memeriksa sintaks kode Anda (ini adalah tugas default , jadi Anda cukup mengetikrake )
  • rake minify - untuk menyiapkan versi minify dari kode JS Anda

Penggabungan sumber

Menggunakan Sprockets, pre-prosesor JavaScript yang dapat Anda sertakan (atau require) file JavaScript lainnya. Gunakan sintaks berikut untuk memasukkan skrip lain dari file awal (bernama "main.js", tetapi Anda bisa mengubahnya di 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
})();

Lalu...

Lihatlah Rakefile yang disediakan dengan WysiHat untuk mengatur pengujian unit otomatis. Barang bagus :)

Dan sekarang untuk jawabannya

Ini tidak menjawab pertanyaan asli dengan sangat baik. Saya tahu dan saya minta maaf tentang hal itu, tetapi saya telah mempostingnya di sini karena saya berharap semoga bermanfaat bagi orang lain untuk mengatur kekacauan mereka.

Pendekatan saya terhadap masalah ini adalah melakukan sebanyak mungkin pemodelan berorientasi objek dan memisahkan implementasi ke dalam file yang berbeda. Maka pawang harus sesingkat mungkin. Contoh dengan Listsingleton juga bagus.

Dan ruang nama ... yah mereka bisa ditiru oleh struktur objek yang lebih dalam.

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

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

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

Saya bukan penggemar imitasi, tetapi ini bisa membantu jika Anda memiliki banyak objek yang ingin Anda pindah dari ruang lingkup global.

Damir Zekić
sumber
18

Organisasi kode memerlukan adopsi konvensi dan standar dokumentasi:
1. Kode namespace untuk file fisik;

Exc = {};


2. Kelas grup dalam javascript namespaces ini;
3. Tetapkan Prototipe atau fungsi atau kelas terkait untuk mewakili objek dunia nyata;

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


4. Tetapkan konvensi untuk meningkatkan kode. Misalnya, kelompokkan semua fungsi atau metode internal di atribut kelasnya dari tipe objek.

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


5. Buat dokumentasi ruang nama, kelas, metode, dan variabel. Di mana perlu juga membahas beberapa kode (beberapa FI dan Fors, mereka biasanya menerapkan logika penting dari kode).

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


Ini hanya beberapa tips, tetapi itu sangat membantu dalam mengatur kode. Ingat Anda harus disiplin untuk berhasil!

Nery Jr
sumber
13

Mengikuti prinsip-prinsip desain OO dan pola desain yang baik akan membuat kode Anda mudah dipelihara dan dipahami. Tapi salah satu hal terbaik yang saya temukan baru-baru ini adalah sinyal dan slot alias publikasikan / berlangganan. Lihat http://markdotmeyer.blogspot.com/2008/09/jquery-publish-subscribe.html untuk implementasi jQuery yang sederhana.

Idenya digunakan dengan baik dalam bahasa lain untuk pengembangan GUI. Ketika sesuatu yang signifikan terjadi di suatu tempat dalam kode Anda, Anda mempublikasikan acara sintetis global yang berlangganan metode lain di objek lain. Ini memberikan pemisahan objek yang sangat baik.

Saya pikir Dojo (dan Prototipe?) Memiliki versi built-in dari teknik ini.

lihat juga Apa itu sinyal dan slot?

meouw
sumber
Saya sudah melakukan ini di jQuery. JS memiliki model acara bawaan, sehingga Anda tidak benar-benar membutuhkan banyak dukungan kerangka kerja.
Marnen Laibow-Koser
12

Saya berhasil menerapkan Pola Modul Javascript ke aplikasi Ext JS di pekerjaan saya sebelumnya. Ini memberikan cara sederhana untuk membuat kode yang dienkapsulasi dengan baik.

Alan
sumber
11

Dojo memiliki sistem modul sejak hari pertama. Bahkan itu dianggap sebagai landasan Dojo, lem yang menyatukan semuanya:

Menggunakan modul, Dojo mencapai tujuan berikut:

  • Ruang nama untuk kode Dojo dan kode khusus ( dojo.declare()) - jangan mencemari ruang global, hidup berdampingan dengan perpustakaan lain, dan kode tidak-sadar pengguna.
  • Memuat modul secara sinkron atau asinkron dengan nama ( dojo.require()).
  • Custom membangun dengan menganalisis dependensi modul untuk membuat satu file atau sekelompok file yang saling bergantung (disebut lapisan) untuk hanya menyertakan apa yang dibutuhkan aplikasi web Anda. Pembuatan kustom dapat mencakup modul Dojo dan modul yang disediakan pelanggan.
  • Akses transparan berbasis CDN ke Dojo dan kode pengguna. Baik AOL dan Google membawa Dojo dengan cara ini, tetapi beberapa pelanggan melakukan itu untuk aplikasi web kustom mereka juga.
Eugene Lazutkin
sumber
9

Lihat JavasciptMVC .

Kamu bisa :

  • pisahkan kode Anda menjadi lapisan model, tampilan dan pengontrol.

  • kompres semua kode menjadi satu file produksi

  • menghasilkan kode secara otomatis

  • buat dan jalankan tes unit

  • dan banyak lagi...

Yang terbaik dari semuanya, ia menggunakan jQuery, sehingga Anda dapat memanfaatkan plugin jQuery lainnya juga.

andyuk
sumber
Yup, saya sudah menggunakan jmvc dan itu cukup bagus - docs bisa lebih baik
meouw
9

Bos saya masih berbicara tentang saat-saat ketika mereka menulis kode modular (bahasa C), dan mengeluh tentang betapa buruknya kode saat ini! Dikatakan bahwa programmer dapat menulis assembly dalam kerangka apa pun. Selalu ada strategi untuk mengatasi kode organisasi. Masalah dasarnya adalah dengan cowok yang memperlakukan skrip java sebagai mainan dan tidak pernah mencoba mempelajarinya.

Dalam kasus saya, saya menulis file js berdasarkan tema UI atau layar aplikasi, dengan init_screen () yang tepat. Menggunakan konvensi penamaan id yang tepat, saya memastikan bahwa tidak ada konflik ruang nama di tingkat elemen root. Di window.load () yang tidak mencolok, saya ikat semuanya berdasarkan id tingkat atas.

Saya benar-benar menggunakan penutupan dan pola skrip java untuk menyembunyikan semua metode pribadi. Setelah melakukan ini, tidak pernah menghadapi masalah sifat yang bertentangan / definisi fungsi / definisi variabel. Namun, ketika bekerja dengan tim, seringkali sulit untuk menegakkan kekakuan yang sama.

questzen
sumber
9

Saya terkejut tidak ada kerangka kerja MVC yang disebutkan. Saya telah menggunakan Backbone.js untuk memodulasi dan memisahkan kode saya, dan itu sangat berharga.

Ada beberapa jenis kerangka kerja di luar sana, dan kebanyakan dari mereka juga sangat kecil. Pendapat pribadi saya adalah bahwa jika Anda akan menulis lebih dari sekedar beberapa baris jQuery untuk hal-hal UI yang mencolok, atau menginginkan aplikasi Ajax yang kaya, kerangka kerja MVC akan membuat hidup Anda lebih mudah.

Chetan
sumber
8

"Menulis seperti orang gila dan hanya berharap itu bekerja untuk yang terbaik?", Saya telah melihat proyek seperti ini yang dikembangkan dan dikelola oleh hanya 2 pengembang, aplikasi besar dengan banyak kode javascript. Selain itu ada beberapa cara pintas yang berbeda untuk setiap fungsi jquery yang mungkin dapat Anda pikirkan. Saya menyarankan mereka mengatur kode sebagai plugin, karena itu setara dengan jquery kelas, modul, namespace ... dan seluruh jagat raya. Tetapi segalanya menjadi lebih buruk, sekarang mereka mulai menulis plugins menggantikan setiap kombinasi dari 3 baris kode yang digunakan dalam proyek. Personaly Saya pikir jQuery adalah iblis dan tidak boleh digunakan pada proyek-proyek dengan banyak javascript karena itu mendorong Anda untuk menjadi malas dan tidak memikirkan mengatur kode dengan cara apa pun. Saya lebih suka membaca 100 baris javascript daripada satu baris dengan 40 fungsi jQuery dirantai (I ' saya tidak bercanda). Bertentangan dengan kepercayaan populer, sangat mudah untuk mengatur kode javascript dalam setara dengan ruang nama dan kelas. Itulah yang dilakukan YUI dan Dojo. Anda dapat dengan mudah menggulung sendiri jika mau. Saya menemukan pendekatan YUI jauh lebih baik dan efisien. Tetapi Anda biasanya memerlukan editor yang bagus dengan dukungan untuk cuplikan untuk mengimbangi konvensi penamaan YUI jika Anda ingin menulis sesuatu yang bermanfaat.

Vasil
sumber
3
Saya setuju dengan Anda tentang perintah yang sangat panjang, dirantai, tetapi salah satu bagian terbaik dari jQuery adalah bahwa ia menjaga semua Javascript dari HTML. Anda dapat mengatur event handler untuk semua elemen Anda tanpa "perlu" untuk menambahkan ID atau pada acara <wh Apapun> pada elemen Anda. Seperti biasa, penggunaan alat apa pun buruk ...
Hugoware
Saya telah bekerja pada proyek-proyek besar dan terorganisir dengan baik di jQuery. Saya tidak tahu mengapa Anda berpikir itu menghalangi organisasi.
Marnen Laibow-Koser
7

Saya membuat lajang untuk setiap hal yang saya benar-benar tidak perlu instantiate beberapa kali di layar, kelas untuk yang lainnya. Dan semuanya ditempatkan di namespace yang sama di file yang sama. Semuanya dikomentari, dan dirancang dengan UML, diagram keadaan. Kode javascript jelas html sehingga tidak ada javascript inline dan saya cenderung menggunakan jquery untuk meminimalkan masalah lintas browser.

Nikola Stjelja
sumber
3
komentar yang baik adalah KUNCI - Saya senang Anda mengatakannya sehingga saya tidak perlu berkomentar. Saya akan menambahkan konvensi penamaan yang konsisten, semacam strategi organisasi yang mudah dipahami untuk variabel & amp; fungsi, dan seperti yang Anda sebutkan, penggunaan kelas secara bijaksana versus lajang.
matt lohkamp
Tidak. Jika Anda perlu komentar, kode Anda umumnya tidak cukup dapat dibaca. Berusaha keras untuk menulis kode yang tidak memerlukan komentar.
Marnen Laibow-Koser
Juga, jika Anda memerlukan UML dan diagram keadaan, itu mungkin berarti bahwa arsitektur Anda tidak cukup jelas dari kode. Downvoting.
Marnen Laibow-Koser
1
@Marnen Proyek yang ditulis dengan baik mencakup komentar untuk menggambarkan MENGAPA, belum tentu APA. Kode sudah menggambarkan APA, tetapi sering kali Anda membutuhkan sesuatu untuk menjelaskan MENGAPA. Upvoting.
Cypher
@ Chypher Proyek yang ditulis dengan baik memiliki kode yang cukup jelas sehingga Anda biasanya dapat mengatakan "mengapa", bukan hanya "apa". Saya tidak akan percaya komentar untuk memberi tahu saya "mengapa", karena saya tidak punya jaminan bahwa itu sinkron dengan kode. Biarkan kode dokumen itu sendiri.
Marnen Laibow-Koser
6

Dalam proyek terakhir saya -Viajeros.com- Saya telah menggunakan kombinasi beberapa teknik. Saya tidak akan tahu bagaimana mengatur aplikasi web - Viajeros adalah situs jejaring sosial untuk pelancong dengan bagian yang terdefinisi dengan baik, jadi agak mudah untuk memisahkan kode untuk setiap area.

Saya menggunakan simulasi namespace dan pemuatan modul yang malas sesuai dengan bagian situs. Pada setiap halaman memuat saya mendeklarasikan objek "vjr", dan selalu memuat satu set fungsi umum untuk itu (vjr.base.js). Kemudian setiap halaman HTML memutuskan modul mana yang perlu dengan sederhana:

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

Vjr.base.js mendapatkan masing-masing gzip dari server dan mengeksekusinya.

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

Setiap "modul" memiliki struktur ini:

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

Mengingat pengetahuan Javascript saya yang terbatas, saya tahu pasti ada cara yang lebih baik untuk mengelola ini, tetapi sampai sekarang ini berfungsi dengan baik bagi kami.

Danita
sumber
6

Mengorganisir kode Anda dengan cara NameSpace sentris Jquery mungkin terlihat sebagai berikut ... dan tidak akan berbenturan dengan API Javascript lainnya seperti Prototipe, 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>

Semoga ini membantu.

Darryl
sumber
Ini menurut saya sebagai kultus kargo kecil. jQuery.fnadalah penunjuk jQuery.prototype, karena $()sebenarnya mengembalikan instance baru dari fungsi konstruktor jQuery. Menambahkan 'plugin' ke jQuery berarti cukup memperluas prototipe-nya. Tetapi yang Anda lakukan bukanlah itu, dan ada cara yang lebih bersih untuk mencapai hal yang sama.
Adam Lassek
Saya percaya dia hanya membuat fungsi statis. Saya ingat melihatnya di dokumen jQuery bahwa cara mendeklarasikan fungsi statis ini dapat diterima
Alex Heyd
6

Prinsipal yang baik dari OO + MVC pasti akan sangat membantu dalam mengelola aplikasi javascript yang kompleks.

Pada dasarnya saya mengatur aplikasi dan javascript saya dengan desain yang sudah saya kenal (yang ada sejak masa pemrograman desktop saya ke Web 2.0)

JS OO dan MVC

Deskripsi untuk nilai numerik pada gambar:

  1. Widget mewakili tampilan aplikasi saya. Ini harus diperluas dan dipisahkan dengan rapi sehingga menghasilkan pemisahan yang baik yang MVC coba capai daripada mengubah widget saya menjadi kode spageti (setara dengan aplikasi web untuk menempatkan blok besar Javascript langsung dalam HTML). Setiap widget berkomunikasi melalui orang lain dengan mendengarkan acara yang dihasilkan oleh widget lain sehingga mengurangi penggabungan kuat antara widget yang dapat menyebabkan kode tidak terkelola (ingat hari menambahkan onclick di mana-mana yang menunjuk ke fungsi global dalam tag skrip? Urgh ...)
  2. Model objek mewakili data yang ingin saya isi di widget dan meneruskan bolak-balik ke server. Dengan mengenkapsulasi data ke modelnya, aplikasi menjadi agnostik format data. Sebagai contoh: sementara secara alami dalam Javascript model objek ini sebagian besar serial dan deserialized ke JSON, jika entah bagaimana server menggunakan XML untuk komunikasi, yang perlu saya ubah adalah mengubah lapisan serialisasi / deserialisasi dan tidak perlu mengubah semua kelas widget .
  3. Kelas-kelas pengontrol yang mengelola logika bisnis dan komunikasi ke server + kadang-kadang lapisan caching. Lapisan ini mengontrol protokol komunikasi ke server dan memasukkan data yang diperlukan ke dalam model objek
  4. Kelas dibungkus rapi dalam ruang nama yang sesuai. Saya yakin kita semua tahu betapa buruknya namespace global dalam Javascript.

Di masa lalu, saya akan memisahkan file menjadi js sendiri dan menggunakan praktik umum untuk membuat prinsip-prinsip OO dalam Javascript. Masalahnya saya segera menemukan bahwa ada beberapa cara untuk menulis JS OO dan belum tentu semua anggota tim memiliki pendekatan yang sama. Ketika tim bertambah besar (dalam kasus saya lebih dari 15 orang), ini menjadi rumit karena tidak ada pendekatan standar untuk Object Oriented Javascript. Pada saat yang sama saya tidak ingin menulis kerangka kerja saya sendiri dan mengulangi beberapa pekerjaan yang saya yakini sebagai orang yang lebih pintar daripada yang telah saya pecahkan.

jQuery sangat bagus sebagai Javascript Framework dan saya menyukainya, namun karena proyek semakin besar, saya jelas membutuhkan struktur tambahan untuk aplikasi web saya terutama untuk memfasilitasi praktik OO terstandarisasi. Bagi saya sendiri, setelah beberapa percobaan, saya menemukan bahwa YUI3 Base dan Widget ( http://yuilibrary.com/yui/docs/widget/ dan http://yuilibrary.com/yui/docs/base/index.html ) menyediakan infrastruktur persis apa yang saya butuhkan. Beberapa alasan mengapa saya menggunakannya.

  1. Ini menyediakan dukungan Namespace. Kebutuhan nyata akan OO dan pengaturan kode Anda dengan rapi
  2. Ini mendukung gagasan tentang kelas dan objek
  3. Ini memberikan cara terstandarisasi untuk menambahkan variabel instan ke kelas Anda
  4. Ini mendukung ekstensi kelas dengan rapi
  5. Ini menyediakan konstruktor dan destruktor
  6. Ini memberikan render dan pengikatan acara
  7. Ini memiliki kerangka dasar widget
  8. Setiap widget sekarang dapat berkomunikasi satu sama lain menggunakan model berbasis event standar
  9. Yang paling penting, ini memberikan semua insinyur Standar OO untuk pengembangan Javascript

Berlawanan dengan banyak pandangan, saya tidak harus memilih antara jQuery dan YUI3. Keduanya bisa hidup berdampingan secara damai. Sementara YUI3 menyediakan templat OO yang diperlukan untuk aplikasi web saya yang kompleks, jQuery masih memberi tim saya Abstraksi JS yang mudah digunakan yang kita semua sukai dan kenal.

Menggunakan YUI3, saya telah berhasil membuat pola MVC dengan memisahkan kelas-kelas yang memperluas Basis sebagai Model, kelas-kelas yang memperluas Widget sebagai Tampilan dan tentunya Anda memiliki kelas-kelas Pengendali yang membuat logika yang diperlukan dan panggilan sisi server.

Widget dapat berkomunikasi satu sama lain menggunakan model berbasis acara dan mendengarkan acara dan melakukan tugas yang diperlukan berdasarkan antarmuka yang telah ditentukan. Sederhananya, menempatkan struktur OO + MVC ke JS adalah kegembiraan bagi saya.

Hanya pelepasan tanggung jawab hukum, saya tidak bekerja untuk Yahoo! dan hanya seorang arsitek yang berusaha mengatasi masalah yang sama yang diajukan oleh pertanyaan asli. Saya pikir jika ada yang menemukan kerangka kerja OO yang setara, ini akan bekerja juga. Pada prinsipnya, pertanyaan ini juga berlaku untuk teknologi lain. Terima kasih Tuhan untuk semua orang yang datang dengan Prinsip OO + MVC untuk membuat hari-hari pemrograman kami lebih mudah dikelola.

momo
sumber
5

Saya menggunakan manajemen paket Dojo ( dojo.requiredan dojo.provide) dan sistem kelas ( dojo.declareyang juga memungkinkan pewarisan berganda sederhana) untuk memodulasi semua kelas / widget saya ke dalam file yang terpisah. Tidak hanya dosis ini menjaga kode Anda terorganisir, tetapi juga memungkinkan Anda melakukan malas / tepat waktu memuat kelas / widget.

Justin Johnson
sumber
3

Beberapa hari yang lalu, orang-orang di 37Signals merilis kontrol RTE , dengan twist. Mereka membuat pustaka yang menggabungkan file javascript menggunakan semacam perintah pra-prosesor.

Saya telah menggunakannya sejak memisahkan file JS saya dan kemudian pada akhirnya menggabungkannya menjadi satu. Dengan begitu saya dapat memisahkan masalah dan, pada akhirnya, hanya memiliki satu file yang melewati pipa (gzip, tidak kurang).

Dalam templat Anda, periksa apakah Anda dalam mode pengembangan, dan sertakan file yang terpisah, dan jika dalam produksi, sertakan yang terakhir (yang Anda harus "membangun" sendiri).

changelog
sumber
1
getsprockets.org adalah tautan langsung
Matt Gardner
3

Buat kelas palsu, dan pastikan apa pun yang dapat dilemparkan ke fungsi terpisah yang masuk akal dilakukan. Pastikan juga untuk banyak berkomentar, dan jangan menulis kode spagghetti, alih-alih menyimpan semuanya di bagian. Misalnya, beberapa kode omong kosong yang menggambarkan cita-cita saya. Jelas dalam kehidupan nyata saya juga menulis banyak perpustakaan yang pada dasarnya mencakup fungsi mereka.

$(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.
    }
};
Dmitri Farkov
sumber
3

Gunakan pola pewarisan untuk mengatur aplikasi jQuery besar.

Chetan
sumber
Saya mulai menggunakannya, bahkan untuk hal-hal yang sangat kecil / dasar, dan sangat membantu menjaga kode tetap bersih dan fleksibel. Ini layak digunakan bahkan untuk manipulasi JS sisi klien sederhana.
Chetan
Ini saya suka, dan gunakan di aplikasi saya.
Andreas
2

Saya pikir ini terkait dengan, mungkin, DDD (Domain-Driven Design). Aplikasi yang saya kerjakan, meskipun tidak memiliki API formal, memang memberikan petunjuk seperti itu dengan kode sisi server (nama kelas / file, dll). Berbekal itu, saya membuat objek tingkat atas sebagai wadah untuk seluruh domain masalah; lalu, saya menambahkan ruang nama di tempat yang dibutuhkan:

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');
ken
sumber
2

Untuk organisasi JavaScript telah menggunakan yang berikut ini

  1. Folder untuk semua javascript Anda
  2. Javascript tingkat halaman mendapatkan file sendiri dengan nama halaman yang sama. ProductDetail.aspx akan menjadi ProductDetail.js
  3. Di dalam folder javascript untuk file perpustakaan saya memiliki folder lib
  4. Masukkan fungsi pustaka terkait dalam folder lib yang ingin Anda gunakan di seluruh aplikasi Anda.
  5. Ajax adalah satu-satunya javascript yang saya pindahkan keluar dari folder javascript dan mendapatkan folder itu sendiri. Lalu saya menambahkan dua sub folder client dan server
  6. Folder klien mendapatkan semua file .js sementara folder server mendapatkan semua file sisi server.
Jason Web Terlalu Keren
sumber
Bagus untuk organisasi file. Saya melakukannya dengan kode. Tetapi pada akhirnya saya mengkompilasi kode saya di ... katakanlah dll. Anda memerlukannya dengan javascript juga atau Anda akhirnya akan meminta 15 js file per halaman.
graffic
Tidak ada yang salah dengan meminta 15 file JS per halaman. Peramban Anda akan menyimpannya untuk permintaan selanjutnya.
Marnen Laibow-Koser
@ MarnenLaibow-Koser Satu-satunya masalah dengan meminta 15 file JS pada halaman adalah berapa banyak permintaan HTTP yang dapat ditangani browser pada suatu waktu. Jadi, menggabungkannya menjadi satu file memungkinkan browser meminta file lain yang diperlukan secara bersamaan.
iwasrobbed
Itu benar, tetapi setelah beberapa klik pertama, mereka akan berada di cache browser, sehingga mereka tidak memerlukan koneksi HTTP.
Marnen Laibow-Koser
2

Saya menggunakan hal kecil ini. Ini memberi Anda 'memasukkan' arahan untuk template JS dan HTML. Itu benar-benar menghilangkan kekacauan.

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.
        });
    }
});
gaperton
sumber
2

Anda dapat menggunakan jquery mx (digunakan dalam javascriptMVC) yang merupakan sekumpulan skrip yang memungkinkan Anda untuk menggunakan model, tampilan, dan pengontrol. Saya telah menggunakannya dalam proyek dan membantu saya membuat javascript terstruktur, dengan ukuran skrip minimal karena kompresi. Ini adalah contoh pengontrol:

$.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'));

Anda juga dapat menggunakan hanya sisi pengontrol jquerymx jika Anda tidak tertarik dengan tampilan dan model bagian.

rolnn
sumber
1

Pertanyaan Anda adalah salah satu yang mengganggu saya akhir tahun lalu. Perbedaannya - memberikan kode ke pengembang baru yang belum pernah mendengar metode pribadi dan publik. Saya harus membangun sesuatu yang sederhana.

Hasil akhirnya adalah kerangka kerja kecil (sekitar 1KB) yang menerjemahkan literal objek menjadi jQuery. Sintaksnya secara visual lebih mudah untuk dipindai, dan jika js Anda tumbuh sangat besar, Anda dapat menulis pertanyaan yang dapat digunakan kembali untuk menemukan hal-hal seperti penyeleksi yang digunakan, memuat file, fungsi dependen, dll.

Memposting kerangka kerja kecil di sini tidak praktis, jadi saya menulis posting blog dengan contoh (Pertama saya. Itu petualangan!). Anda dipersilakan untuk melihatnya.

Untuk yang lainnya di sini dengan beberapa menit untuk memeriksanya, saya akan sangat menghargai umpan balik!

FireFox direkomendasikan karena mendukung toSource () untuk contoh permintaan objek.

Bersulang!

Adam

Adam
sumber
0

Saya menggunakan skrip khusus yang terinspirasi oleh perilaku Ben Nolan (saya tidak dapat menemukan tautan saat ini lagi, sayangnya) untuk menyimpan sebagian besar penangan acara saya. Penangan acara ini dipicu oleh elemen className atau Id, misalnya. Contoh:

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

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

});

Saya ingin memasukkan sebagian besar pustaka Javascript saya dengan cepat, kecuali yang berisi perilaku global. Saya menggunakan headplace () placeholder helper pembantu Zend untuk ini, tetapi Anda juga dapat menggunakan javascript untuk memuat skrip lain dengan cepat menggunakan Ajile misalnya.

Aron Rotteveel
sumber
Apakah ini yang Anda cari? koders.com/javascript/…
DOK
Yup, itu dia! :) Sepertinya kode di balik tautan ini jauh lebih baru daripada versi yang saya terinspirasi. Terima kasih atas usaha Anda!
Aron Rotteveel
0

Anda tidak menyebutkan apa bahasa sisi server Anda. Atau, lebih tepatnya, kerangka apa yang Anda gunakan - jika ada - di sisi server.

IME, saya mengatur hal-hal di sisi server dan membiarkan semuanya terguncang ke halaman web. Kerangka kerja ini diberi tugas mengatur tidak hanya JS yang harus dimuat setiap halaman, tetapi juga fragmen JS yang berfungsi dengan markup yang dihasilkan. Fragmen-fragmen seperti itu biasanya tidak Anda inginkan dipancarkan lebih dari satu kali - itulah sebabnya mereka diabstraksi ke dalam kerangka kerja agar kode itu dapat mengatasi masalah itu. :-)

Untuk halaman akhir yang harus memancarkan JS mereka sendiri, saya biasanya menemukan bahwa ada struktur logis dalam markup yang dihasilkan. JS lokal seperti itu sering dapat dirakit pada awal dan / atau akhir struktur seperti itu.

Perhatikan bahwa semua ini tidak membebaskan Anda dari penulisan JavaScript yang efisien! :-)

ahli statika
sumber
0

Malas Memuat kode yang Anda butuhkan sesuai permintaan. Google melakukan sesuatu seperti ini dengan google.loader mereka

Brig Lamoreaux
sumber