JavaScript sering disebut "bahasa paling populer", tetapi tampaknya tidak ada yang menyebut pengembangan JS sebagai "yang paling aman", dan jumlah masalah yang bersembunyi di ekosistem sangat besar. Bagaimana menyiasatinya secara efektif?
Ilya Klimov memikirkan hal ini ketika kesalahannya sangat mahal (secara harfiah) - dan akhirnya membuat presentasi tentang HolyJS. Dan karena ulasan audiens ternyata sangat bagus, kami sekarang telah menyiapkan versi teks dari laporan ini untuk Habr. Di bawah cut - baik teks dan video.
Halo semuanya. Nama saya Ilya Klimov, saya dari Kharkov, Ukraina. Saya punya perusahaan outsourcing kecil hingga sepuluh orang. Kami melakukan segalanya untuk yang uang dibayarkan ... dalam arti, kami memprogram dalam JavaScript di semua sektor. Hari ini, berbicara tentang JavaScript yang dapat diandalkan, saya ingin berbagi praktik terbaik saya di suatu tempat selama setahun terakhir, karena topik ini mulai mengganggu saya dengan sangat serius dan serius.
Mereka yang bekerja dalam outsourcing akan memahami konten slide berikut:

Semua yang akan kita bicarakan, tentu saja, tidak ada hubungannya dengan kenyataan. Seperti yang mereka katakan di South Park, semua karakter manja, dan celaka. Secara alami, tempat-tempat di mana ada dugaan pelanggaran NDA disepakati dengan perwakilan pelanggan.
Tidak ada yang memengaruhi pikiran saya tentang keandalan dan sejenisnya sebagai fondasi perusahaan saya sendiri. Ketika Anda memulai perusahaan Anda sendiri, tiba-tiba ternyata Anda bisa menjadi programmer yang sangat keren, Anda dapat memiliki orang-orang yang sangat keren, tetapi kadang-kadang hal-hal luar biasa terjadi, beberapa hal yang mustahil dan benar-benar gila.
Saya memiliki proyek pendidikan Ninja JavaScript. Terkadang saya membuat janji. Kadang-kadang saya bahkan mengikuti mereka. Saya berjanji pada tahun 2017, sebagai bagian dari proyek pendidikan, untuk merekam video tentang Kubernetes. Saya menyadari bahwa saya telah membuat janji ini dan akan menyenangkan untuk memenuhinya, 31 Desember. Dan saya duduk untuk merekam (
ini hasilnya ).
Karena saya suka merekam video yang sedekat mungkin dengan kenyataan, saya mengambil keuntungan dari contoh proyek nyata. Akibatnya, di demo cluster, saya menggunakan sesuatu yang menerima pesanan nyata dari produksi nyata dan menempatkannya di database Kubernetes terpisah di cluster demo saya.
Karena tanggal 31 Desember, sebagian dari pesanan hilang. Dihapus karena musiman: semua orang pergi minum teh. Ketika pelanggan bangun sekitar 12-13 Januari, total biaya video adalah sekitar $ 500.000. Saya belum memiliki produksi yang begitu mahal.

