Artikel ini dikaji semula oleh Vildan Softic. Terima kasih kepada semua pengulas rakan sebaya SitePoint untuk membuat kandungan SitePoint yang terbaik boleh!
Atom adalah moden, kepada editor teras. Ini hebat, tetapi bagi pemaju yang tidak fasih dalam Coffeescript, sukar untuk mengikuti dokumentasi. Memahami ekosistem atom boleh menjadi mengelirukan. Mari kita melalui semua aspek bagaimana menulis pakej atom dalam kerja JavaScript.Takeaways Key
Babel adalah pengkompil sumber-sumber; Menghidupkan kod ECMAScript 2015 (dahulunya dikenali sebagai ES6) ke dalam kod ECMAScript 5. Oleh kerana persekitaran adalah kromium, sudah ada banyak ciri ES2015 yang disokong. Tetapi bukannya sentiasa mencari yang dilaksanakan, saya cadangkan menggunakan Babel untuk memindahkan kod anda. Dalam pelepasan kemudian - apabila ES2015 lebih baik disokong dalam kromium - anda boleh menyahaktifkan Babel sekali lagi dan menyimpan pangkalan kod anda (hampir) tidak disentuh.
Ia membantu melihat pakej atom sebagai modul NPM. Anda mempunyai akses yang sama ke API sebagai alat yang berjalan di Node.js. Oleh itu, mungkin untuk menambah sebarang kebergantungan NPM yang diperlukan. Pakej.json juga diperlukan, mengandungi semua data meta untuk projek anda. Fail asas mestilah seperti berikut:
<span>{ </span> <span>"name": "your-package", </span> <span>"main": "./lib/main", </span> <span>"version": "0.1.0", </span> <span>"description": "A short description of your package", </span> <span>"keywords": [ </span> <span>"awesome" </span> <span>], </span> <span>"repository": "https://github.com/<your-name>/<package>", </span> <span>"license": "MIT", </span> <span>"engines": { </span> <span>"atom": ">=1.0.0 <2.0.0" </span> <span>}, </span> <span>"dependencies": { </span> <span>} </span><span>} </span>
Kekunci penting adalah utama - menentukan titik masuk utama pakej anda (lalai ke index.js/index.coffee) - dan enjin - memberitahu atom di mana versi pakej anda berjalan. Terdapat juga satu set kekunci pilihan yang tersedia, didokumenkan dalam dokumentasi pakej "WordCount" (bungkusan.json) .
Semua kod pakej anda tergolong dalam direktori peringkat atas lib/. Saya cadangkan mempunyai titik masuk anda dalam folder ini juga, kerana ia menjadikan struktur bersih dan menjadikannya lebih mudah untuk mengimbas projek.
Fail utama anda mestilah objek tunggal yang mengekalkan kitaran hayat keseluruhan pakej anda. Walaupun pakej anda hanya terdiri daripada satu pandangan, semuanya akan diuruskan dari objek ini. Titik entri anda memerlukan satu kaedah mengaktifkan (), tetapi juga harus mempunyai pilihan dinyahaktifkan () dan bersiri ().
<span>// lib/main.js </span><span>'use babel'; </span> <span>// This is your main singleton. </span><span>// The whole state of your package will be stored and managed here. </span><span>const YourPackage = { </span> <span>activate (state) { </span> <span>// Activates and restores the previous session of your package. </span> <span>}, </span> <span>deactivate () { </span> <span>// When the user or Atom itself kills a window, this method is called. </span> <span>}, </span> <span>serialize () { </span> <span>// To save the current package's state, this method should return </span> <span>// an object containing all required data. </span> <span>} </span><span>}; </span> <span>export default YourPackage; </span>
Fungsi Aktifkan () adalah satu -satunya kaedah yang diperlukan. Inisiasi semua modul, pandangan atau pembantu anda di sini. Ia diluluskan objek, yang mengandungi keadaan bersiri sebelumnya pakej anda. Jika anda tidak bersiri apa -apa dalam pakej anda, ia akan menjadi objek kosong. Maksudnya, ia terpulang kepada anda dan seni bina pakej anda mengenai apa yang hendak bersiri.
kaedah menyahaktifkan () adalah pilihan, tetapi penting. Ia akan dipanggil oleh atom apabila tingkap ditutup, atau pengguna menyahaktifkannya dalam tetapan. Apabila pakej anda dinyahaktifkan oleh pengguna, dan anda tidak melupuskan peristiwa/arahan tambahan, mereka masih tersedia. Ini bukan masalah apabila atom menutup tingkap. Ia akan meruntuhkan peristiwa dan arahan. Tetapi jika pakej anda menonton fail atau melakukan apa -apa kerja lain, anda harus melepaskannya dalam menyahaktifkan ().
Pakej biasanya melanggan pelbagai acara seperti menambah arahan tersuai, mendengar perubahan, atau fail yang diubah suai. Adalah mungkin untuk membungkus ini ke dalam contoh compositeSposable (), dan dengan cara ini mereka semua boleh dilupuskan sekaligus.
<span>// lib/main.js </span><span>import <span>{ CompositeDisposable }</span> from 'atom'; </span> <span>const YourPackage = { </span> <span>subscriptions: null, </span> <span>activate (state) { </span> <span>// Assign a new instance of CompositeDisposable... </span> <span>this.subscriptions = new CompositeDisposable(); </span> <span>// ...and adding commands. </span> <span>this.subscriptions.add( </span> atom<span>.commands.add('atom-workspace', { </span> <span>'your-package:toggle': this.togglePackage </span> <span>}) </span> <span>); </span> <span>}, </span> <span>// When your package get's deactivated, all added </span> <span>// subscriptions will be disposed of at once. </span> <span>deactivate () { </span> <span>this.subscriptions.dispose(); </span> <span>}, </span> <span>togglePackage () { </span> <span>// Code to toggle the package state. </span> <span>} </span><span>}; </span>
Serialization adalah ciri yang kuat, tetapi sekali lagi, ciri pakej atom. Serialization/deserialization berlaku apabila tingkap ditutup, disegarkan atau dipulihkan dari sesi sebelumnya. Terserah kepada anda untuk menentukan yang mana dan berapa banyak komponen anda harus bersiri data mereka. Apa yang penting ialah ia mengembalikan JSON. Sekiranya anda mempunyai pandangan, dan mahu itu dapat disegarkan semula, anda perlu menjadikannya serasi dengan siri dan deserialization.
Komponen yang sangat asas ini mengambil objek, yang akan digunakan sebagai data dalaman komponen. Komponen anda kemudian mungkin melakukan kerja dengan data dan boleh membenarkan keadaannya bersiri melalui kaedah Serialize ().
<span>{ </span> <span>"name": "your-package", </span> <span>"main": "./lib/main", </span> <span>"version": "0.1.0", </span> <span>"description": "A short description of your package", </span> <span>"keywords": [ </span> <span>"awesome" </span> <span>], </span> <span>"repository": "https://github.com/<your-name>/<package>", </span> <span>"license": "MIT", </span> <span>"engines": { </span> <span>"atom": ">=1.0.0 <2.0.0" </span> <span>}, </span> <span>"dependencies": { </span> <span>} </span><span>} </span>
Untuk menjadikan semua ini berguna, komponen ini mesti dipanggil dan bersiri dalam pakej anda singleton utama.
<span>// lib/main.js </span><span>'use babel'; </span> <span>// This is your main singleton. </span><span>// The whole state of your package will be stored and managed here. </span><span>const YourPackage = { </span> <span>activate (state) { </span> <span>// Activates and restores the previous session of your package. </span> <span>}, </span> <span>deactivate () { </span> <span>// When the user or Atom itself kills a window, this method is called. </span> <span>}, </span> <span>serialize () { </span> <span>// To save the current package's state, this method should return </span> <span>// an object containing all required data. </span> <span>} </span><span>}; </span> <span>export default YourPackage; </span>
Semua objek yang anda mahu bersiri memerlukan kaedah Serialize (). Ia mesti mengembalikan "objek berseri", dan kunci deserializer dengan nama deserializer berdaftar. Menurut Atom, "biasanya nama kelas itu sendiri". Tambahan untuk itu, kelas juga memerlukan kaedah deserialize statik (). Kaedah ini menukarkan objek dari keadaan sebelumnya ke objek tulen.
Untuk menjadikan semua ini mungkin, anda perlu menambah kelas anda ke sistem deserialization dengan atom.deserializers.add ().
Pane adalah tetingkap individu dalam atom. Ia mengandungi semua tab terbuka, yang dipanggil "item". Panel ini disimpan dalam objek Atom.Workspace. Dengan atom.workspace.getActivePane () anda meminta anak tetingkap aktif semasa. Objek pane tidak mengandungi unsur -unsur DOM, tetapi semua contoh komponen dalaman Atom (mis. TextEditor, Guttercontainer, NotificationManager). Memahami panel ini adalah penting untuk membuat pandangan tersuai untuk pakej anda.
paparan atau mana -mana elemen UI tersuai lain yang anda mahu tambah mesti dibuat dengan JavaScript. Atom sepenuhnya dibina dengan komponen web, tetapi anda tidak perlu berbuat demikian. Contoh yang sangat asas dari modal tersuai mungkin seperti berikut.
<span>// lib/main.js </span><span>import <span>{ CompositeDisposable }</span> from 'atom'; </span> <span>const YourPackage = { </span> <span>subscriptions: null, </span> <span>activate (state) { </span> <span>// Assign a new instance of CompositeDisposable... </span> <span>this.subscriptions = new CompositeDisposable(); </span> <span>// ...and adding commands. </span> <span>this.subscriptions.add( </span> atom<span>.commands.add('atom-workspace', { </span> <span>'your-package:toggle': this.togglePackage </span> <span>}) </span> <span>); </span> <span>}, </span> <span>// When your package get's deactivated, all added </span> <span>// subscriptions will be disposed of at once. </span> <span>deactivate () { </span> <span>this.subscriptions.dispose(); </span> <span>}, </span> <span>togglePackage () { </span> <span>// Code to toggle the package state. </span> <span>} </span><span>}; </span>
<span>// lib/fancy-component.js </span><span>class FancyComponent { </span> <span>constructor (configData) { </span> <span>this.data = configData; </span> <span>} </span> <span>// This method will be called when the class </span> <span>// is restored by Atom. </span> <span>static deserialize (config) { </span> <span>return new FancyComponent(config); </span> <span>} </span> <span>// The returned object will be used to restore </span> <span>// or save your data by Atom. </span> <span>// The "deserializer" key must be the name of your class. </span> <span>serialize () { </span> <span>return { </span> <span>deserializer: 'FancyComponent', </span> <span>data: this.data </span> <span>}; </span> <span>} </span> <span>doSomethingWithData () {} </span><span>} </span> <span>// Add class to Atom's deserialization system </span>atom<span>.deserializers.add(FancyComponent); </span> <span>export default FancyComponent; </span>
kaedah atom.workspace.addmodalpanel () menambah elemen modal ke ruang kerja Atom. Sekiranya anda ingin menambah paparan tersuai ke panel (mis. Untuk halaman tetapan) terdapat sedikit kerja yang diperlukan walaupun.
Konfigurasi pakej hendaklah diterangkan dalam skema JSON. Untuk menambah tetapan, objek pakej anda memerlukan kunci konfigurasi dengan data. Sebagai alternatif, anda boleh memindahkan konfigurasi ke fail config-schema.json dan mengimportnya. Ini menjadikan konfigurasi anda dipisahkan dan seni bina anda dianjurkan.
<span>// lib/main.js </span><span>import <span>FancyComponent</span> from './fancy-component'; </span><span>import <span>SomeView</span> from './some-view'; </span> <span>const YourPackage = { </span> <span>fancyComponent: null, </span> <span>someView: null, </span> <span>activate (state) { </span> <span>// If the component has been saved at a previous session of Atom, </span> <span>// it will be restored from the deserialization system. It calls your </span> <span>// your components static 'deserialize()' method. </span> <span>if (state.fancy) { </span> <span>this.fancyComponent = atom.deserializers.deserialize(state.fancy); </span> <span>} </span> <span>else { </span> <span>this.fancyComponent = new FancyComponent({ otherData: 'will be used instead' }); </span> <span>} </span> <span>// More activation logic. </span> <span>}, </span> <span>// As well as your component, your package has a serialize method </span> <span>// to save the current state. </span> <span>serialize () { </span> <span>return { </span> <span>fancy: this.fancyComponent.serialize(), </span> <span>view: this.someView.serialize() </span> <span>}; </span> <span>} </span><span>}; </span>
<span>// lib/custom-view-element.js </span><span>export default class YourPackageView { </span> <span>constructor (state) { </span> <span>this.data = state; </span> <span>this.element = document.createElement('div'); </span> <span>this.message = document.createElement('span'); </span> <span>this.textNode = document.createTextNode(this.data.content); </span> <span>this.element.classList.add('your-package'); </span> <span>this.message.classList.add('your-package-message'); </span> <span>this.message.appendChild(this.textNode); </span> <span>this.element.appendChild(this.message); </span> <span>} </span> <span>serialize () { </span> <span>return { </span> <span>data: this.data </span> <span>}; </span> <span>} </span> <span>destroy () { </span> <span>this.element.remove(); </span> <span>} </span> <span>getElement () { </span> <span>return this.element; </span> <span>} </span> <span>doSomethingWithData () {} </span><span>} </span>
Ini mewujudkan konfigurasi pada halaman tetapan pakej anda secara automatik. Senarai semua jenis yang disokong boleh didapati di halaman konfigurasi dokumentasi API Atom. Objek tetapan anda, bersama -sama dengan semua konfigurasi pakej lain, disimpan dalam objek atom.config.
Anda boleh mendapatkan dan menetapkan sebarang kunci konfigurasi anda dengan kaedah GET () dan set (). Ia juga mungkin untuk mendapatkan tetapan umum Atom atau tetapan pakej lain. Jika anda ingin berinteraksi dengan pakej lain, anda perlu menyediakan dan menggunakan perkhidmatan.
<span>{ </span> <span>"name": "your-package", </span> <span>"main": "./lib/main", </span> <span>"version": "0.1.0", </span> <span>"description": "A short description of your package", </span> <span>"keywords": [ </span> <span>"awesome" </span> <span>], </span> <span>"repository": "https://github.com/<your-name>/<package>", </span> <span>"license": "MIT", </span> <span>"engines": { </span> <span>"atom": ">=1.0.0 <2.0.0" </span> <span>}, </span> <span>"dependencies": { </span> <span>} </span><span>} </span>
Untuk mendengar perubahan, anda boleh memerhatikan konfigurasi untuk perubahan, atau mempunyai pendengar - dipanggil ondidChange () - ke jalan utama. Kedua -duanya mengembalikan pakai buang yang anda boleh .dispose () untuk berhenti berlangganan.
sekali lagi, menambahkannya kepada contoh kompositisposable membolehkan anda melupuskan pelbagai peristiwa sekaligus:
<span>// lib/main.js </span><span>'use babel'; </span> <span>// This is your main singleton. </span><span>// The whole state of your package will be stored and managed here. </span><span>const YourPackage = { </span> <span>activate (state) { </span> <span>// Activates and restores the previous session of your package. </span> <span>}, </span> <span>deactivate () { </span> <span>// When the user or Atom itself kills a window, this method is called. </span> <span>}, </span> <span>serialize () { </span> <span>// To save the current package's state, this method should return </span> <span>// an object containing all required data. </span> <span>} </span><span>}; </span> <span>export default YourPackage; </span>
atau, buangnya secara individu:
<span>// lib/main.js </span><span>import <span>{ CompositeDisposable }</span> from 'atom'; </span> <span>const YourPackage = { </span> <span>subscriptions: null, </span> <span>activate (state) { </span> <span>// Assign a new instance of CompositeDisposable... </span> <span>this.subscriptions = new CompositeDisposable(); </span> <span>// ...and adding commands. </span> <span>this.subscriptions.add( </span> atom<span>.commands.add('atom-workspace', { </span> <span>'your-package:toggle': this.togglePackage </span> <span>}) </span> <span>); </span> <span>}, </span> <span>// When your package get's deactivated, all added </span> <span>// subscriptions will be disposed of at once. </span> <span>deactivate () { </span> <span>this.subscriptions.dispose(); </span> <span>}, </span> <span>togglePackage () { </span> <span>// Code to toggle the package state. </span> <span>} </span><span>}; </span>
Menu dan KeyMaps menjadikan fungsi pakej anda dapat diakses oleh pengguna dalam persekitaran atom. Mereka dikaitkan dengan arahan tertentu antara muka anda. Sekiranya pakej anda boleh ditukar, buka paparan, lakukan tindakan tersuai atau apa -apa lagi, ia harus tersedia kepada pengguna.
Definisi menu boleh disimpan sebagai fail JSON dalam direktori menu/ peringkat atas atau dalam kunci menu pakej.json anda. Contoh berikut menambah arahan ke bar menu pakej dan ke menu konteks editor. Menu konteks muncul apabila mengklik kanan di dalam editor.
<span>// lib/fancy-component.js </span><span>class FancyComponent { </span> <span>constructor (configData) { </span> <span>this.data = configData; </span> <span>} </span> <span>// This method will be called when the class </span> <span>// is restored by Atom. </span> <span>static deserialize (config) { </span> <span>return new FancyComponent(config); </span> <span>} </span> <span>// The returned object will be used to restore </span> <span>// or save your data by Atom. </span> <span>// The "deserializer" key must be the name of your class. </span> <span>serialize () { </span> <span>return { </span> <span>deserializer: 'FancyComponent', </span> <span>data: this.data </span> <span>}; </span> <span>} </span> <span>doSomethingWithData () {} </span><span>} </span> <span>// Add class to Atom's deserialization system </span>atom<span>.deserializers.add(FancyComponent); </span> <span>export default FancyComponent; </span>
dengan KeyMaps anda menentukan jalan pintas untuk arahan pakej anda. Mereka terikat dengan skop tertentu, di mana skop adalah pemilih CSS seperti atom-teks-editor, atom-teks-editor: tidak ([mini]) atau ruang kerja atom. Apabila elemen yang sepadan dengan pemilih adalah fokus, dan corak kekunci digunakan, tindakan tersuai anda dipancarkan.
<span>// lib/main.js </span><span>import <span>FancyComponent</span> from './fancy-component'; </span><span>import <span>SomeView</span> from './some-view'; </span> <span>const YourPackage = { </span> <span>fancyComponent: null, </span> <span>someView: null, </span> <span>activate (state) { </span> <span>// If the component has been saved at a previous session of Atom, </span> <span>// it will be restored from the deserialization system. It calls your </span> <span>// your components static 'deserialize()' method. </span> <span>if (state.fancy) { </span> <span>this.fancyComponent = atom.deserializers.deserialize(state.fancy); </span> <span>} </span> <span>else { </span> <span>this.fancyComponent = new FancyComponent({ otherData: 'will be used instead' }); </span> <span>} </span> <span>// More activation logic. </span> <span>}, </span> <span>// As well as your component, your package has a serialize method </span> <span>// to save the current state. </span> <span>serialize () { </span> <span>return { </span> <span>fancy: this.fancyComponent.serialize(), </span> <span>view: this.someView.serialize() </span> <span>}; </span> <span>} </span><span>}; </span>
perlu diingat bahawa arahan ini mestilah didaftarkan (atom.commands.add ()) dalam entri-titik anda.
Debugging dalam Atom tidak jauh berbeza untuk menyahpepijat di web. Anda boleh mengaktifkan alat pemaju Chrome di bawah Lihat> Pembangun> Toggle Alat Pembangun untuk melihat kesilapan yang dilemparkan, log dari kod anda atau mendapatkan pemahaman tentang markup Atom.
Atom menggunakan kerangka Jasmine untuk ujiannya. Ujian diletakkan di dalam direktori dan fail peringkat atas dan fail dalam mesti berakhir dengan -spec (mis. Fancy-component-spec.js). Ujian tidak diperlukan untuk menjalankan pakej anda atau menerbitkannya, tetapi mereka adalah cara yang baik untuk menyokong kualiti kod anda dan pastikan tiada apa -apa pecah apabila menambah ciri -ciri baru.
Untuk menjalankan ujian anda, anda boleh menggunakan tetingkap: perintah run-package-specs atau pergi ke View> Developer> Run Package Specs.
Jika anda ingin menjalankan spesifikasi pakej anda di Travis CI, terdapat jawatan ringkas mengenai blog Atom tentang cara menetapkannya.
itu banyak input. Aliran sebenar atau urutan pelaksanaan atom adalah kira -kira seperti berikut (nota: ujian bukan sebahagian daripada aliran pakej).
Saya harap artikel saya telah membantu anda untuk mendapatkan pemahaman asas tentang pembangunan pakej atom. Masih banyak lagi fungsi, dan banyak topik, yang malangnya tidak dapat dilindungi dalam satu artikel sahaja. Lihatlah Manual Penerbangan Atom untuk melihat apa lagi yang mungkin.
pakej apa yang akan anda usahakan?
// mengeksport fungsi dalam modul.js
fungsi eksport myFunction () {// mengimporting Fungsi dalam modul lain
import {myFunction} dari './module.js';Modularizing code in vanilla JavaScript mempunyai beberapa faedah. Ia menjadikan kod anda lebih teratur, lebih mudah difahami, dan dikekalkan. Ia juga menggalakkan penggunaan semula kod, kerana anda boleh mengimport dan menggunakan modul yang sama di bahagian yang berlainan aplikasi anda. Selain itu, ia membantu dalam menguruskan kebergantungan, kerana setiap modul dapat menentukan kebergantungannya sendiri. yang boleh anda gunakan untuk debug pakej anda. Anda boleh membuka panel ini dengan melihat> pemaju> alat pemaju togol. Di sini, anda boleh memeriksa kod anda, menetapkan titik putus, dan memantau pembolehubah dan aktiviti rangkaian. Di samping itu, anda boleh menggunakan pernyataan konsol.log () dalam kod anda ke nilai output ke konsol untuk tujuan debug. Untuk memastikan pakej atom anda serasi dengan versi atom yang berlainan, anda harus mengikuti garis panduan Atom API dan elakkan menggunakan API yang ditetapkan. Anda juga harus menguji pakej anda pada versi Atom yang berbeza untuk mengenal pasti dan membetulkan sebarang masalah keserasian. Di samping itu, anda boleh menentukan versi atom minimum yang diperlukan dalam fail pakej.json pakej anda.
Atas ialah kandungan terperinci Cara Menulis Pakej Atom Menggunakan Vanilla Javascript. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!