3 poin oleh GN⁺ 2023-07-03 | 1 komentar | Bagikan ke WhatsApp
  • Menggambarkan adegan seorang pengembang JavaScript berpengalaman 10 tahun membaca package.json sebagai ujian rasa sakit, untuk menunjukkan betapa banyak kompleksitas yang terakumulasi di dalam satu file konfigurasi
  • Field seperti main, browser, type: module membangkitkan 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 seperti resolutions
  • eslint, postcss, jest serta 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 engines Node, 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.json di 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
  • version masih belum mencapai 1.0, dan SemVer tersisa sebagai kenangan tidak menyenangkan tentang kebiasaan mengabaikannya yang sudah dipelajari sejak lama
  • name menunjukkan 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 main dan browser secara bersamaan memperlihatkan jejak Isomorphic JavaScript
  • Ingatan tentang pernah mencoba me-require modul fs di bundle browser, serta hack yang digunakan agar itu bisa berjalan, tertinggal sebagai pengalaman yang tidak menyenangkan
  • type: module terhubung dengan migrasi dari require ke import
  • Pengalaman mencoba saling mengimpor modul CommonJS dan ESM meninggalkan rasa sakit yang besar

Kekacauan script dan dependency

  • scripts adalah 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
  • 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 dependencies ada sangat banyak paket, dan tiap paket menghidupkan kembali ingatan traumatis masing-masing
  • left-pad adalah 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
  • resolutions tersisa 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 eslint telah 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-ignore di seluruh codebase
  • postcss tidak digunakan secara langsung, tetapi tetap ada karena dibutuhkan oleh dependency dari dependency lain
    • Setiap kali mencoba npm install di platform baru, paket ini memunculkan error kompilasi C++ yang tidak jelas
  • jest bermula 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, node tertulis 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

 
GN⁺ 2023-07-03
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

    • Grunt, Gulp, CoffeeScript, IIFE, undefined yang ditimpa, with, closure untuk meniru field privat, prototype yang dimodifikasi, variabel global bawaan, this yang berubah tergantung lokasi pemanggilan, koersi tipe otomatis saat perbandingan…
      Ya, memang begitu lebih dari 10 tahun hidup bersama JavaScript
    • Saya setuju soal callback. Tapi kalau melihat JavaScript saya 10 tahun lalu, penderitaan terbesar justru semua kelas palsu yang dibuat dengan memodifikasi SomeFunction.prototype
      Itu lalu dibungkus dalam fungsi anonim yang langsung dieksekusi dan dikembalikan sebagai objek, sehingga SomeFunction terlihat seperti kelas dan kita memanggil new SomeFunction() atau SomeFunction.actualFunction(). Karena belum ada arrow function, kami juga mengutak-atik Function.prototype sendiri untuk mengikat event ke scope lalu memakai .apply(), atau jatuh ke neraka .bind(this) tanpa akhir di setiap callback event
    • Saya mengembangkan di Firefox agar bisa memakai Firebug, sambil harus mendukung ie6, ie7, ie8 masing-masing secara terpisah
    • Ada juga masa ketika header diubah menjadi applet Flash kecil agar bisa memakai font yang diinginkan tanpa dibatasi font yang terpasang di komputer pengguna
    • Neraka callback dan ketiadaan tipe secara umum memang besar pengaruhnya
      Hari 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 .devcontainer atau 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 jadi
    Setelah 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?

    • Bahkan orang yang sudah tahu semua ini tetap butuh sehari. Sebagai developer backend dan ops, saya beberapa kali mencoba masuk ke stack seperti ini, tapi jujur dalam banyak kasus saya malah gagal
      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
    • Ada dua linter. Itu saja sudah gila. Yang lain memang lebih parah, tapi bahkan bagian terkecil dari memilih tool di ekosistem JavaScript pun penuh dengan penderitaan
    • Saya tinggal menyalin direktori starter TypeScript dan hanya mengganti nama di package.json. Memang saya cuma mengerjakan backend, tapi untuk frontend pun bukankah bisa membuat template pribadi seperti itu?
    • Bukankah npm create melakukan 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 berfungsi
    • Sepertinya cukup buat saja proyek stub berisi semua konfigurasi favorit di atas lalu unggah ke GitHub
      Saat 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 sendiri

    • Berapa persentase developer JavaScript yang tidak memakai NodeJS?
      Memang 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
    • Benar, jadi ekosistem bukan sasaran yang sah untuk kritik terhadap bahasa ya
    • Coba benar-benar menulis JavaScript sekali tanpa bundler yang memakai package.json. Sampai ECMA memasukkan package manager atau bundler ke spesifikasi resminya, package.json pada praktiknya adalah bagian dari JavaScript
    • Kalau itu sangat mengganggumu, anggap saja setiap kali seseorang bilang JavaScript, yang dimaksud sebenarnya adalah ECMAscript
    • Betul. Ini kritik terhadap ekosistem JavaScript
  • Suka 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

    • Benar. Ironisnya, karena kompromi itu, bahkan kalau developer senior yang sudah 20 tahun membuat hal-hal yang berjalan di browser dilempar ke situ, dia belum tentu siap dalam sehari
      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
    • Lalu setelah itu kamu akan merakit sesuatu secara paksa selama satu sampai tiga hari, menyesalinya selama 10 tahun ke depan, lalu menulis artikel seperti ini. Siklusnya terus berulang
    • Para junior yang aku kenal bilang, “mari bikin framework untuk menangani kompleksitas ini”
      Mereka polos tidak menyadari bahwa membuatnya butuh berbulan-bulan, dan bahwa sebagian masalahnya justru adalah kebanyakan framework, sehingga besoknya pun itu sudah ketinggalan zaman
    • Sekarang orang tidak mencari di web lagi, tapi bertanya ke ChatGPT
  • “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 ada
    Aku 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

    • Setuju. Aku sedang membuat video game, dan sejak memutuskan untuk tidak memakai dependensi sama sekali, ngoding jadi 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

    • Humor bukan berarti tidak serius
  • 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

    • Karena itu aku berusaha memakai Go untuk hampir semua hal. Mungkin bukan pilihan terbaik, tapi kerja-kerja remehnya paling sedikit
    • C itu rumit? Itu hampir satu-satunya bahasa yang bisa kusimpan di kepala terlepas dari seberapa sering kupakai. Sebagian sintaks JavaScript modern gampang menguap dari ingatan meski kupakai setiap hari
  • 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.json lebih dari 20 baris

    • Sedang melototi frontend Angular baru yang sedang dikembangkan sekarang; ada empat komponen frontend dan masing-masing punya package.json lebih dari 200 baris
      Mengucapkannya 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
    • Saya juga sama. Tapi sedikit di luar topik, tautan di profilmu diblokir oleh uBlock Origin dan mengarah ke liang kelinci situs-situs aneh. Saya belum pernah memakai hackernewsers jadi tidak tahu apakah itu perilaku normal
  • 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