Contoh nomor dua: cluster Kubernetes lainnya. Infrastruktur ekosistem yang baru sebagai Kode: segala sesuatu yang dapat dijelaskan dengan kode dan konfigurasi, Kubernet berkedut secara terprogram dari cangkang JavaScript dan sebagainya. Keren, semua orang suka itu. Sedikit perubahan dalam prosedur penyebaran, dan tiba saatnya Anda perlu menggunakan cluster baru. Situasi berikut muncul:
const config = { // … mysql: process.env.MYSQL_URI || 'mysql://localhost:3306/foo' // ... }
Banyak dari Anda mungkin juga memiliki baris kode ini di konfigurasi Anda. Yaitu, kita mengambil konfigurasi dari variabel mysql atau mengambil database lokal.
Karena kesalahan ketik dalam sistem penyebaran, ternyata sistem itu lagi dikonfigurasi sebagai produksi, tetapi database MySQL menggunakan database uji - lokal, yang untuk pengujian. Kali ini lebih sedikit uang yang dihabiskan - hanya $ 300.000. Untungnya, ini bukan perusahaan saya, tetapi tempat saya bekerja sebagai konsultan yang terlibat.

Anda mungkin berpikir bahwa semua ini tidak menjadi perhatian Anda, karena saya berbicara tentang DevOps (omong-omong, saya mengagumi nama konferensi
DevOops , itu menggambarkan esensinya dengan sempurna). Tetapi saya akan memberi tahu Anda tentang situasi lain.
Ada sistem yang mengendalikan epidemi hewan di Ethiopia, yang dikembangkan di bawah naungan PBB. Ini berisi salah satu elemen antarmuka ketika mereka datang ke seseorang, dan dia secara manual memasukkan koordinat: kapan dan di mana ada wabah penyakit tertentu.
Ada wabah penyakit kaki-dan-mulut yang biasa (saya tidak kuat dalam penyakit sapi), dan terburu-buru operator tanpa sengaja menekan tombol "tambah" dua kali, meninggalkan ladang kosong. Karena kita memiliki JavaScript, dan JavaScript serta tipenya sangat bagus, bidang lintang dan bujur yang kosong dengan senang hati mengarah ke koordinat nol.
Tidak, kami tidak mengirim dokter jauh ke laut, tetapi ternyata semua ini sebelumnya dihitung dari sudut pandang pengelompokan untuk ditampilkan di peta, membuat laporan, menganalisis, dan menganalisis penempatan orang di backend. Kami mencoba untuk menyatukan poin wabah.
Akibatnya, sistem lumpuh pada siang hari, karena backend berusaha menghitung cluster dengan dimasukkannya titik ini, semua data menjadi tidak relevan, pesanan yang sama sekali tidak bertanggung jawab dari seri "drive 400 kilometer" datang ke dokter. 400 kilometer di Ethiopia adalah kesenangan yang meragukan.
Perkiraan kerugian total sekitar satu juta dolar. Dalam laporan tentang situasi ini tertulis "Kami adalah korban dari serangkaian keadaan yang tidak menguntungkan." Tetapi kita tahu bahwa intinya adalah JavaScript!

Dan contoh terakhir. Sayangnya, meskipun cerita ini sudah lama, saya masih belum bisa menyebutkan nama perusahaan. Tetapi ini adalah perusahaan yang memiliki maskapai penerbangan sendiri, hotel sendiri dan sebagainya. Dia bekerja sangat interaktif dengan bisnis, yaitu, dia memberi mereka antarmuka terpisah untuk pemesanan tiket dan sebagainya.
Sekali pada kecelakaan yang absurd, pesanan untuk memesan tiket dari New York ke Los Angeles dalam jumlah 999.999 buah tiba. Sistem perusahaan dengan senang hati membeli semua penerbangan dari perusahaannya sendiri, menemukan bahwa tidak ada cukup kursi, dan mengirim data ke sistem pemesanan internasional untuk mengkompensasi kekurangan tersebut. Sistem pemesanan internasional, melihat permintaan sekitar 950.000 tiket, dengan senang hati memutuskan maskapai ini dari sistemnya.
Karena shutdown adalah kejadian yang tidak biasa, setelah itu masalahnya diselesaikan dalam waktu tujuh menit. Namun, dalam tujuh menit ini, biaya denda yang harus dibayar hanya $ 100.000.

Untungnya, ini semua terjadi dalam lebih dari satu tahun. Tetapi kasus-kasus ini membuat saya berpikir tentang masalah keandalan dan mengajukan dua pertanyaan asli Rusia: siapa yang harus disalahkan dan apa yang harus dilakukan?
Mengapa ini terjadi: pemuda ekosistem
Jika Anda menganalisis banyak cerita, Anda akan menemukan bahwa ada lebih banyak cerita tentang masalah serupa dengan JavaScript daripada dengan bahasa pemrograman lain. Ini bukan kesan subyektif saya, tetapi hasil analisis berita yang cerdas tentang Hacker News. Di satu sisi, ini adalah sumber hipster dan subyektif, tetapi, di sisi lain, cukup sulit untuk menemukan sumber waras oleh fakap di bidang pemrograman.
Apalagi setahun yang lalu saya mengadakan kompetisi di mana saya harus menyelesaikan masalah algoritmik setiap hari. Karena saya bosan, saya menyelesaikannya dalam JavaScript menggunakan pemrograman fungsional. Saya menulis fungsi yang sepenuhnya murni, dan di Chrome saat ini, berfungsi dengan benar 1197 kali, dan 3 kali menghasilkan hasil yang berbeda. Itu hanya kesalahan kecil dalam pengoptimal TurboFan, yang baru saja masuk ke Chrome utama.
Tentu saja, itu sudah diperbaiki, tetapi Anda mengerti: ini berarti, misalnya, bahwa jika tes unit Anda lulus sekali, ini tidak berarti sama sekali bahwa mereka akan bekerja dalam sistem. Artinya, kami mengeksekusi kode sekitar 1197 kali, kemudian pengoptimal datang dan berkata: "Wow! Fitur panas! Mari kita optimalkan. " Dan dalam proses optimasi menyebabkan hasil yang salah.
Dengan kata lain, kita dapat menyebut pemuda ekosistem sebagai salah satu alasan pertama mengapa ini terjadi. JavaScript adalah industri yang cukup muda tepatnya di bidang pemrograman yang serius, dalam kasus di mana jutaan berputar, di mana biaya kesalahan diukur oleh lima hingga enam karakter.
Untuk waktu yang lama JavaScript dianggap sebagai mainan. Karena ini (bukan karena kami tidak menganggapnya serius), kami masih memiliki masalah dengan kurangnya alat.
Oleh karena itu, untuk mengatasi alasan ini, yang merupakan prinsip fundamental fundamental dari semua yang akan saya bicarakan hari ini, saya mencoba merumuskan aturan keandalan yang dapat saya terapkan di perusahaan saya atau mentransfer sebagai konsultan kepada orang lain. Seperti kata pepatah, "aturan nomor satu adalah tidak berbicara tentang keandalan." Tetapi yang lebih serius, maka ...
Aturan keandalan # 1: segala sesuatu yang dapat diotomatisasi harus diotomatisasi
Termasuk, omong-omong, dan pemeriksaan ejaan:
Teks tersembunyiAturan keandalan # 1: segala sesuatu yang dapat diotomatisasi harus diotomatisasi
Semuanya dimulai dengan hal-hal yang paling sederhana. Tampaknya semua orang telah menulis Prettier untuk waktu yang lama. Tetapi hanya pada tahun 2018, hal ini yang kita semua gunakan, baik dan suara, belajar untuk bekerja dengan git add -p ketika kita menambahkan sebagian file ke repositori git, dan kami ingin memformat kode dengan baik, misalnya, sebelum mengirimnya ke repositori utama. Utilitas realinstaged yang cukup terkenal, yang memungkinkan Anda untuk memeriksa hanya file-file yang telah diubah, memiliki masalah yang persis sama.

Terus bermain Kapten Evidence: ESLint. Saya tidak akan bertanya siapa yang menggunakannya di sini, karena tidak masuk akal bagi seluruh audiens untuk mengangkat tangan (well, saya harap begitu dan saya tidak ingin kecewa). Lebih baik angkat tangan yang memiliki aturan tertulis khusus mereka di ESLint.
Aturan semacam itu adalah salah satu cara yang sangat ampuh untuk mengotomatisasi kekacauan yang terjadi dalam proyek-proyek di mana orang menulis di tingkat junior dan sejenisnya.
Kita semua menginginkan tingkat isolasi tertentu, tetapi cepat atau lambat suatu situasi muncul: “Lihat, pembantu ini Vasya dijual di suatu tempat di direktori komponennya sangat dekat. Saya tidak akan mengambilnya secara umum, maka saya akan melakukannya. " Kata ajaibnya adalah "nanti." Ini mengarah pada fakta bahwa ketergantungan vertikal tidak mulai muncul dalam proyek (ketika elemen atas menghubungkan yang lebih rendah, yang lebih rendah tidak pernah naik di belakang yang atas), tetapi komponen A tergantung pada komponen B, yang berada di cabang yang sama sekali berbeda. Akibatnya, komponen A tidak mudah diangkut ke komponen lain.
Ngomong-ngomong, saya menyatakan rasa hormat saya kepada Alfa-Bank, mereka memiliki pustaka komponen yang ditulis dengan sangat baik dan indah tentang Bereaksi, dengan senang hati menggunakannya secara tepat dalam hal merancang kualitas kode.
Aturan ESLint dangkal, yang melacak dari mana Anda mengimpor entitas, memungkinkan Anda untuk secara signifikan meningkatkan kualitas kode dan menyimpan model mental selama peninjauan kode.
Saya sudah dari sudut pandang dunia front-end. Baru-baru ini, di wilayah Kharkov, sebuah perusahaan besar dan serius PricewaterhouseCoopers telah menyelesaikan studi, dan usia rata-rata vendor front-end adalah sekitar 24-25 tahun. Sudah sulit bagi saya untuk memikirkan semua ini, saya ingin fokus pada logika bisnis selama peninjauan permintaan tarik. Karena itu, saya senang menulis aturan ESLint agar tidak memikirkan hal-hal seperti itu.
Tampaknya Anda dapat menyesuaikan aturan yang biasa untuk ini, tetapi kenyataan biasanya lebih mengecewakan, karena ternyata beberapa penyeleksi Redux diperlukan dari komponen reaksi (sayangnya, masih hidup). Dan penyeleksi ini berada di suatu tempat dalam hierarki yang sama sekali berbeda, jadi "../../../ ..".
Atau, lebih buruk lagi, alias webpack, yang merusak sekitar 20% dari alat lain, karena tidak semua orang mengerti cara bekerja dengannya. Misalnya, Aliran tercinta saya.
Oleh karena itu, lain kali sebelum Anda ingin menggeram di junior (dan programmer memiliki hobi favorit), pikirkan apakah Anda dapat mengotomatisasi ini entah bagaimana agar tidak membuat kesalahan di masa depan. Di dunia yang ideal, tentu saja, Anda akan menulis instruksi yang tidak akan dibaca siapa pun. Berikut adalah para pembicara HolyJS - spesialis berbakat dengan pengalaman hebat, tetapi ketika diusulkan untuk menyusun instruksi untuk para pembicara pada rapat umum internal, mereka berkata "ya mereka tidak akan membacanya." Dan ini adalah orang-orang untuk mengambil contoh!
Yang terakhir dari dangkal, dan beralih ke timah. Ini adalah alat apa pun untuk menjalankan kait pra-komitmen. Kami menggunakan
husky , dan saya tidak bisa tidak memasukkan foto husky yang indah ini, tetapi Anda dapat menggunakan sesuatu yang lain.

Jika Anda berpikir bahwa ini semua sangat sederhana - seperti kata mereka, tahan bir saya, kami akan segera mengetahui bahwa semuanya lebih rumit daripada yang Anda pikirkan. Beberapa poin lagi:
Mengetik
Jika Anda tidak menulis TypeScript, Anda mungkin ingin memikirkannya. Saya tidak suka TypeScript, saya secara tradisional aliran tinggi, tetapi kita akan membicarakan ini nanti, tapi di sini dari tahap saya akan mempromosikan solusi mainstream dengan jijik.
Kenapa begitu Komite program TC39 baru-baru ini mengadakan diskusi yang sangat besar tentang ke mana bahasa umumnya digunakan. Kesimpulan yang sangat lucu, mereka datang ke: di TC39 selalu ada "angsa, kanker dan tombak" yang menyeret lidah mereka ke arah yang berbeda, tetapi ada satu hal yang semua orang inginkan dan selalu ada kinerja.
TC39 secara informal, dalam diskusi internal, mengeluarkan omelan ini: "Kami akan selalu membuat JavaScript agar tetap produktif, dan mereka yang tidak suka akan mengambil semacam bahasa yang dikompilasi ke dalam JavaScript."
TypeScript adalah alternatif yang cukup bagus untuk ekosistem dewasa. Saya tidak bisa tidak menyebutkan cinta saya untuk GraphQL. Sangat bagus, sayangnya, tidak ada yang akan membiarkannya diimplementasikan pada sejumlah besar proyek yang sudah ada di mana kita sudah harus bekerja.

Sudah ada laporan tentang GraphQL di konferensi, oleh karena itu hanya ada satu pukulan khusus untuk pertanyaan keandalan: jika Anda menggunakan, katakanlah, Express GraphQL, maka setiap kali selain resolver tertentu Anda dapat menggantung validator tertentu yang memungkinkan Anda untuk memperketat persyaratan nilai dibandingkan dengan jenis standar GraphQL.
Misalnya, saya ingin jumlah transfer antara dua perwakilan beberapa bank menjadi positif. Karena paling lambat kemarin, sembulan di Internet banking saya dengan gembira mengumumkan bahwa saya memiliki -2 pesan yang belum dibaca dari bank. Dan itu seperti bank terkemuka di negara saya.
Adapun validator ini, yang memaksakan kekakuan tambahan: menggunakannya adalah ide yang bagus dan bagus, tapi jangan gunakan seperti yang disarankan, katakanlah, oleh GraphQL. Anda menemukan diri Anda sangat terikat dengan GraphQL sebagai platform. Pada saat yang sama, validasi yang Anda lakukan diperlukan di dua tempat secara bersamaan: di frontend sebelum kami mengirim dan menerima data, dan di backend.
Saya secara teratur harus menjelaskan kepada pelanggan mengapa kami mengambil JavaScript dan bukan bahasa X sebagai backend.Selain itu, bahasa X biasanya semacam PHP, dan bukan Go yang cantik dan sejenisnya. Saya harus menjelaskan bahwa kami dapat menggunakan kembali kode seefisien mungkin, termasuk antara klien dan backend, karena fakta bahwa mereka ditulis dalam bahasa pemrograman yang sama. Sayangnya, seperti yang diperlihatkan oleh praktik, seringkali tesis ini tetap merupakan ungkapan di konferensi dan tidak menemukan perwujudan dalam kehidupan nyata.
Kontrak
Saya sudah bicara tentang pemuda ekosistem. Pemrograman kontrak telah ada selama lebih dari 25 tahun sebagai pendekatan utama. Jika Anda menulis di TypeScript, ambil io-ts, jika Anda menulis di Flow, seperti saya, ambil kontrak yang diketik, dan Anda akan mendapatkan hal yang sangat penting: kemampuan untuk menggambarkan kontrak runtime dari mana untuk mendapatkan tipe statis.

Tidak ada yang lebih buruk bagi seorang programmer daripada memiliki lebih dari satu sumber kebenaran. Saya tahu orang-orang yang kehilangan jumlah lima digit dalam dolar hanya karena tipenya dijelaskan dalam bahasa dengan pengetikan statis (mereka menggunakan TypeScript - yah, tentu saja, ini hanya kebetulan) dan tipe runtime (sepertinya menggunakan
tcomb ) sedikit berbeda.
Oleh karena itu, kesalahan tidak tertangkap dalam waktu kompilasi, hanya karena mengapa memeriksanya? Tidak ada tes unit untuk itu, karena kami diperiksa oleh pengetik statis. Tidak masuk akal untuk menguji hal-hal yang telah diverifikasi oleh lapisan di bawah ini, semua orang mengingat hierarki pengujian.
Karena fakta bahwa sinkronisasi antara kedua kontrak ini rusak dari waktu ke waktu, suatu hari transfer yang salah dilakukan ke alamat yang pergi ke alamat yang salah. Karena itu adalah cryptocurrency, tidak mungkin untuk memutar kembali transaksi sedikit lebih dari pada prinsipnya. Tidak ada yang akan memotong udara demi Anda lagi. Oleh karena itu, kontrak dan interaksi dalam pemrograman kontrak adalah hal pertama yang harus Anda mulai lakukan besok.
Mengapa ini terjadi: isolasi
Masalah selanjutnya adalah isolasi. Ini beragam dan beragam. Ketika saya bekerja di sebuah perusahaan perjalanan hotel dan udara, mereka memiliki aplikasi pada Angular 1. Itu sudah lama sekali, jadi itu bisa dimaafkan. Tim yang terdiri dari 80 orang bekerja pada aplikasi ini. Semuanya tercakup dalam tes. semuanya baik-baik saja sampai suatu hari saya melakukan fitur saya, tidak membekukannya, dan menemukan bahwa saya telah merusak, selama pengujian, tempat yang benar-benar luar biasa pada sistem yang bahkan tidak saya sentuh.
Ternyata saya punya masalah dengan kreativitas. Ternyata saya tidak sengaja memanggil layanan persis sama dengan layanan lain yang ada di sistem. Karena itu adalah Angular 1, dan sistem layanan di sana tidak diketik dengan ketat, tetapi pengetikan yang ketat diketik, Angular dengan tenang mulai menyelinap layanan saya ke tempat yang sama sekali berbeda dan, ironisnya, beberapa metode dalam penamaan bertepatan.
Ini, tentu saja, bukan kebetulan: Anda mengerti bahwa jika dua layanan diberi nama yang sama, mereka kemungkinan akan melakukan hal yang sama, plus atau minus. Itu adalah layanan yang berkaitan dengan menghitung diskon. Hanya satu modul yang sibuk menghitung diskon untuk klien korporat, dan modul kedua dengan nama saya terhubung dengan menghitung diskon pada saham.
Jelas, ketika aplikasi digergaji oleh 80 orang, ini berarti besar. Pemecahan kode diimplementasikan dalam aplikasi, dan ini berarti bahwa urutan menghubungkan modul secara langsung tergantung pada perjalanan pengguna di situs. Untuk membuatnya lebih menarik, itu terjadi bahwa tidak ada satu tes end-to-end yang menguji perilaku dan bagian pengguna melalui situs, yaitu, skenario bisnis tertentu, menangkap kesalahan ini. Karena sepertinya tidak ada yang perlu menghubungi kedua modul diskon pada saat yang sama. Benar, ini sepenuhnya melumpuhkan pekerjaan admin situs, tetapi dengan siapa itu tidak terjadi.
Masalah isolasi diilustrasikan dengan sangat baik oleh logo salah satu proyek yang sebagian menyelesaikan masalah ini. Ini Lerna.

Lerna adalah alat yang sangat baik untuk mengelola beberapa paket npm di repositori. Ketika Anda memiliki palu di tangan Anda, semuanya menjadi curiga seperti paku. Ketika Anda memiliki sistem seperti unix dengan filosofi yang tepat, semuanya menjadi mencurigakan seperti file. Semua orang tahu bahwa pada sistem unix, semuanya adalah file. Ada sistem di mana ia dibawa ke tingkat tertinggi (saya hampir mengatakan "ke titik absurditas"), seperti
Rencana 9 .
Saya tahu organisasi yang, setelah memastikan keandalan aplikasi raksasa, telah datang dengan satu ide sederhana: semuanya adalah paket.

Ketika Anda mengambil beberapa elemen fungsi, baik itu komponen atau sesuatu yang lain, dalam paket terpisah, Anda secara otomatis menyediakan lapisan isolasi. Hanya karena Anda biasanya tidak dapat menjangkau yang lain dari satu paket. Dan juga karena sistem untuk bekerja dengan paket-paket yang dikumpulkan dalam mono-repositori melalui npm-link atau Yarn Workspaces sangat mengerikan dan tidak dapat diprediksi dalam hal bagaimana hal itu diatur secara internal sehingga Anda bahkan tidak dapat menggunakan peretasan dan menghubungkan beberapa jenis File melalui "node_modules something", hanya karena orang yang berbeda memiliki semuanya masuk ke struktur yang berbeda. Ini terutama tergantung pada versi Benang. Di sana, di salah satu versi, mereka diam-diam sepenuhnya mengubah mekanisme bagaimana Ruang Kerja Benang mengatur bekerja dengan paket.
Contoh kedua isolasi untuk menunjukkan bahwa masalahnya multifaset adalah paket yang saya coba gunakan di mana-mana sekarang - ini
cls-doyan . Anda mungkin mengetahui paket lain yang mengimplementasikan hal yang sama - ini adalah
kelanjutan-penyimpanan-lokal . Ini memecahkan masalah yang sangat penting yang, misalnya, tidak dihadapi, misalnya oleh pengembang dalam PHP.
Ini tentang mengisolasi setiap permintaan spesifik. Dalam PHP, kami memiliki, rata-rata, di rumah sakit, semua permintaan terisolasi, berinteraksi di antara mereka hanya jika Anda tidak menggunakan penyimpangan seperti Memori Bersama, kami tidak bisa, semuanya baik-baik saja, damai, indah. Intinya, cls-hooked menambahkan hal yang sama, memungkinkan Anda untuk membuat konteks eksekusi, memasukkan variabel lokal di dalamnya, dan kemudian, yang paling penting, secara otomatis menghancurkan konteks ini sehingga mereka tidak terus memakan ingatan Anda.
cls-hooked async_hooks, node.js , , . , .
, , node-.
#2: «»
, , . , JavaScript — , . grep-.
Apa ini vim. , - Language Server, - — , , grep. , , . grep- , grep. , , .
Sequelize . ORM . user.getProjects(). , getProjects? .

, Sequelize, , hasMany, belongsToMany. , , , . , .
code review, , . . — , .
, : «merge request 20 — 30 , merge request 5000 — looks good to me». , .
JavaScript Ninja , , , junior-, . « react redux», 8000 , 10 000 » , , « ». , , « », , merge request .
, , merge request , , Linux. , , -. , git. , . , , . .
- . . - , , - .
, . Microsoft Surface Linux, . , , . - .
:

« », « ». , React. React, Fiber — .
, Fiber ( OCaml) JavaScript, . , . , — , proposal, JavaScript. Scheduler — proposal stage 0.
, React , - . , : , DOM. — . , .

— Vue.js. Vue? , . Vue, , , .
Vue React. , Vue, , React.
. Vue , state, , state , . , . Vue .
. , , Web Components c , , . : , pop-up, , , - . — .
Vue — scoped slots. , - . scoped slot — , . . React Render Proper: , . Vue , -.
-, Vue . Vue : , child-, , scoped slots, forceUpdate. , child . .
React . , , shouldComponentUpdate(), . Vue , , , , . . Vue. , - .

—
Jest . Facebook. JavaScript: , , . . , .
, ECMAScript 2015 . , if, require. Require , . , , , . Jest Babel Require .
NGS- Node, proposal, . JavaScript : Require, . . , Jest c NGS- , , . , .
, , - . , Inversion of Control - Dependency Injection-.
IoC/DI
, , . Angular IoC/DI. React … , , React Vue?
dan.church , evan.church .
, , React Dependency Injection, - . Vue inject provide. .
, , . ,
NestJS .
InversifyJS . TypeScript, , , JavaScript. , .

Typescript, Inversify. , :
inject (TYPES.Weapon) katana: Weapon. , , TYPES.Weapon Weapon? — .
, , , TypeScript ( Flow ) , inject dependency injection runtime, .
« »? Weapon , , TypeScript , . TypeScript , first-class citizen JavaScript, . , , runtime , katana Weapon. .
- C++, , , RTTI: run-time type information, , . C# Java reflection, . TypeScript, « », , RTTI.
. . Vue Vue 3 TypeScript, , Vue TypeScript , Microsoft: « , TypeScript, ?» , Vue, : props, this. , props , this, . TypeScript , . .
Microsoft , : Vue , Angular, . , TypeScript. React, , .
, . , Dart, mirrors, , Flutter. mirrors, , , .
Inversify, Babel-, , , , runtime-, , .
: . . , , , . , V8 .
V8 , . , , V8, , , . , V8 , TypeScript.
. , , .
#3: «» , «»
«» «» , , «» — , . , Vue, . - , - props' .
. typed-css-modules? : CSS, CSS Modules, .
typed-css-modules , , css-, .
12 , CSS- , . 11 12 undefined, CSS- , , , , undefined, .

Yeoman , , , . , , . Angular CLI, Blueprints (, Angular, GDG SPB , , ).

Anguar , , . .
, «» , «» — , . , «» — . , , , , , , .
, — . junior', , , , . , , React- .
, , , - ESLInt, - , , .
, , . ,
NestJS Sails.js .

, , , , , - -. Sails ORM, . Waterline — , . , Sails.js . blueprint , . , , .

Nest, — , . Dependency Injection, , middleweight .
. , , , , , : « - ?»
Angular, — , , dependency injection, , .
- Vue (, ), , Vue . Vue, - , — Nest. , , , , TypeScript.

:
, JavaScript. , , , , , .
— , , , , , : - . - , — .

Grafana, , — . , - , . speech recognition API Microsoft, , , 20 . , , , -.

: CI/CD. GitLab, , . GitLab, , JavaScript-friendly environment , , .
. , , … , -.

Blue/Green deployment: - , , . , , !
- JavaScript , , . , , , JavaScript GitHub. — , , , .
- JavaScript , ( , ). « , ». , . DI , « ?»
- , . TypeScript, Flow, Rizen — , runtime exception, , .
, — -, .
HolyJS, : HolyJS 24-25 . — , ( MobX) ( Chrome DevTools). — .