FAQ tentang SmooshGate

Apa yang terjadi smoosh?!

Proposal untuk fitur bahasa JavaScript yang disebut Array.prototype.flatten ternyata tidak kompatibel dengan Web. Pengiriman fitur di Firefox Nightly menyebabkan setidaknya satu situs populer rusak. Mengingat kode yang bermasalah adalah bagian dari library MooTools yang tersebar luas, kemungkinan ada lebih banyak situs yang terpengaruh. (Meskipun MooTools tidak umum digunakan untuk situs baru pada tahun 2018, MooTools dulu sangat populer dan masih ada di banyak situs produksi.)

Penulis proposal dengan bercanda menyarankan untuk mengganti nama flatten menjadi smoosh untuk menghindari masalah kompatibilitas. Lelucon itu tidak jelas bagi semua orang, beberapa orang mulai salah meyakini bahwa nama baru telah diputuskan, dan segala sesuatunya menjadi makin cepat.

Apa yang dilakukan Array.prototype.flatten?

Array.prototype.flat, yang awalnya diusulkan sebagai Array.prototype.flatten, akan meratakan array secara rekursif hingga depth yang ditentukan, yang secara default ditetapkan ke 1.

// Flatten one level:
const array = [1, [2, [3]]];
array.flat();
// → [1, 2, [3]]

// Flatten recursively until the array contains no more nested arrays:
array.flat(Infinity);
// → [1, 2, 3]

Proposal yang sama mencakup Array.prototype.flatMap, yang mirip dengan Array.prototype.map, kecuali bahwa Array.prototype.flatMap meratakan hasilnya ke dalam array baru.

[2, 3, 4].flatMap((x) => [x, x * 2]);
// → [2, 4, 3, 6, 4, 8]

Apa yang dilakukan MooTools yang menyebabkan masalah ini?

MooTools menentukan versi Array.prototype.flatten non-standarnya sendiri:

Array.prototype.flatten = /* non-standard implementation */;

Implementasi flatten MooTools berbeda dari standar yang diusulkan. Namun, ini bukan masalahnya. Saat browser mengirimkan Array.prototype.flatten secara native, MooTools akan mengganti penerapan native. Hal ini memastikan bahwa kode yang mengandalkan perilaku MooTools berfungsi seperti yang diinginkan, terlepas dari apakah flatten native tersedia atau tidak. Sejauh ini, hasilnya bagus.

Sayangnya, hal lain kemudian terjadi. MooTools menyalin semua metode array kustomnya ke Elements.prototype (dengan Elements adalah API khusus MooTools):

for (var key in Array.prototype) {
  Elements.prototype[key] = Array.prototype[key];
}

for-in melakukan iterasi pada properti “yang dapat dihitung”, yang tidak menyertakan metode native seperti Array.prototype.sort, tetapi menyertakan properti yang ditetapkan secara rutin seperti Array.prototype.foo = whatever. Namun, dan inilah intinya — jika Anda menimpa properti yang tidak dapat di-enumerasi, misalnya Array.prototype.sort = whatever, properti tersebut tetap tidak dapat di-enumerasi.

Saat ini, Array.prototype.flatten = mooToolsFlattenImplementation membuat properti flatten yang dapat dihitung, sehingga nanti disalin ke Elements. Namun, jika browser mengirimkan flatten versi native, flatten menjadi tidak dapat dihitung, dan tidak disalin ke Elements. Kode apa pun yang mengandalkan Elements.prototype.flatten MooTools kini rusak.

Meskipun tampaknya mengubah Array.prototype.flatten native menjadi dapat dihitung akan memperbaiki masalah, tindakan ini kemungkinan akan menyebabkan lebih banyak masalah kompatibilitas. Setiap situs yang mengandalkan for-in untuk melakukan iterasi pada array (yang merupakan praktik buruk, tetapi hal ini terjadi) akan tiba-tiba mendapatkan iterasi loop tambahan untuk properti flatten.

Masalah mendasar yang lebih besar di sini adalah mengubah objek bawaan. Memperluas prototype native saat ini umumnya dianggap sebagai praktik yang buruk, karena tidak berkomponen dengan baik dengan library lain dan kode pihak ketiga. Jangan ubah objek yang bukan milik Anda.

Mengapa kita tidak mempertahankan nama yang ada dan merusak Web?

Pada tahun 1996, sebelum CSS tersebar luas, dan jauh sebelum “HTML5” menjadi hal yang umum, situs Space Jam diluncurkan. Saat ini, situs tersebut masih berfungsi dengan cara yang sama seperti 22 tahun yang lalu.

Bagaimana hal itu bisa terjadi? Apakah ada seseorang yang mengelola situs tersebut selama bertahun-tahun, dan memperbaruinya setiap kali vendor browser merilis fitur baru?

Ternyata, “jangan merusak Web” adalah prinsip desain nomor satu untuk HTML, CSS, JavaScript, dan standar lainnya yang banyak digunakan di Web. Jika fitur browser baru yang dikirimkan menyebabkan situs yang ada berhenti berfungsi, hal ini akan merugikan semua orang:

  • pengunjung situs web yang terpengaruh tiba-tiba mengalami kerusakan pengalaman pengguna;
  • pemilik situs berubah dari memiliki situs yang berfungsi dengan sempurna menjadi situs yang tidak berfungsi tanpa mengubah apa pun;
  • Vendor browser yang mengirimkan fitur baru kehilangan pangsa pasar, karena pengguna beralih browser setelah melihat "fungsi ini berfungsi di browser X";
  • jika masalah kompatibilitas diketahui, vendor browser lain menolak untuk mengirimkannya. Spesifikasi fitur tidak sesuai dengan kenyataan (“hanya karya fiksi”), yang buruk untuk proses standardisasi.

