Bagaimana cara menghindari "kesalahan bahasa dinamis" yang khas?

42

Saya baru-baru ini menuangkan beberapa jam ke dalam JavaScript karena saya ingin mendapat manfaat dari basis pengguna yang besar. Melakukan hal itu, saya perhatikan sebuah pola yang oleh sebagian besar orang dikaitkan dengan bahasa dinamis. Anda membuat segala sesuatunya bekerja dengan sangat cepat, tetapi begitu kode Anda mencapai ukuran tertentu Anda membuang banyak waktu dengan kesalahan ketik, ejaan, dan refactoring secara umum. Kesalahan yang biasanya dikompilasi oleh kompiler saya. Dan tidak ada saya mencari kesalahan dalam logika ketika saya baru saja membuat kesalahan ketik pada modul lain.

Mengingat JavaScript yang luar biasa berikut dan bahasa yang diketik secara dinamis lainnya saya percaya bahwa ada sesuatu yang salah dengan pendekatan saya. Atau apakah ini harga yang harus Anda bayar?

Untuk membuatnya lebih ringkas:

  • Bagaimana Anda mendekati proyek JavaScript (atau bahasa dinamis lainnya dalam hal ini) dengan ~ 2000 LOC?
  • Apakah ada alat untuk mencegah saya melakukan kesalahan itu? Saya telah mencoba aliran oleh Facebook dan JSHint yang agak membantu, tetapi tidak menangkap kesalahan ketik.
TomTom
sumber
2
Meskipun ada cara untuk mengurangi biaya, ada yang biaya .
dcastro
29
Saya akan mencoba menulis program Anda dalam bahasa yang diketik secara statis yang mengkompilasi ke javascript, seperti Typescript, Scala.js atau Elm.
dcastro
6
pengujian, pengujian, lebih banyak pengujian, dan laporan cakupan.
njzk2
7
~ 2000 LOC adalah proyek kecil. Itu harus dengan mudah masuk ke dalam apa yang dilakukan oleh bahasa yang dinamis dengan mudah dan baik. Jika Anda kesulitan dengan proyek ukuran seperti itu, Anda memiliki masalah yang lebih mendasar dengan keterampilan pemrograman Anda daripada apa pun yang relevan dengan bahasa dinamis secara khusus.
Jack Aidley
5
@JackAidley Tidak setuju. OP digunakan untuk fokus pada masalah tingkat tinggi dan bukan apakah pengenal dieja dengan benar. Itu adalah keterampilan pemrograman. Memastikan ejaan yang benar dapat dilakukan oleh siswa kelas menengah dan / atau alat bantu.
mucaho

Jawaban:

37

Khusus berbicara tentang JavaScript, Anda bisa menggunakan TypeScript sebagai gantinya. Menawarkan beberapa hal yang Anda maksud. Mengutip situs web:

Jenis memungkinkan pengembang JavaScript untuk menggunakan alat dan praktik pengembangan yang sangat produktif seperti pemeriksaan statis dan refactoring kode ketika mengembangkan aplikasi JavaScript.

Dan itu hanya superset dari JS, artinya beberapa kode Anda yang ada akan bekerja dengan TS:

TypeScript dimulai dari sintaks dan semantik yang sama seperti yang diketahui jutaan pengembang JavaScript saat ini. Gunakan kode JavaScript yang ada, sertakan pustaka JavaScript populer, dan panggil kode TypeScript dari JavaScript.

VinArrow
sumber
11
... dan TypeScript pada dasarnya adalah Ecmascript 6.
Robert Harvey
11
Uh, kutipan itu menyakitkan. Itu hanya menunjukkan bahwa Microsoft selalu menjadi perusahaan bahasa statis yang tidak mengerti bahasa dinamis. "Jenis memungkinkan ... kode refactoring"? Sangat? Apakah departemen PR Microsoft menyadari bahwa kode refactoring sebagai praktik diciptakan dalam Smalltalk (bahasa dinamis) dan ada bahkan sebelum itu dalam Forth (bahasa tanpa huruf)? Bahwa alat refactoring otomatis pertama adalah bagian dari Smalltalk IDE, sebelum bahasa statis bahkan memiliki IDE? Bahwa Smalltalk IDE modern memiliki alat refactoring setidaknya sekuat jika tidak lebih dari Java, C #, dan C ++? Ayo.
Jörg W Mittag
5
TypeScript adalah bahasa yang hebat, mengapa Anda harus mencoba dan mendorongnya dengan omong kosong seperti itu?
Jörg W Mittag
29
@ Jörg saya tidak cukup tentang Smalltalk tahu, tapi setiap IDE tunggal untuk JavaScript atau Python saya lihat adalah mil di balik apa IDE yang baik untuk Java atau C # dapat melakukan. Juga ada beberapa hal yang tidak mungkin dilakukan dalam bahasa yang dinamis (beberapa refactor yang paling populer): Katakanlah Anda memiliki fungsi publik foo(x) { return x.bar;}atau semacamnya. Karena tidak ada informasi jenis dan fungsinya bersifat publik (maka Anda tidak dapat mengetahui semua penelepon), tidak mungkin bagi Anda untuk mengetahui apakah bilah harus diubah namanya menjadi baz jika Anda mengganti nama beberapa kelas.
Voo
10
Jawaban ini mengatakan bahwa solusi untuk "kesalahan bahasa dinamis" adalah tidak menggunakan bahasa dinamis sama sekali.
bgusach
19

