Membina Alat Codemod untuk Menulis Semula Eksport Lalai
Baru-baru ini di tempat kerja, kami memutuskan untuk berhijrah ke eksport/import yang dinamakan dan menambah peraturan eslint no-default-export.
Motivasi berbunyi seperti:
Eksport lalai boleh menjadikan kod lebih sukar untuk dikekalkan, terutamanya dalam pangkalan kod yang besar. Nama yang diimport mungkin berbeza untuk entiti yang sama, menjejaskan proses membaca kod dan menulis penganalisis statik, menjadikannya lebih sukar. Sebaliknya, beralih kepada eksport dinamakan akan mengalih keluar semua kelemahan eksport lalai.
Sudah tentu, kami mempunyai pangkalan kod yang besar dan bukan tugas yang menarik untuk menggantikan ~1500 eksport lalai dan ~12000 import lalai secara manual ?
Kesukaran utama adalah mengemas kini semua fail yang dipautkan dengan pengecam baharu yang sama, dibuat untuk eksport yang dinamakan.
Saya berikan anda contoh:
// Button/Button.tsx const Button = () => {}; export default Button; // Button/index.ts export { default } from './Button.tsx'; // SomePage1.tsx import OldButton from './component/Button'; // SomePage2.tsx import TestButton from './component/Button';
Dan hasil sasaran yang saya kira akan kelihatan seperti ini:
// Button/Button.tsx export const Button = () => {}; // Button/index.ts export { Button } from './Button.tsx'; // SomePage1.tsx import { Button as OldButton } from './component/Button'; // SomePage2.tsx import { Button as TestButton } from './component/Button';
Setiap penyelesaian yang saya temui di internet hanyalah codemod untuk mengubah setiap fail secara bebas tanpa mengetahui perkara lain di luar fail itu.
Saya mula bermimpi tentang penghurai yang akan:
- selesaikan semua import dalam projek dan simpan hubungan antara fail
- kumpul maklumat tentang import/eksport lalai
- buat nama pengecam baharu untuk eksport bernama
- ganti semua entri merentas repo ?
Jadi saya mengambil cabaran baharu untuk membangunkan alat codemod yang secara automatik menulis semula eksport/import lalai kepada yang dinamakan.
Saya sudah membangunkannya! ? ? spoiler
Proses pembangunan
Fikiran pertama
Ia berlaku sejurus selepas percubaan saya sebelum ini Visualize react component tree dan idea pertama adalah untuk menggunakan semula pemalam babel dan webpack untuk lelaran melalui semua modul dan menghuraikan AST, tetapi mengapa, jika jscodeshift sudah mempunyai parser, dan jika saya menemui pengganti untuk pemalam webpack saya akan dapat menulis alat pengikat-agnostik, bagus ?
Alat
Ok, saya mempunyai jscodeshift sebagai penghurai. Tetapi untuk mencari hubungan antara semua fail bermula dari titik masuk, saya menemui pakej penyelesaian, yang membantu menyelesaikan laluan seperti nodejs asli require.resolve, tetapi ia lebih serupa dengan menyelesaikan laluan seperti bundler, anda mempunyai lebih kawalan ke atas sambungan, penyegerakan tingkah laku /async, dsb.
Kejuruteraan Proses Dua Langkah
Versi awal alat saya adalah seperti segala-galanya dalam satu skrip. Walau bagaimanapun, untuk meningkatkan fleksibiliti dan prestasi serta memudahkan proses pembangunan dengan penyahpepijatan, saya memfaktorkan semula alat kepada dua peringkat:
-
Pengumpulan Data: Fasa pertama mengumpulkan semua contoh import dan eksport lalai merentas pangkalan kod
- Saya memperkenalkan pembolehubah persekitaran, IS_GATHER_INFO, untuk mengawal fasa ini. Skrip menggunakan tekad untuk mencari setiap penggunaan eksport / import lalai
- Entri env var lain mengandungi laluan relatif ke titik masuk asas kod anda, bermula dari fail itu, semua import akan diselesaikan dan dianalisis
-
Transformasi: Setelah data dikumpul, fasa kedua menulis semula eksport lalai ke dalam eksport bernama. Menggunakan jscodeshift, saya menukar kod sumber secara selari dan mudah.
- Saya memperkenalkan pembolehubah persekitaran, IS_TRANSFORM, untuk mengawal fasa ini
Dengan membahagikan kepada dua langkah ini:
- Saya dapat mengasingkan pengumpulan data daripada transformasi, mengurangkan jumlah kod yang dilaksanakan dan menghabiskan masa semasa pembangunan dan penyahpepijatan
- Ini adalah cara yang sangat mudah untuk melihat hasil fungsi gatherInfo, menganalisisnya, menjalankan semula kod anda
- Uji transformasi tanpa berulang kali menjalankan keseluruhan saluran paip dengan data pengumpulan
- Mengumpul pembuangan data berguna jika anda perlu menjalankan alat ini untuk titik masuk yang berbeza tetapi menggunakan semula data yang dikumpul
Apabila kes mula terkumpul (seperti import dinamik, lalai dieksport semula, entiti eksport yang berbeza: pembolehubah, fungsi dan kelas serta nama isu pembolehubah yang sudah digunakan) masa itu saya meluangkan masa tambahan untuk menyediakan kes ujian. Dalam masa kira-kira 30 minit saya mempunyai persediaan ujian yang kukuh, membolehkan saya beralih kepada pembangunan dipacu ujian (TDD). Percayalah, anda berbaloi untuk meluangkan masa menggunakan TDD untuk alatan sedemikian, yang mempunyai bilangan kes yang sangat besar. Lebih jauh anda pergi, lebih banyak nilai yang anda rasa daripada kes ujian anda. Saya akan mengatakan bahawa selepas menutup separuh daripada kes jika anda tidak mempunyai ujian, ia menjadi mimpi ngeri untuk menjalankan dan nyahpepijat pada projek besar kerana setiap kali anda perlu menambah beberapa perubahan, ia mungkin memecahkan banyak kes lain.
AST:
Saya menggunakan jenis nod AST berikut:
-
ImportDefaultSpecifier untuk mencari hanya import pernyataan lalai
- import sesuatu daripada '...'
-
ExportDefaultDeclaration untuk mencari hanya eksport pernyataan lalai
- eksport sesuatu lalai;
-
ExportNamedDeclaration untuk mencari pernyataan lalai import dan eksport lalai
- eksport { sesuatu sebagai lalai } daripada '...' - eksport lalai
- eksport { lalai sebagai sesuatu } daripada '...' - import lalai
- eksport { lalai } daripada '...' - import lalai dan eksport lalai serentak
-
ImportExpression untuk mencari import dinamik dan tandakan fail itu sebagai diperlukan untuk mengekalkan eksport lalai. Sesetengah alatan seperti React.lazy berfungsi dengan eksport lalai sahaja.
- import('...')
- Selain itu, saya menyimpan maklumat tentang fail proksi, ia ialah fail yang mengimport sesuatu lalai dan mengeksport sesuatu itu sebagai lalai
- Menggunakannya untuk mencari nama baharu eksport yang dinamakan dalam mana-mana fail: fail a -> fail b -> fail c
Pertimbangan Teknikal dan Had yang Diketahui
Walaupun alat ini berfungsi, terdapat beberapa kes tepi yang masih belum dikendalikan:
ruang nama.penggunaan lalai
kod berikut tidak akan ditukar lagi:
// Button/Button.tsx const Button = () => {}; export default Button; // Button/index.ts export { default } from './Button.tsx'; // SomePage1.tsx import OldButton from './component/Button'; // SomePage2.tsx import TestButton from './component/Button';
Konflik dalam fail proksi
sumber:
// Button/Button.tsx export const Button = () => {}; // Button/index.ts export { Button } from './Button.tsx'; // SomePage1.tsx import { Button as OldButton } from './component/Button'; // SomePage2.tsx import { Button as TestButton } from './component/Button';
hasil:
import * as allConst from './const'; console.log(allConst.default);
Eksport berantakan seperti
sumber:
export { Modals as default } from './Modals'; export { Modals } from './Modals';
akan mengakibatkan logik rosak, kerana kini ia mempunyai dua eksport yang sama dengan pelaksanaan yang berbeza:
export { Modals } from './Modals'; export { Modals } from './Modals';
Dan import untuk entiti sebelumnya juga harus dibetulkan secara manual
sumber:
export class GhostDataProvider {} export default hoc()(GhostDataProvider);
hasil:
export class GhostDataProvider {} const GhostDataProviderAlias = hoc()(GhostDataProvider); export { GhostDataProviderAlias as GhostDataProvider };
Walaupun pengehadan ini, saya membetulkan baki ralat secara manual dalam 15-20 minit dan berjaya membuat projek sebenar kami. Eksport-lalai-tulis semula.
Pautan
- jscodeshift
- astexplorer
Itu sahaja, selamat datang ke komen di bawah! ?
Atas ialah kandungan terperinci Membina Alat Codemod untuk Menulis Semula Eksport Lalai. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas











Enjin JavaScript yang berbeza mempunyai kesan yang berbeza apabila menguraikan dan melaksanakan kod JavaScript, kerana prinsip pelaksanaan dan strategi pengoptimuman setiap enjin berbeza. 1. Analisis leksikal: Menukar kod sumber ke dalam unit leksikal. 2. Analisis Tatabahasa: Menjana pokok sintaks abstrak. 3. Pengoptimuman dan Penyusunan: Menjana kod mesin melalui pengkompil JIT. 4. Jalankan: Jalankan kod mesin. Enjin V8 mengoptimumkan melalui kompilasi segera dan kelas tersembunyi, Spidermonkey menggunakan sistem kesimpulan jenis, menghasilkan prestasi prestasi yang berbeza pada kod yang sama.

Python lebih sesuai untuk pemula, dengan lengkung pembelajaran yang lancar dan sintaks ringkas; JavaScript sesuai untuk pembangunan front-end, dengan lengkung pembelajaran yang curam dan sintaks yang fleksibel. 1. Sintaks Python adalah intuitif dan sesuai untuk sains data dan pembangunan back-end. 2. JavaScript adalah fleksibel dan digunakan secara meluas dalam pengaturcaraan depan dan pelayan.

Peralihan dari C/C ke JavaScript memerlukan menyesuaikan diri dengan menaip dinamik, pengumpulan sampah dan pengaturcaraan asynchronous. 1) C/C adalah bahasa yang ditaip secara statik yang memerlukan pengurusan memori manual, manakala JavaScript ditaip secara dinamik dan pengumpulan sampah diproses secara automatik. 2) C/C perlu dikumpulkan ke dalam kod mesin, manakala JavaScript adalah bahasa yang ditafsirkan. 3) JavaScript memperkenalkan konsep seperti penutupan, rantaian prototaip dan janji, yang meningkatkan keupayaan pengaturcaraan fleksibiliti dan asynchronous.