Tentu saja, jika dipikir-pikir, MooTools melakukan hal yang salah — tetapi merusak web tidak menghukum mereka, melainkan menghukum pengguna. Pengguna ini tidak tahu apa itu alat moo. Atau, kita dapat menemukan solusi lain, dan pengguna dapat terus menggunakan web. Pilihannya mudah dibuat.

Apakah itu berarti API yang buruk tidak akan pernah dihapus dari Platform Web?

Tergantung. Dalam kasus yang jarang terjadi, fitur buruk dapat dihapus dari Web. Bahkan hanya mengetahui apakah mungkin untuk menghapus fitur adalah upaya yang sangat rumit, yang memerlukan telemetri yang luas untuk mengukur berapa banyak halaman web yang perilakunya akan diubah. Namun, jika fitur tersebut tidak cukup aman, berbahaya bagi pengguna, atau jarang digunakan, hal ini dapat dilakukan.

<applet>, <keygen>, dan showModalDialog() adalah contoh API buruk yang berhasil dihapus dari Web Platform.

Mengapa kita tidak memperbaiki MooTools saja?

Melakukan patch pada MooTools agar tidak lagi memperluas objek bawaan adalah ide yang baik. Namun, hal tersebut tidak menyelesaikan masalah yang dihadapi. Meskipun MooTools akan merilis versi yang di-patch, semua situs yang ada yang menggunakannya harus diupdate agar masalah kompatibilitas hilang.

Tidak bisakah orang cukup memperbarui salinan MooTools mereka?

Dalam dunia yang sempurna, MooTools akan merilis patch, dan setiap situs yang menggunakan MooTools akan otomatis diupdate keesokan harinya. Masalahnya selesai, bukan?

Sayangnya, hal ini tidak realistis. Meskipun seseorang berhasil mengidentifikasi seluruh situs yang terpengaruh, menemukan informasi kontak untuk setiap situs, berhasil menghubungi semua pemilik situs, dan meyakinkan mereka semua untuk melakukan update (yang mungkin berarti memfaktorkan ulang seluruh codebase mereka), seluruh prosesnya akan memakan waktu bertahun-tahun.

Perlu diingat bahwa banyak situs ini sudah lama dan mungkin tidak dikelola. Meskipun pengelola masih ada, mungkin ia bukan developer web yang sangat terampil seperti Anda. Kita tidak dapat mengharapkan semua orang untuk mengubah situs mereka yang sudah berusia 8 tahun karena masalah kompatibilitas web.

Bagaimana cara kerja proses TC39?

TC39 adalah komite yang bertanggung jawab mengembangkan bahasa JavaScript melalui standar ECMAScript.

#SmooshGate membuat beberapa orang percaya bahwa “TC39 ingin mengganti nama flatten menjadi smoosh”, tetapi itu adalah lelucon yang tidak dikomunikasikan dengan baik secara eksternal. Keputusan besar seperti mengganti nama proposal tidak diambil dengan mudah, tidak diambil oleh satu orang, dan pastinya tidak diambil dalam semalam berdasarkan satu komentar GitHub.

TC39 beroperasi pada proses staging yang jelas untuk proposal fitur. Proposal ECMAScript dan perubahan besar apa pun pada proposal tersebut (termasuk penggantian nama metode) dibahas selama rapat TC39, dan perlu disetujui oleh seluruh komite sebelum menjadi resmi. Dalam kasus Array.prototype.flatten, proposal telah melalui beberapa tahap persetujuan, hingga Tahap 3, yang menunjukkan bahwa fitur tersebut siap diterapkan di browser Web. Masalah spesifikasi tambahan biasanya muncul selama penerapan. Dalam hal ini, masukan yang paling penting datang setelah mencoba mengirimkannya: fitur, dalam statusnya saat ini, merusak Web. Masalah yang sulit diprediksi seperti ini adalah salah satu alasan mengapa proses TC39 tidak hanya berakhir setelah browser mengirimkan fitur.

TC39 beroperasi berdasarkan konsensus, yang berarti komite harus menyetujui setiap perubahan baru. Meskipun smoosh adalah saran yang serius, sepertinya anggota komite akan menolaknya dan memberikan nama yang lebih umum seperti compact atau chain.

Penggantian nama dari flatten menjadi smoosh (meskipun bukan lelucon) belum pernah dibahas dalam rapat TC39. Dengan demikian, sikap resmi TC39 tentang topik ini saat ini tidak diketahui. Tidak ada satu orang pun yang dapat berbicara atas nama semua TC39 hingga konsensus tercapai pada rapat berikutnya.

Rapat TC39 umumnya dihadiri oleh orang-orang dengan latar belakang yang sangat beragam: beberapa memiliki pengalaman desain bahasa pemrograman selama bertahun-tahun, yang lain bekerja di browser atau mesin JavaScript, dan semakin banyak peserta yang hadir untuk mewakili komunitas developer JavaScript.

Bagaimana akhirnya SmooshGate diselesaikan?

Selama rapat TC39 Mei 2018, #SmooshGate resmi diselesaikan dengan mengganti nama flatten menjadi flat.

Array.prototype.flat dan Array.prototype.flatMap dikirimkan di V8 v6.9 dan Chrome 69.