JavaScript Gom Jabbar
(frantic.im)- Menggambarkan adegan seorang pengembang JavaScript berpengalaman 10 tahun membaca
package.jsonsebagai ujian rasa sakit, untuk menunjukkan betapa banyak kompleksitas yang terakumulasi di dalam satu file konfigurasi - Field seperti
main,browser,type: modulemembangkitkan luka migrasi lama dari Isomorphic JavaScript, bundle browser, serta transisi CommonJS dan ESM - Di dalam
scripts,dependencies,devDependencies, bercampur berbagai varian lint,watchman, gulp,left-pad, moment.js, dan masalah manajemen paket lama sepertiresolutions eslint,postcss,jestserta alat build dan test meningkatkan biaya pemeliharaan lingkungan pengembangan lewat aturan yang terlalu ketat, error instalasi spesifik platform, dan sulitnya konfigurasi ESM·TypeScript- Bahkan saat melihat
enginesNode, alasan tidak pindah ke Bun atau Deno adalah keyakinan bahwa rasa sakit itu tidak akan hilang, malah akan membesar; pengembang pun menutup file dan setidaknya berhasil bertahan hidup untuk sementara
Ujian membaca package.json
- Cerita dimulai dari situasi ketika seorang pengembang yang telah menggunakan JavaScript selama 10 tahun membuka file
package.jsondi depan komputer dan harus membacanya sampai habis - File ini bukan sekadar file konfigurasi sederhana, melainkan sesuatu yang sekaligus memunculkan kembali ingatan dan rasa sakit yang dialami dalam ekosistem JavaScript
versionmasih belum mencapai1.0, dan SemVer tersisa sebagai kenangan tidak menyenangkan tentang kebiasaan mengabaikannya yang sudah dipelajari sejak lamanamemenunjukkan situasi ketika nama yang diinginkan tidak bisa dipakai karena sudah diambil seseorang 7 tahun lalu dan paket itu tak pernah diperbarui lagi
Luka lama modul dan bundling
- Keberadaan field
maindanbrowsersecara bersamaan memperlihatkan jejak Isomorphic JavaScript - Ingatan tentang pernah mencoba me-
requiremodulfsdi bundle browser, serta hack yang digunakan agar itu bisa berjalan, tertinggal sebagai pengalaman yang tidak menyenangkan type: moduleterhubung dengan migrasi darirequirekeimport- Pengalaman mencoba saling mengimpor modul CommonJS dan ESM meninggalkan rasa sakit yang besar
Kekacauan script dan dependency
scriptsadalah pusat dari kekacauan yang panas dan menyakitkan- Ada berbagai varian seperti
lint,lintall,lintfast,lintdiff - Muncul eksekusi paralel, argumen yang tidak jelas, dan double escape pada argumen berformat JSON
- Bahkan setelah pindah ke yarn dan pnpm, beberapa subperintah masih memanggil npm
- Ada berbagai varian seperti
- Beberapa script masih menggunakan
watchman- Harus diingat bahwa tool ini tidak mendukung symlink sehingga seharusnya tidak digunakan
- Issue terkait sudah terbuka sejak 2015
- Script berbasis gulp juga masih tersisa, dan meski ingin menggantinya dengan sesuatu yang lebih modern, tak seorang pun berani melakukannya
Trauma yang dipanggil daftar paket
- Di dalam
dependenciesada sangat banyak paket, dan tiap paket menghidupkan kembali ingatan traumatis masing-masing left-padadalah paket kecil, tetapi tetap dikenang sebagai paket legendaris yang “merusak seluruh internet”- Setiap kali daftar dependency diubah, beberapa paket mencetak permintaan donasi atau peringatan breaking change yang panjang di konsol
- Pengembang pun hanya bisa berharap agar paket berbahaya tidak mencuri rahasia atau merusak komputernya
- moment.js dikenang sebagai library dengan API yang bagus, tetapi internet menilai library ini terlalu mutable, terlalu besar, dan tidak mendukung treeshaking, sehingga kini harus dimigrasikan ke date-fns
- Versi paket tertinggal jauh dari standar saat ini dan perlu di-upgrade, tetapi pengalaman upgrade di masa lalu membuat rasa sakit besar sudah bisa diperkirakan
resolutionstersisa sebagai bentuk rasa sakit lain yang dipilih demi menghindari upgrade paket
Kompleksitas lain yang diciptakan alat pengembangan
- Saat melihat
devDependencies, sulit bahkan untuk mengingat masa ketika hanya non-dev dependency yang dibutuhkan - Konfigurasi
eslinttelah menjadi terlalu ketat sehingga kesalahan kecil pun langsung diberi garis merah, dan CI memperlakukan masalah lint seolah kiamat sudah datang- Ini memberi rasa aman yang keliru bagi engineer junior di tim
- Pernah ada banyak perdebatan tentang aturan mana yang harus diaktifkan
- Rasa sakit bertambah sebanding dengan banyaknya
eslint-ignoredi seluruh codebase
postcsstidak digunakan secara langsung, tetapi tetap ada karena dibutuhkan oleh dependency dari dependency lain- Setiap kali mencoba
npm installdi platform baru, paket ini memunculkan error kompilasi C++ yang tidak jelas
- Setiap kali mencoba
jestbermula sebagai test runner cepat, tetapi kini telah menjadi besar dan berat, serta bergantung pada beberapa paket Babel- Sisa aplikasi ditranspilasi dengan kombinasi esbuild dan swc
- Mengonfigurasinya dengan benar agar cocok dengan ESM dan TypeScript sesulit “proyek ilmiah PhD”
- Di codebase, banyak tool dan parser terlibat seperti TypeScript, esbuild, swc, babel, eslint, prettier, jest, webpack, rollup, terser
- Di
engines,nodetertulis jelas, dan bahkan jika pindah ke Bun atau Deno, rasa sakit diyakini tidak akan berhenti dan justru akan memburuk - Setelah membaca sampai kurung kurawal penutup terakhir, ia menutup tab, mengatur napas, dan untuk sementara berhasil bertahan hidup dengan tangan dan otak yang masih utuh
1 komentar
Komentar Hacker News
Cukup lucu. Saya menulis JavaScript selama sekitar 18 tahun dan berhenti sekitar 3 tahun lalu, dan sebagian besar hal yang dikhawatirkan dalam daftar ini berasal dari 10 tahun terakhir
Yang особенно mencolok adalah tidak adanya polyfill yang pasti ada kalau ini ditulis pada 2013. Kira-kira mimpi buruk JavaScript tahun 2013 apa lagi yang sekarang hampir hilang? Tentu saja sekarang sudah digantikan oleh daftar lucu ini
Bagian favorit saya adalah saat menghitung alat dan parser yang benar-benar berfungsi di codebase lalu teringat TypeScript, esbuild, swc, babel, eslint, prettier, jest, webpack, rollup, terser, dan rasa sakitnya begitu besar sampai saya bahkan tidak ingin tahu apakah masih ada yang terlewat
undefinedyang ditimpa,with, closure untuk meniru field privat, prototype yang dimodifikasi, variabel global bawaan,thisyang berubah tergantung lokasi pemanggilan, koersi tipe otomatis saat perbandingan…Ya, memang begitu lebih dari 10 tahun hidup bersama JavaScript
SomeFunction.prototypeItu lalu dibungkus dalam fungsi anonim yang langsung dieksekusi dan dikembalikan sebagai objek, sehingga
SomeFunctionterlihat seperti kelas dan kita memanggilnew SomeFunction()atauSomeFunction.actualFunction(). Karena belum ada arrow function, kami juga mengutak-atikFunction.prototypesendiri untuk mengikat event ke scope lalu memakai.apply(), atau jatuh ke neraka.bind(this)tanpa akhir di setiap callback eventHari ini pun saya sial harus menulis tugas tes untuk perusahaan yang masih memakai JavaScript murni tanpa Promise atau declaration file, dan rasanya seperti kembali ke saat pertama kali bertemu Node pada 2012. Kewajiban memakai JavaScript saya siasati dengan JSDoc, tapi ternyata jauh lebih buruk daripada yang saya ingat
Setiap kali memulai proyek JavaScript baru, atau lebih tepatnya proyek TypeScript, saya selalu melalui prosedur yang sama
Biasanya ini frontend jadi saya memilih React, walau saya juga ingin mencoba Svelte. Dulu bundler-nya create-react-app atau wrapper Webpack, tapi sekarang pilihan terbaik adalah Vite karena konfigurasinya sedikit dan mendukung semua framework utama
Lalu saya memasang dan mengatur compiler TypeScript, biasanya copy-paste dari template. Targetnya JavaScript stabil terbaru dan modul ESM, lalu saya menyelaraskan eslint dan prettier, serta menambahkan plugin seperti TypeScript dan React. Saya juga memasang hook untuk menjalankan Prettier dan eslint sebelum commit
Saya juga memasang ekstensi IDE dan menyiapkan
.devcontaineratau daftar ekstensi yang direkomendasikan. Saya tidak terlalu peduli soal gaya itu sendiri; yang penting konsistensi kode dan deteksi kesalahan, jadi biasanya saya memakai konfigurasi eslint yang sudah jadiSetelah itu saya menyiapkan unit test seperti jest atau vitest, lalu ikut datang lagi pengaturan terkait TypeScript dan aturan eslint. Untuk framework CSS saya suka tailwind, jadi saya juga memasang styled-components dan twin.macro agar cocok dengan React, plus plugin Google Fonts atau pustaka font
Baru setelah kira-kira sehari seperti ini saya bisa mulai ngoding. Kenapa pekerjaannya sebanyak ini? Begitu banyak orang memakai kombinasi Vite + TypeScript + React/Vue/Svelte + eslint/prettier + tailwind/bootstrap + jest/vitest, jadi kenapa tidak ada library tanpa konfigurasi yang langsung cocok untuk 90% kasus penggunaan?
Sekalipun toolchain-nya akhirnya hidup, saya sama sekali tidak merasa mengendalikannya; rasanya seperti akan runtuh hanya karena guncangan kecil, dan saya pun tidak akan bisa memperbaikinya
Belakangan ini saya memutuskan untuk melihat sebagian besar stack JavaScript ini sebagai hambatan bagi pekerjaan yang sebenarnya ingin saya lakukan, lalu membuat aplikasi server-side rendering berbasis Flask dan Jinja2 seperti dulu. Memang tidak tampak modern berkilau dan tanpa CSS jadinya cukup jelek sekarang, tapi saya diberi saran untuk mencoba CSS modern murni. Meski begitu, kecepatan membuat fitur di stack itu benar-benar mengejutkan
package.json. Memang saya cuma mengerjakan backend, tapi untuk frontend pun bukankah bisa membuat template pribadi seperti itu?npm createmelakukan itu?Kalau menjalankan
npm create vue, hasilnya adalah konfigurasi Vue yang cukup bagus dan berfungsi dengan sebagian besar pengaturan sudah siap. Saya setuju ada banyak boilerplate dan mainan tambahan, tapi aplikasi yang kita bangun di web sekarang juga jauh lebih besar dibanding dulu. Anda tetap bisa memakai JavaScript tanpa tool hanya dengan ESModules, tapi itu jarang dilakukan karena tool-tool itu memang benar-benar melakukan sesuatu. Bukan cara yang paling rapi, tapi setidaknya berfungsiSaat memulai proyek baru, tinggal clone lalu ganti nama di beberapa tempat dan semuanya siap
Ini contoh lain ketika orang bilang JavaScript, padahal yang mereka maksud sebenarnya adalah “ruwetnya ekosistem Node”
Dari awal sudah disuruh membuka dan membaca file
package.json, dan setelah itu pun alurnya tetap seperti itu. Dari semua yang disebut, hampir tidak ada yang benar-benar terkait dengan JavaScript itu sendiriMemang benar JavaScript dan NodeJS bukan hal yang sama, tetapi kebanyakan orang mungkin paham maksud penulisnya. Akan lebih baik kalau ditulis lebih presisi, tapi juga sulit dibilang sepenuhnya salah
package.json. Sampai ECMA memasukkan package manager atau bundler ke spesifikasi resminya,package.jsonpada praktiknya adalah bagian dari JavaScriptSuka dengan nadanya yang bercanda. Setelah kulit dan ujung-ujung sarafmu terbakar beberapa lapis, ada gunanya mengingat kembali titik-titik rasa sakit seperti ini
Sebaliknya, artinya kamu bisa memberi MacBook baru ke developer junior yang termotivasi lalu melemparkannya ke air dalam, dan dalam sehari dia sudah bisa produktif. Tidak perlu tahu container, .NET, nginx, atau 100 alat command line yang sering dipakai, dan kalau ada masalah tinggal cari saja
Kamu tahu bahwa kalau bisa menyentuhnya langsung dengan tangan, kamu bisa membangun seluruh kapal dalam beberapa hari, tetapi malah harus melawan lapisan-lapisan kompleksitas yang tidak perlu sambil memperbaiki kapal di dalam botol dengan alat seadanya yang disediakan. Kalau kamu biasa melaju cepat dengan proyek pribadi yang hanya memakai JavaScript, HTML, dan CSS, lalu dimasukkan ke pekerjaan frontend modern, rasanya persis seperti itu
Mereka polos tidak menyadari bahwa membuatnya butuh berbulan-bulan, dan bahwa sebagian masalahnya justru adalah kebanyakan framework, sehingga besoknya pun itu sudah ketinggalan zaman
“Aku mengikuti petunjuknya lalu diberi tahu bahwa grunt belum terpasang. Sekarang aku sudah tua, jadi aku tidak begitu tahu apa itu grunt, dan file grunt milikku juga sepertinya ada yang tidak cocok. Jadi aku mencari-cari sedikit dan tahu apa itu grunt. Grunt adalah… sebenarnya sampai sekarang aku masih tidak begitu tahu.”
--Joe Armstrong, https://www.youtube.com/watch?v=lKXe3HUG2l4
Beberapa hari lalu aku menjalankan
gem install wayback_machine_downloader. Aku tidak pernah cukup menyukai Ruby sampai benar-benar masuk ke ekosistemnya, tetapi dari luar kelihatannya ekosistem itu terjaga dengan sangat stabil. gem masih alat yang dipakai, dan Rails juga masih adaAku sedang menunggu proyek baru yang benar-benar butuh frontend kompleks sampai melewati 0~30 baris JavaScript. Saat itu, rasanya aku akan lebih bahagia dengan HTMX daripada framework raksasa paling populer saat ini
Ini tulisan tentang npm, bukan JavaScript
Karena segala keruwetan seperti ini, aku membenci npm dan sebisa mungkin menghindarinya. Secara pribadi aku memakai Deno, dan di kantor aku memakai sesuatu berbasis monorepo mirip bazel yang membuat npm tidak diperlukan
Tetapi menurutku JavaScript/TypeScript adalah bahasa yang enak dipakai untuk ngoding, dan itu adalah bahasa pertama yang kupilih untuk apa pun yang mau kubuat. Sedih rasanya ketika orang bilang “JavaScript jelek”, padahal yang mereka maksud sebenarnya adalah membangun aplikasi React dengan npm itu yang jelek. Ngoding JavaScript/TypeScript modern itu benar-benar menyenangkan
Rasanya JavaScript dan ekosistemnya sudah meninggalkan PTSD pada kita semua sampai-sampai kita tidak bisa menikmati komedi dalam tulisan ini
Terlalu banyak diskusi yang “serius” tentang tulisan lucu. Silakan dibedah sepuasnya, tapi akan bagus kalau tetap ingat bahwa niat aslinya adalah humor
Sejujurnya, ekosistem pertamaku adalah Node, dan hal-hal lain yang kupelajari belakangan juga masing-masing punya masalah gila yang tidak kalah parah
Haskell sangat sulit dipakai di banyak mesin, memasangnya di MacOS pada 2019 juga menyiksa, dan mengelola ekosistemnya pun sulit. Makro dan extension-nya sangat membingungkan, dan kompatibilitas mundur bahasanya juga buruk. Sebaliknya, untuk JavaScript tahun 2010, biasanya kamu masih bisa berharap itu tetap jalan pada 2023
Bahkan membuat image Docker atau environment seperti codespace/gitpod dengan benar pun sulit, image bawaan yang disediakan GitHub juga kurang bagus dan punya masalah
C umumnya cukup oke di kebanyakan platform, tetapi bahasanya sendiri terus terang rumit dan menuntut pengetahuan yang sangat luas tentang keseluruhan sistem. Akibatnya, mudah sekali menghasilkan kode yang tidak portabel dan tidak cocok untuk sebagian besar kebutuhan pemrograman umum
Aku bisa lanjut lagi, tetapi siapa pun yang sudah memakai banyak bahasa tahu bahwa semua ekosistem punya banyak cacat dan kita semua terus menderita. Dengan PHP, aku belum pernah menyelesaikan setup proyek dalam hitungan beberapa hari, dan Elm memang tidak terlalu menyakitkan, tetapi punya masalahnya sendiri seperti model benevolent dictator dan kecepatan pengembangan
Saya adalah pengembang multibahasa yang merasa nyaman dengan berbagai paradigma dan bahasa pemrograman, baik frontend maupun backend
Hampir selalu bereaksi seperti ini setiap kali melihat
package.jsonlebih dari 20 barispackage.jsonlebih dari 200 barisMengucapkannya keras-keras seolah sedang mengusir iblis. “Jangan takut. Ketakutan adalah pembunuh pikiran. Ketakutan adalah kematian kecil yang membawa kehancuran total. Aku akan menghadapi ketakutanku. Aku akan membiarkannya melewatiku. Setelah ia berlalu, dengan mata batin aku akan melihat jalannya. Di tempat yang telah dilewati ketakutan, tidak akan ada apa-apa. Hanya aku yang akan tersisa.”
Sedang menangis
Adegan pengembang JavaScript gaya lama membaca tulisan itu sambil menderita PTSD dan kilas balik
Jangan takut. Ketakutan adalah pembunuh pikiran. Ketakutan adalah kematian kecil yang membawa kehancuran total
Aku akan menghadapi ketakutanku. Aku akan membiarkannya melewatiku. Setelah ia berlalu, dengan mata batin aku akan melihat jalannya
Di tempat yang telah dilewati ketakutan, tidak akan ada apa-apa. Hanya aku yang akan tersisa
Menyadari setelah selesai membaca tulisan itu bahwa ia berhasil selamat, tetapi sudah bermandikan keringat