Penggunaan utama JavaScript dalam pembangunan web termasuk interaksi klien, pengesahan bentuk dan komunikasi tak segerak. 1) kemas kini kandungan dinamik dan interaksi pengguna melalui operasi DOM; 2) pengesahan pelanggan dijalankan sebelum pengguna mengemukakan data untuk meningkatkan pengalaman pengguna; 3) Komunikasi yang tidak bersesuaian dengan pelayan dicapai melalui teknologi Ajax.

Aplikasi JavaScript di dunia nyata termasuk pembangunan depan dan back-end. 1) Memaparkan aplikasi front-end dengan membina aplikasi senarai TODO, yang melibatkan operasi DOM dan pemprosesan acara. 2) Membina Restfulapi melalui Node.js dan menyatakan untuk menunjukkan aplikasi back-end.

Memahami bagaimana enjin JavaScript berfungsi secara dalaman adalah penting kepada pemaju kerana ia membantu menulis kod yang lebih cekap dan memahami kesesakan prestasi dan strategi pengoptimuman. 1) aliran kerja enjin termasuk tiga peringkat: parsing, penyusun dan pelaksanaan; 2) Semasa proses pelaksanaan, enjin akan melakukan pengoptimuman dinamik, seperti cache dalam talian dan kelas tersembunyi; 3) Amalan terbaik termasuk mengelakkan pembolehubah global, mengoptimumkan gelung, menggunakan const dan membiarkan, dan mengelakkan penggunaan penutupan yang berlebihan.

Python dan JavaScript mempunyai kelebihan dan kekurangan mereka sendiri dari segi komuniti, perpustakaan dan sumber. 1) Komuniti Python mesra dan sesuai untuk pemula, tetapi sumber pembangunan depan tidak kaya dengan JavaScript. 2) Python berkuasa dalam bidang sains data dan perpustakaan pembelajaran mesin, sementara JavaScript lebih baik dalam perpustakaan pembangunan dan kerangka pembangunan depan. 3) Kedua -duanya mempunyai sumber pembelajaran yang kaya, tetapi Python sesuai untuk memulakan dengan dokumen rasmi, sementara JavaScript lebih baik dengan MDNWebDocs. Pilihan harus berdasarkan keperluan projek dan kepentingan peribadi.

Kedua -dua pilihan Python dan JavaScript dalam persekitaran pembangunan adalah penting. 1) Persekitaran pembangunan Python termasuk Pycharm, Jupyternotebook dan Anaconda, yang sesuai untuk sains data dan prototaip cepat. 2) Persekitaran pembangunan JavaScript termasuk node.js, vscode dan webpack, yang sesuai untuk pembangunan front-end dan back-end. Memilih alat yang betul mengikut keperluan projek dapat meningkatkan kecekapan pembangunan dan kadar kejayaan projek.