Ada beberapa pendekatan yang dapat membantu:

Pengujian unit

Tuliskan tes unit jika memungkinkan. Hanya mengandalkan pengujian manual atau menemukan bug di alam liar adalah untung-untungan.

Gunakan kerangka kerja

Daripada memutar sendiri dan mempertaruhkan pengenalan bug, gunakan kerangka kerja yang mapan jika memungkinkan.

Lebih suka CSS / bahasa tingkat tinggi

Di mana Anda dapat menyerahkan fungsionalitas ke CSS atau bahasa tingkat tinggi apa pun yang Anda tulis.

Refactor

Refactor untuk mengurangi jumlah kode. Lebih sedikit kode = lebih sedikit tempat untuk kesalahan.

Penggunaan kembali

Gunakan kembali kode yang ada di mana Anda bisa. Meskipun kode tidak sama persis, lebih baik menyalin, menempel, dan memodifikasi daripada menulis sesuatu lagi.

IDE

IDE modern umumnya memiliki setidaknya beberapa dukungan Javascript. Beberapa editor teks juga sadar Javascript.

Robbie Dee
sumber
5
Meskipun benar, saran Anda pada dasarnya berlaku untuk setiap bahasa pemrograman dan terutama bertujuan memperbaiki kesalahan logis daripada yang muncul dari bahasa dinamis.
edmz
1
"Saran Anda pada dasarnya berlaku untuk setiap bahasa pemrograman" . Sangat benar - dengan cara yang hampir sama melalui persneling dari proyek hobi hingga solusi perusahaan penuh lemak, yang membutuhkan semakin banyak penyempitan, sama - semakin banyak Javascript yang ditulis, semakin banyak disiplin yang dibutuhkan jika roda tidak mau untuk cepat lepas. Eric Lippert menggambarkan ini dengan sangat baik.
Robbie Dee
4
"Lebih suka CSS / bahasa tingkat tinggi" - Saya tidak begitu mengerti apa arti bit ini dalam kaitannya dengan JavaScript: apakah Anda mengatakan untuk memindahkan elemen (seperti animasi, mungkin?) Ke dalam stylesheet daripada kode JS? Bagaimana kaitan CSS dengan bahasa tingkat tinggi?
anotherdave
@anotherdave Banyak hal yang dulu merupakan domain Javascript sekarang dapat dicapai dalam CSS3. Beberapa fungsionalitas juga dapat dipindahkan ke bahasa tingkat yang lebih tinggi yang akan tunduk pada kontrol yang lebih ketat.
Robbie Dee
4
@anotherdave Banyak hal yang orang coba lakukan dengan JavaScript tidak cocok dan tidak pantas. Perpustakaan yang menyediakan alat bahasa standar, kerangka kerja yang menyediakan elemen HTML standar sedikit lebih banyak, kode yang mereplikasi fungsi dasar seperti jangkar, emulasi MVC, gaya, implementasi ulang DOM, abstraksi AJAX, render objek sepele (reimplementing SVG), fitur polyfilling yang tidak bermanfaat bagi pengguna ... Anda harus meminimalkan jumlah JS yang Anda tulis. Jika Anda dapat melakukannya tanpa JS, lakukan tanpa JS.
bjb568
2

Salah satu alat yang belum disebutkan adalah pencarian teks sederhana, lokal file atau proyek-lebar .

Kedengarannya sederhana, tetapi ketika Anda memasukkan beberapa ekspresi reguler, Anda dapat melakukan pemfilteran dasar hingga lanjutan, mis. Mencari kata-kata yang terdapat dalam dokumentasi atau kode sumber.

