Catatan Editor
Pada
artikel terakhir, kami berbicara tentang rilis panel kontrol Voximplant, tidak lupa menyebutkan IDE yang diperbarui. Hari ini kami menyediakan
longride terpisah untuk alat ini - kolega kami
Geloosa dengan hati-hati menjelaskan proses pemilihan teknologi dan penerapannya dengan tab, lengkapi-otomatis, dan gaya khusus. Duduk lebih nyaman, sisihkan sisa urusan Anda dan pergi ke mengatasi, di mana nyali Monaco menunggu yang penasaran - jangan terpeleset, ada banyak dari mereka :) Selamat membaca.
Pustaka mana yang akan dipilih untuk editor kode?
Npm menghasilkan 400+ hasil untuk editor kode. Untuk sebagian besar, ini adalah pembungkus UI dari beberapa lib paling populer yang dibuat untuk kerangka kerja atau proyek tertentu, plug-in untuk lib yang sama atau garpu mereka dengan modifikasi untuk diri mereka sendiri, serta tidak untuk mengedit kode di browser, mereka hanya masuk ke output dengan kata kunci. Jadi, untungnya, pilihannya jauh lebih sempit. Beberapa
lib lagi - ala
CodeFlask , ringan, tetapi tidak terlalu fungsional, dirancang untuk cuplikan kecil dan contoh interaktif, tetapi tidak untuk IDE web lengkap dengan fungsi yang biasa kita gunakan dalam editor desktop.
Pada akhirnya, kami memiliki 3 perpustakaan untuk dipilih:
Ace ,
CodeMirror dan
Editor Monaco . Yang paling awal, CodeMirror, adalah inisiatif pribadi oleh Berliner
Marijn Haverbeke , yang membutuhkan editor kode latihan dalam tutorial online-nya,
Eloquent JavaScript . Versi pertama editor dirilis pada 2007. Pada tahun 2010, versi pertama Ace dipresentasikan di JSConf.eu di Berlin yang sama, yang kemudian dikembangkan oleh Ajax.org untuk cloud-nya IDE Cloud9 (pada kenyataannya, Ace adalah singkatan dari Ajax.org Cloud9 Editor). Pada 2016, Cloud9 dibeli oleh Amazon dan sekarang menjadi bagian dari AWS. Yang terbaru, Monaco Editor, adalah komponen VS Code dan diterbitkan oleh Microsoft pada akhir 2015.
Setiap editor memiliki kelebihan dan kekurangan masing-masing, masing-masing digunakan di lebih dari satu proyek besar. Misalnya, CodeMirror digunakan di alat pengembang Chrome dan Firefox, sebuah IDE di Bitbucket, di RunKit di npm; Ace - di Codecademy, Khan Academy, MODX; Monako - di GitLab IDE dan CodeSandbox. Berikut ini adalah bagan perbandingan yang dapat membantu Anda memilih perpustakaan yang paling cocok untuk proyek Anda.
| Perpustakaan |
| Ace | CodeMirror | Monako |
Pengembang | Cloud9 IDE (Ajax.org), sekarang bagian dari AmazonMozilla | Marijn haverbeke | Microsoft |
Dukungan browser | Firefox ^ 3.5 Chrome Safari ^ 4.0 IE ^ 8.0 Opera ^ 11.5 | Firefox ^ 3.0 Chrome Safari ^ 5.2 IE ^ 8.0 Opera ^ 9.2 | Firefox ^ 4.0 Chrome Safari (v -?) IE ^ 11.0 Opera ^ 15.0 |
Dukungan bahasa (penyorotan sintaksis) | > 120 | > 100 | > 20 |
Jumlah karakter dalam versi terbaru aktif cndjs.com | 366 608 (v1.4.3) | 394.269 (v5.44.0) | 2.064.949 (v0.16.2) |
Berat versi terbaru, gzip | 2.147 KB | 1.411 KB | 10.898 KB |
Rendering | Dom | Dom | DOM dan sebagian <canvas> (untuk scrolling dan minimap) |
Dokumentasi | 7 dari 10: tidak ada pencarian, tidak selalu jelas Metode yang kembali, ada keraguan dalam kelengkapan dan relevansi (tidak semua tautan berfungsi di dok) | 6 dari 10: digabung dengan buku petunjuk, cari dengan Ctrl + F, ada keraguan tentang kelengkapan | 9 dari 10: cantik, dengan pencarian dan referensi silang -1 poin karena tidak ada penjelasan ke beberapa bendera yang aplikasi tidak cukup jelas dari namanya |
Demo mulai cepat | Bagaimana-ke - teks dokumen dengan contoh kode, secara terpisah ada demo dengan contoh kode (Benar, mereka tersebar di halaman yang berbeda, tidak semua orang berfungsi dan mereka paling mudah dicari melalui Google), ada demo di mana Anda dapat menyentuh berbagai fitur, tetapi diusulkan untuk mengelolanya melalui kontrol UI, yaitu, maka kita masih harus mencari metode secara terpisah untuk menghubungkan mereka | Bagaimana-benar-benar miskin pada dasarnya semuanya tersebar di github dan stackoverflow, tetapi ada demo fitur dengan contoh kode untuk implementasi mereka | Dikombinasikan dalam format taman bermain: kode dengan komentar dan sejumlah demo, Anda bisa segera coba dan evaluasi banyak kemungkinan |
Kegiatan komunitas | Rata-rata | Tinggi | Rata-rata |
Aktivitas Pengembang | Rata-rata | Rata-rata | Tinggi |
Tidak masuk akal untuk membandingkan pustaka berdasarkan ukuran, karena itu semua tergantung pada apa dan bagaimana menghubungkan untuk proyek tertentu: memuat file yang sudah selesai dengan salah satu build (yang juga bervariasi) atau menjalankan paket npm melalui semacam kolektor. Dan yang paling penting adalah seberapa banyak editor yang digunakan: apakah semua gaya dan tema dimuat, berapa banyak dan apa add-on dan plug-in yang digunakan. Misalnya, di CodeMirror, sebagian besar fungsi yang bekerja di Monaco dan Ace di luar kotak hanya tersedia dengan add-on. Tabel menunjukkan jumlah karakter dalam versi terbaru pada CDN dan berat file terkompresi mereka untuk ide umum tentang pesanan apa yang terlibat.
Semua perpustakaan memiliki sekumpulan fitur dasar yang kira-kira sama: autoformatting kode, garis lipat, potong / salin / tempel, tombol pintas, kemampuan untuk menambahkan sintaks baru untuk penyorotan dan pemesanan, pemeriksaan sintaks (dalam CodeMirror hanya melalui add-ons, di Ace sejauh ini hanya untuk JavaScript / CoffeeScript / CSS / XQuery), tooltips dan pelengkapan otomatis (dalam CodeMirror - melalui add-ons), pencarian lanjutan dengan kode (dalam CodeMirror - melalui add-ons), metode untuk menerapkan tab dan mode-split, mode diff dan alat gabungan (dalam CodeMirror - Baik dengan plus dan minus dalam satu jendela, atau dua panel melalui addon, Ace - Lieb terpisah). Karena usianya, banyak add-on telah ditulis untuk CodeMirror, tetapi jumlah mereka akan memengaruhi berat dan kecepatan editor. Monako dapat melakukan banyak hal di luar kotak, dan, menurut pendapat saya, lebih baik dan dalam volume yang lebih besar daripada Ace dan CodeMirror.
Kami tinggal di Monako karena beberapa alasan:
- Alat paling berkembang yang kami anggap penting untuk proyek kami:
- IntelliSense - kiat dan pelengkapan otomatis;
- navigasi kode pintar dalam menu konteks dan melalui minimap;
- mode diff dua-panel keluar dari kotak.
- Ditulis dalam TypeScript. Panel kontrol kami ditulis dalam skrip Vue +, sehingga dukungan TS penting. Omong-omong, Ace baru-baru ini juga mendukung TS, tetapi pada awalnya ditulis dalam JS. Untuk CodeMirror, ada beberapa tipe di DefinitelyTyped .
- Ini paling aktif dikembangkan di dalamnya (mungkin karena dirilis belum lama ini), bug diperbaiki lebih cepat dan permintaan kolam diperjuangkan. Sebagai perbandingan, dengan CodeMirror kami memiliki pengalaman yang menyedihkan, ketika bug tidak diperbaiki selama bertahun-tahun dan kami menaruh kruk di atas kruk dan mengendarai kruk.
- Dokumentasi hasil-otomatis yang nyaman (yang memberikan harapan untuk kelengkapannya) dengan referensi silang antara antarmuka dan metode.
- Menurut selera kami, UI terindah (mungkin juga terkait dengan waktu pembuatan) dan API ringkas.
- Setelah bertanya kepada teman-teman pengembang editor mana yang paling menyebabkan sakit kepala, Ace dan CodeMirror adalah pemimpinnya.
Secara terpisah, harus dikatakan tentang kecepatan kerja. Penguraian mahal dilakukan dalam utas pekerja paralel. Plus, semua perhitungan dibatasi oleh ukuran viewport (semua jenis, warna, rendering dihitung hanya untuk garis-garis yang terlihat). Itu mulai mengerem hanya jika kode berisi 100.000 baris - prompt dapat dihitung selama beberapa detik. Ace, yang juga menggunakan pekerja untuk komputasi berat, ternyata lebih cepat: dalam kode dengan panjang yang sama, prompt muncul hampir secara instan, dan dengan cepat mengatasi 200.000 baris (di situs web resmi dinyatakan bahwa bahkan 4 juta baris seharusnya tidak menjadi masalah, meskipun sekrup dipercepat, input mulai melambat dan konfirmasi menghilang setelah 1 juta). CodeMirror, di mana tidak ada perhitungan paralel, hampir tidak dapat menarik volume seperti itu: ia dapat berkedip teks dan penyorotan sintaksis. Karena 100.000 baris dalam file jarang terjadi di dunia nyata, kami menutup mata terhadap hal ini. Bahkan dengan 40-50 ribu baris Monako melakukan pekerjaan yang sangat baik.
Menghubungkan Monako dan menggunakan fitur-fitur dasar (misalnya, integrasi dengan Vue)
Koneksi
Di sini saya akan memberikan contoh kode dari komponen vue dan menggunakan terminologi yang sesuai. Tapi semua ini dengan mudah dipindahkan ke kerangka kerja lain atau JS murni.
Kode sumber Monaco dapat diunduh di situs web resmi dan dimasukkan ke dalam proyek Anda, Anda dapat mengambilnya dari CDN, Anda dapat terhubung ke proyek melalui npm. Saya akan berbicara tentang opsi ketiga dan membangun menggunakan webpack.
Kami menempatkan monaco-editor dan plug-in untuk perakitan:
npm i -S monaco-editor npm i -D monaco-editor-webpack-plugin
Di konfigurasi webpack, tambahkan:
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin'); module.exports = {
Jika Anda menggunakan Vue dan vue-cli-service untuk membangun, tambahkan ke vue.config.js:
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin'); module.exports = {
Jika Anda tidak memerlukan semua bahasa dan fitur Monaco, untuk mengurangi ukuran bundel, Anda dapat mentransfer objek dengan pengaturan ke
MonacoWebpackPlugin
:
new MonacoWebpackPlugin({ output: '',
Daftar lengkap fitur dan bahasa untuk plugin ada di
sini .
Buat dan sesuaikan editor
Kami mengimpor
editor
dan memanggil
editor.create(el: HTMLElement, config?: IEditorConstructionOptions)
, melewati elemen DOM di mana kami ingin membuat editor sebagai argumen pertama.
Dalam komponen editor:
<template> <div ref='editor' class='editor'></div> </template> <script> import {editor} from 'monaco-editor'; import {Component, Prop, Vue} from 'vue-property-decorator'; @Component() export default class Monaco extends Vue { private editor = null; mounted() { this.editor = editor.create(this.$refs.editor); } } </script> <style> .editor { margin: auto; width: 60vw; height: 200px; } </style>
Wadah untuk editor harus mengatur ketinggian agar tidak menjadi nol. Jika Anda membuat editor dalam div kosong (dengan tinggi nol - K.O Anda), Monako akan menulis ketinggian yang sama dengan gaya inline di jendela editor.
Argumen opsional kedua untuk
editor.create
adalah konfigurasi editor. Ada lebih dari seratus opsi di dalamnya, deskripsi lengkap antarmuka
IEditorConstructionOptions ada dalam dokumentasi.
Sebagai contoh, kami akan mengatur bahasa, tema dan teks awal dan memungkinkan pembungkus baris (secara default tidak ada pembungkus):
const config = { value: `function hello() { alert('Hello world!'); }`, language: 'javascript', theme: 'vs-dark', wordWrap: 'on' }; this.editor = editor.create(this.$refs.editor, config);
Fungsi
editor.create
mengembalikan objek dengan antarmuka
IStandaloneCodeEditor . Melalui itu, Anda sekarang dapat mengontrol semua yang terjadi di editor, termasuk mengubah pengaturan awal:
Sekarang untuk rasa sakit:
updateOptions
menerima objek dengan antarmuka
IEditorOptions , bukan IEditorConstructionOptions. Mereka sedikit berbeda: IEditorConstructionOptions lebih luas, termasuk properti instance editor ini dan beberapa yang global. Properti
updateOptions
diubah melalui
updateOptions
, global - melalui metode
editor
global. Dan karenanya, mereka yang berubah secara global berubah untuk semua hal. Di antara opsi-opsi ini adalah
theme
. Buat 2 instance dengan tema yang berbeda; y dari keduanya akan menjadi yang diberikan dalam yang terakhir (gelap di sini). Metode global
editor.setTheme('vs')
juga akan mengubah topik pembicaraan untuk keduanya. Ini bahkan akan memengaruhi jendela-jendela yang ada di halaman lain SPA Anda. Ada beberapa tempat seperti itu, tetapi Anda harus mengikuti mereka.
<template> <div ref='editor1' class='editor'></div> <div ref='editor2' class='editor'></div> </template> <script> </script>
Hapus Editor
Saat Anda menghancurkan jendela Monako, Anda harus memanggil metode
dispose
, jika tidak semua pendengar tidak akan dihapus dan jendela yang dibuat setelah ini mungkin tidak berfungsi dengan benar, bereaksi terhadap beberapa peristiwa beberapa kali:
beforeDestroy() { this.editor && this.editor.dispose(); }
Tab
Tab yang terbuka di editor file menggunakan jendela Monaco yang sama. Untuk beralih di antara mereka, metode IStandaloneCodeEditor digunakan:
getModel
untuk menyimpan dan
setModel
untuk memperbarui model editor. Model menyimpan teks, posisi kursor, riwayat tindakan untuk undo-redo. Untuk membuat model file baru, metode
editor.createModel(text: string, language: string)
digunakan. Jika file kosong, Anda tidak dapat membuat model dan meneruskan
null
ke
setModel
:
Lihat kode <template> <div class='tabs'> <div class='tab' v-for="tab in tabs" :key'tab.id' @click='() => switchTab(tab.id)'> {{tab.name}} </div> </div> <div ref='editor' class='editor'></div> </template> <script> import {editor} from 'monaco-editor'; import {Component, Prop, Vue} from 'vue-property-decorator'; @Component() export default class Monaco extends Vue { private editor = null; private tabs: [ {id: 1, name: 'tab 1', text: 'const tab = 1;', model: null, active: true}, {id: 2, name: 'tab 2', text: 'const tab = 2;', model: null, active: false} ]; mounted() { this.editor = editor.create(this.$refs.editor); } private switchTab(id) { const activeTab = this.tabs.find(tab => tab.id === id); if (!activeTab.active) { </script>
Mode Diff
Untuk mode diff, Anda perlu menggunakan metode
editor
lain saat membuat jendela editor -
createDiffEditor
:
<template> <div ref='diffEditor' class='editor'></div> </template> // ... mounted() { this.diffEditor = editor.createDiffEditor(this.$refs.diffEditor, config); } // ...
Dibutuhkan parameter yang sama dengan
editor.create
, tetapi konfigurasi harus memiliki antarmuka
IDiffEditorConstructionOptions , yang sedikit berbeda dari konfigurasi editor biasa, khususnya, tidak memiliki
value
. Teks untuk perbandingan ditetapkan setelah membuat
IStandaloneDiffEditor yang dikembalikan melalui
setModel :
this.diffEditor.setModel({ original: editor.createModel('const a = 1;', 'javascript'), modified: editor.createModel('const a = 2;', 'javascript') });
Menu konteks, palet perintah dan tombol pintas
Monaco menggunakan sendiri, non-browser, menu konteks, di mana ada navigasi yang cerdas, multi-kursor untuk mengubah semua kejadian, dan palet perintah seperti dalam VS Code (Command palette) dengan sekelompok perintah yang berguna dan cara pintas yang mempercepat penulisan kode:
Menu konteks Monaco
Palet perintah Monaco
Menu konteks diperluas melalui metode
addAction
(ada di
IStandaloneCodeEditor
dan
IStandaloneDiffEditor
), yang menerima objek
IActionDescriptor :
Untuk hanya mengikat pintasan ke tindakan tanpa menunjukkannya di menu konteks, metode yang sama digunakan, hanya
contextMenuGroupId
tindakan tidak ditentukan:
Palet perintah akan mencakup semua tindakan yang ditambahkan.
Kiat dan lengkapi otomatis
Untuk tujuan ini, Monako menggunakan
IntelliSense , yang keren. Anda dapat membaca dan melihat pada tangkapan layar tautan berapa banyak informasi berguna yang dapat dia perlihatkan. Jika bahasa Anda belum memiliki pelengkapan otomatis, Anda dapat menambahkannya melalui
registerCompletionItemProvider . Dan untuk JS dan TS, sudah ada metode
addExtraLib
yang memungkinkan Anda memuat definisi TypeScript untuk tooltips dan pelengkapan otomatis:
Di parameter pertama, baris melewati definisi, di kedua, opsional, nama lib.
Bahasa dan Tema Kustom
Monako memiliki modul
Monarch untuk menentukan sintaks bahasanya. Sintaksnya diuraikan cukup standar: korespondensi antara pelanggan tetap dan token yang merupakan karakteristik untuk bahasa ini ditetapkan.
Anda juga dapat membuat tema untuk token Anda - sebuah objek dengan antarmuka
IStandaloneThemeData - dan menginstalnya di
editor
global:
Sekarang teks dalam bahasa yang dijelaskan akan terlihat seperti ini:
Anda dapat menerapkan fitur ini, selama Anda memiliki imajinasi yang cukup. Misalnya, kami membuat penampil log panggilan di panel kami untuk pengembang. Log seringkali panjang dan tidak dapat dipahami, tetapi ketika mereka ditampilkan dengan penyorotan sintaks, pencarian cerdas, pelipatan / perluasan jalur, perintah yang diperlukan (misalnya, parett Prettify), menyorot semua saluran panggilan dengan id atau menerjemahkan waktu dalam log ke zona waktu yang berbeda, kemudian menggali menjadi lebih mudah di dalamnya (tangkapan layar dapat diklik):
Kesimpulan
Singkatnya, saya akan mengatakan bahwa Monaco adalah api. Setelah berbulan-bulan bekerja dengannya, saya memiliki kenangan yang sangat menyenangkan. Jika Anda memilih editor untuk kode, pastikan untuk pergi ke
Playground -nya dan bermain-main dengan kode, lihat apa lagi yang bisa dilakukan. Mungkin inilah yang Anda cari.