Ini telah menjadi alat yang efektif bagi saya (selain analisa statis), dan mengingat ukuran proyek Anda sebesar 2k LOC, yang menurut saya tidak terlalu besar, semoga berhasil.

mucaho
sumber
2
greppergi jauh. Kecuali Anda tidak melakukan hal-hal dinamis yang terlalu aneh, itu berhasil. Namun, rasanya sangat manual jika Anda terbiasa dengan IDE untuk bahasa yang diketik secara statis.
bgusach
1

Saat ini saya sedang refactoring beberapa ribu baris kode pada proyek AngularJS besar. Salah satu kerepotan terbesar adalah mencari tahu kontrak yang tepat dari fungsi yang diberikan. Saya kadang-kadang akhirnya membaca dokumentasi API karena elemen respons API mentah ditugaskan ke variabel yang melewati 6 lapisan kode sebelum dimodifikasi dan dikembalikan melalui 6 lapisan kode lagi.

Saran pertama saya adalah merancang berdasarkan kontrak . Ambil input spesifik, hasilkan output spesifik, hindari efek samping, dan dokumentasikan ekspektasi tersebut menggunakan TypeScript atau setidaknya JSDoc.

Saran kedua saya adalah menerapkan sebanyak mungkin pemeriksaan. Kami mengikuti standar AirBnB dan menggunakan eslint pada seluruh basis kode kami. Kait komit memverifikasi bahwa kami selalu mengikuti standar. Kami secara alami memiliki baterai unit dan tes penerimaan, dan semua komitmen harus ditinjau oleh sejawat.

Beralih dari editor teks (Sublime Text) ke IDE yang tepat (WebStorm) juga membuatnya lebih mudah untuk bekerja dengan kode pada umumnya. WebStorm akan menggunakan JSDoc untuk memberikan petunjuk tentang tipe parameter yang diharapkan dan meningkatkan kesalahan jika Anda memberikan tipe yang salah atau menggunakan nilai balik dengan cara yang salah.

Dalam JavaScript, fitur-fitur baru seperti simbol dan pengambil / setter dapat membantu menegakkan tingkat kualitas tertentu dengan menambahkan pernyataan ke penugasan variabel (mis. Pastikan bilangan bulat berada dalam jangkauan, atau bahwa objek data memiliki atribut tertentu).

Sayangnya, saya tidak berpikir ada solusi yang benar untuk mencegah kesalahan bahasa dinamis, hanya serangkaian tindakan yang dapat membantu mengurangi frekuensi mereka.

Nicolas Bouliane
sumber
0

Jawaban saya untuk pertanyaan "Bagaimana Anda mendekati proyek JavaScript (atau bahasa dinamis lainnya dalam hal ini) dengan ~ 2000 LOC?"

Saya mengembangkan aplikasi formulir PDF. Saya mendekati proyek pengembangan perangkat lunak JavaScript saya (terlepas dari ukuran kode sumber) menggunakan elemen bersih dan penjelasan Petri. Metode ini tidak terikat pada teknologi bahasa pemrograman tertentu. Dengan demikian dapat digunakan untuk "bahasa pemrograman" lainnya.

Saya membuat diagram dari logika aplikasi. Untuk menjaga diagram tetap rapi, saya menambahkan sebagian besar penjelasan saya ke formulir yang saya gunakan dengan diagram. Entri dalam formulir termasuk referensi ke properti atau fungsi. Kemudian saya menulis kode sumber berdasarkan informasi dalam diagram dan entri dalam formulir. Metode ini sistematis karena setiap kode sumber yang ditulis langsung dipetakan dari diagram dan entri dalam formulir. Kode sumber dapat dengan mudah diperiksa karena saya juga mengikuti konvensi penamaan dan pengkodean ketika saya menulis kode.

Sebagai contoh, saya telah memilih konvensi bahwa semua fungsi adalah prototipe. Jika kinerja menjadi masalah maka itu dapat ditingkatkan dengan mendeklarasikan fungsi dalam konstruktor. Untuk beberapa properti saya menggunakan array. Sekali lagi jika kinerja menjadi masalah maka itu dapat diperbaiki dengan menggunakan referensi langsung.

Saya juga menggunakan eval. Ini dapat sangat mengurangi ukuran kode sumber. Karena masalah kinerja, saya menggunakan eval di bagian awal atau inisialisasi aplikasi saya; Saya tidak pernah menggunakannya dalam "logika runtime" - ini adalah konvensi pengkodean lain yang saya ikuti.

John Frederick Chionglo
sumber