Saya ditanyai hari ini dan tidak dapat memberikan jawaban yang tepat.
Transparansi ketikan ke JS. Lalu ada getar pohon, "kurang" (opsional) dan apa lagi dalam proses membuat penerapan. Tapi tidak ada yang seperti itu (afaik) yang ada hubungannya dengan "kompilasi". Semuanya dibundel dan sangat dioptimalkan, tetapi sebenarnya tidak dikompilasi, bukan?
Bahkan ada kompiler "sebelumnya", yang benar-benar berfungsi dengan baik. Apa yang saya lewatkan
Javascript sendiri masih diartikan kan?
Jawaban:
Anda menganggap kompilasi berarti mengambil kode sumber dan menghasilkan kode mesin, kode level rendah, dll. Tetapi kompilasi sebenarnya hanya berarti mengambil satu kode sumber dan mengubahnya menjadi kode lain. Jadi sepertinya masuk akal untuk mengatakan bahwa mengambil Typecript dan memproduksi JavaScript adalah bentuk kompilasi. Ini tidak berbeda dengan apa yang (misalnya) c # lakukan ketika dikompilasi ke dalam bahasa IL.
Karena itu, saya akan mengatakan kata yang lebih baik untuk ini adalah Transpiling . Saya menyarankan agar compiler Typecript lebih baik dijelaskan sebagai Transpiler.
Perbedaannya tidak kentara dan transpiler dapat dianggap sebagai jenis penyusun; tetapi bahasa yang dikompilasi (murni) adalah (biasanya) mengubah bahasa tingkat tinggi ke bahasa tingkat rendah (er) (lebih dekat ke kode mesin), seperti contoh C #. Transpiler mengubah bahasa tingkat tinggi menjadi bahasa tingkat (abstraksi) yang serupa (juga tingkat tinggi). *
Hasil dari kode yang dikompilasi biasanya bukan bahasa yang Anda tulis sendiri . Hasil dari transpiler adalah bahasa tingkat tinggi lainnya. Secara teori, Anda dapat menulis IL (sebagai contoh) tetapi IL ini benar-benar dirancang untuk diproduksi oleh kompiler dan tidak ada alat atau dukungan untuk melakukan ini, Anda menghasilkan IL hanya dengan mengkompilasi C # / vb.net. Sedangkan Javascript adalah bahasa pemrograman yang dapat digunakan (dan digunakan) dengan sendirinya.
* Banyak peringatan karena definisi dari kata-kata ini dan penggunaannya cukup kabur
sumber
Anda sepertinya menanyakan tiga pertanyaan sekaligus:
@ JörgWMittag memberikan jawaban yang sangat bagus untuk pertanyaan ini.
Baik TS dan Angular menerapkan kompiler nyata . Mereka mengikuti tahapan yang sama dari analisis leksikal, parsing, analisis semantik, dan pembuatan kode sebagai kompiler C / C ++ yang menghasilkan kode assembly (kecuali mungkin untuk pengoptimalan). Anda dapat melihat bahwa kelas / folder bernama "compiler" di Angular dan TS .
Kompilator sudut tidak benar-benar terkait dengan kompilator TypeScript. Ini adalah kompiler yang sangat berbeda.
Angular memiliki dua kompiler:
Tugas compiler tampilan adalah mengubah template yang Anda tentukan untuk template komponen menjadi representasi internal komponen yang merupakan pabrik tampilan yang kemudian digunakan untuk membuat instance tampilan .
Selain mengubah template, view compiler juga mengkompilasi berbagai informasi metadata dalam bentuk dekorator seperti
@HostBinding
,@ViewChild
dll.Misalkan Anda menentukan komponen dan templatnya seperti ini:
@Component({ selector: 'a-comp', template: '<span>A Component</span>' }) class AComponent {}
Dengan menggunakan data ini, kompilator membuat pabrik komponen yang sedikit disederhanakan berikut ini:
function View_AComponent { return jit_viewDef1(0,[ elementDef2(0,null,null,1,'span',...), jit_textDef3(null,['My name is ',...]) ]
Ini menjelaskan struktur tampilan komponen dan digunakan saat membuat instance komponen. Node pertama adalah definisi elemen dan yang kedua adalah definisi teks. Anda dapat melihat bahwa setiap node mendapatkan informasi yang dibutuhkan ketika dibuat instance-nya melalui daftar parameter. Merupakan tugas kompilator untuk menyelesaikan semua dependensi yang diperlukan dan menyediakannya pada waktu proses.
Saya sangat merekomendasikan membaca artikel ini:
Juga, lihat jawaban untuk Apa perbedaan antara kompiler Angular AOT dan JIT.
Tugas compiler modul adalah membuat pabrik modul yang pada dasarnya berisi definisi gabungan dari provider.
Untuk informasi lebih lanjut, baca:
sumber
Kompilasi berarti mengubah program yang ditulis dalam bahasa A menjadi program yang secara semantik setara yang ditulis dalam bahasa B sehingga mengevaluasi program yang dikompilasi sesuai dengan aturan bahasa B (misalnya menafsirkannya dengan penerjemah untuk B ) menghasilkan hasil yang sama dan memiliki efek samping yang sama seperti mengevaluasi program asli sesuai dengan aturan bahasa A (misalnya menafsirkannya dengan penerjemah untuk A ).
Kompilasi hanya berarti menerjemahkan program dari bahasa A ke bahasa B . Hanya itu artinya. (Juga perhatikan bahwa sangat mungkin A dan B menjadi bahasa yang sama.)
Dalam beberapa kasus, kami memiliki nama yang lebih terspesialisasi untuk jenis kompiler tertentu, bergantung pada apa itu A dan B , dan apa yang dilakukan kompilator:
Juga, perhatikan bahwa sumber yang lebih lama mungkin menggunakan istilah "terjemahan" dan "penerjemah" daripada "kompilasi" dan "kompilator". Misalnya, C berbicara tentang "unit terjemahan".
Anda juga mungkin menemukan istilah "pemroses bahasa". Ini bisa berarti compiler, interpreter, atau compiler dan interpreter bergantung pada definisinya.
JavaScript adalah sebuah bahasa. Bahasa adalah sekumpulan aturan dan batasan logis. Bahasa tidak diinterpretasikan atau dikompilasi. Bahasa hanya merupakan .
Kompilasi dan interpretasi adalah ciri-ciri seorang compiler atau interpreter (duh!). Setiap bahasa dapat diimplementasikan dengan kompiler dan setiap bahasa dapat diimplementasikan dengan penerjemah. Banyak bahasa memiliki kompiler dan interpreter. Banyak mesin eksekusi berperforma tinggi modern memiliki setidaknya satu kompiler dan setidaknya satu interpreter.
Kedua istilah ini termasuk dalam lapisan abstraksi yang berbeda. Jika bahasa Inggris adalah bahasa yang diketik, "bahasa yang ditafsirkan" akan menjadi kesalahan jenis.
Perhatikan juga bahwa beberapa bahasa tidak memiliki interpreter atau compiler. Ada bahasa yang tidak memiliki implementasi sama sekali. Tetap saja, mereka adalah bahasa, dan Anda dapat menulis program di dalamnya. Anda tidak bisa menjalankannya.
Juga, perhatikan bahwa semuanya ditafsirkan di beberapa titik : jika Anda ingin mengeksekusi sesuatu, Anda harus menafsirkannya. Kompilasi hanya menerjemahkan kode dari satu bahasa ke bahasa lain. Itu tidak menjalankannya. Interpretasi menjalankannya. (Kadang-kadang, ketika penerjemah diimplementasikan di perangkat keras, kami menyebutnya sebagai "CPU", tetapi ini masih merupakan penerjemah.)
Contoh kasus: setiap implementasi JavaScript mainstream yang ada saat ini memiliki kompiler.
V8 dimulai sebagai kompiler murni: ia mengkompilasi JavaScript langsung ke kode mesin asli yang dioptimalkan secara moderat. Kemudian, kompiler kedua ditambahkan. Sekarang, ada dua kompiler: kompiler ringan yang menghasilkan kode yang cukup dioptimalkan tetapi kompilernya sendiri sangat cepat dan menggunakan sedikit RAM. Kompiler ini juga memasukkan kode profil ke dalam kode yang dikompilasi. Kompiler kedua adalah kompiler kelas berat, lebih lambat, lebih mahal, yang, bagaimanapun, menghasilkan kode yang jauh lebih ketat, lebih cepat. Ini juga menggunakan hasil kode profil yang dimasukkan oleh compiler pertama untuk membuat keputusan pengoptimalan dinamis. Selain itu, keputusan kode mana yang akan dikompilasi ulang menggunakan kompilator kedua dibuat berdasarkan informasi profil tersebut. Perhatikan bahwa tidak ada penerjemah yang terlibat. V8 tidak pernah menafsirkan, ia selalu dikompilasi. Itu tidak t bahkan mengandung penerjemah. (Sebenarnya, saya yakin saat ini memang demikian, saya sedang menjelaskan dua iterasi pertama.)
SpiderMonkey mengompilasi JavaScript ke bytecode SpiderMonkey, yang kemudian diinterpretasikan. Interpreter juga membuat profil kode, dan kemudian kode yang paling sering dieksekusi dikompilasi oleh compiler ke kode mesin native. Jadi, SpiderMonkey berisi dua kompiler: satu dari JavaScript ke bytecode SpiderMonkey, dan satu lagi dari bytecode SpiderMonkey ke kode mesin asli.
Hampir semua mesin eksekusi JavaScript (dengan pengecualian V8) mengikuti model kompiler AOT yang mengompilasi JavaScript ke bytecode, dan mesin mode campuran yang beralih antara menafsirkan dan mengompilasi bytecode tersebut.
Anda menulis dalam komentar:
Apa artinya "kode mesin"?
Apa bahasa mesin satu orang adalah bahasa perantara orang lain dan sebaliknya? Misalnya, ada CPU yang secara native dapat mengeksekusi bytecode JVM, pada CPU seperti itu, bytecode JVM adalah kode mesin native. Dan ada interpreter untuk kode mesin x86, ketika Anda menjalankan kode mesin x86 tersebut diinterpretasikan bytecode.
Ada interpreter x86 yang disebut JPC yang ditulis di Java. Jika saya menjalankan kode mesin x86 pada JPC yang berjalan pada CPU JVM asli… yang merupakan bytecode dan yang merupakan kode asli? Jika saya mengompilasi kode mesin x86 ke JavaScript (ya, ada alat yang dapat melakukannya) dan menjalankannya di browser pada ponsel saya (yang memiliki CPU ARM), yang merupakan bytecode dan yang merupakan kode mesin asli? Bagaimana jika program yang saya kompilasi adalah emulator SPARC, dan saya menggunakannya untuk menjalankan kode SPARC?
Perhatikan bahwa setiap bahasa menginduksi mesin abstrak, dan merupakan bahasa mesin untuk mesin itu. Jadi, setiap bahasa (termasuk bahasa tingkat sangat tinggi) adalah kode mesin asli. Selain itu, Anda dapat menulis penerjemah untuk setiap bahasa. Jadi, setiap bahasa (termasuk kode mesin x86) tidak asli.
sumber
Mendapatkan kode yang Anda tulis untuk dijalankan di browser melibatkan dua hal:
1) Transpiling Ketikan ke JavaScript . Ini adalah jenis masalah yang terpecahkan. Saya pikir mereka hanya menggunakan webpack.
2) Menyusun abstraksi sudut ke dalam JavaScript . Maksud saya hal-hal seperti komponen, pipa, arahan, templat, dll. Inilah yang dikerjakan tim inti sudut.
Jika Anda benar-benar tertarik dengan bit kedua itu, kompiler sudut, lihat penulis kompiler Tobias Bosch menjelaskan Angular Compiler di AngularConnect 2016 .
Saya pikir ada sedikit kebingungan yang terjadi di sini antara transpiling dan kompilasi. Ini bukan masalah dan masalah selera pribadi, keduanya hanya berubah di antara representasi kode. Tetapi definisi yang saya gunakan secara pribadi adalah bahwa transpilasi berada di antara dua bahasa yang berbeda pada tingkat abstraksi yang serupa (misalnya skrip ketikan ke javascript), sedangkan kompilasi memerlukan penurunan tingkat abstraksi. Saya pikir dari template, komponen, pipa, arahan dll menjadi hanya javascript adalah langkah menuruni tangga abstraksi, dan itulah mengapa ini disebut kompiler.
sumber
Penyusun Sudut
Salah satu perubahan terpenting dari Angular 4 menjadi 5 adalah bahwa kompilator telah ditulis ulang menjadi lebih cepat dan lebih menyeluruh. Di masa lalu, aplikasi Angular menggunakan apa yang kami sebut kompilasi Just-in-Time (JIT), di mana aplikasi tersebut dikompilasi saat runtime di browser sebelum dijalankan. Pembaruan kompiler di Angular 5 memajukan perpindahan ke AOT, yang membuat aplikasi berjalan lebih cepat karena melakukan lebih sedikit kompilasi saat menjalankan aplikasi. AOT diaktifkan secara default di semua build produksi sejak Angular CLI versi 1.5.
Katakanlah kita ingin membangun aplikasi untuk penerapan dan menjalankan perintah berikut:
Beberapa hal terjadi: versi produksi, minifikasi, aset bundel, hashing nama file, goyangan pohon, AOT ... (kita dapat mengaktifkan / menonaktifkan ini menggunakan flag, mis. Aot = false). Singkatnya, flag prod membuat bundel aplikasi yang dioptimalkan dengan melakukan kompilasi AOT menggunakan ngc (Angular compiler) untuk membuat kode yang dioptimalkan dan siap untuk browser ( Ya, itu mengkompilasi template sebelumnya ).
TypeScript Compiler
Kompilator TypeScript, tsc , bertanggung jawab untuk mengompilasi file TypeScript. Ini adalah kompilator yang bertanggung jawab untuk mengimplementasikan fitur TypeScript, seperti tipe statis, dan hasilnya adalah JavaScript murni dari mana kata kunci dan ekspresi TypeScript telah dihapus.
Kompiler TypeScript memiliki dua fitur utama: ini adalah transpiler dan pemeriksa tipe. Kompilator memindahkan TypeScript ke JavaScript. Itu melakukan transformasi berikut pada kode sumber Anda:
Memanggilnya, kompilator mencari konfigurasi yang dimuat di tsconfig.json (Daftar terperinci dari semua opsi kompilator, bersama dengan nilai default, dapat ditemukan di sini ).
Dalam banyak hal, kompilator TypeScript berfungsi seperti kompiler apa pun. Tetapi ada satu perbedaan yang dapat menarik perhatian yang tidak waspada: secara default, compiler terus memancarkan kode JavaScript bahkan ketika menemui kesalahan. Untungnya, perilaku ini dapat dinonaktifkan dengan menyetel pengaturan
noEmitOnError
konfigurasi ke true di file tsconfig.json.Yang perlu diperhatikan : tsc dan ngc memiliki tujuan yang berbeda dan ini bukan tentang memilih satu dari yang lain. Jawaban ini mungkin menarik .
Jawaban ini dibuat berdasarkan konten dari buku-buku berikut
Cloe, M. (2018). "Angular 5 Projects: Belajar Membangun Aplikasi Web Satu Halaman Menggunakan 70+ Proyek".
Dewey, B., Grossnicklaus, K., Japikse, P. (2017). "Membangun Aplikasi Web dengan Visual Studio 2017: Menggunakan .NET Core dan Modern JavaScript Frameworks".
Freeman, A. (2019). "Essential TypeScript: Dari Pemula hingga Pro".
Ghiya, P. (2018). "TypeScript Microservices".
Iskandar, A., Chivukulu, S. (2019). "Pengembangan Web dengan Angular dan Bootstrap - Edisi Ketiga".
Hennessy, K., Arora, C. (2018). "Sudut 6 dengan Contoh".
Jansen, R., Wolf, I., Vane, V. (2016). "TypeScript: Pengembangan JavaScript Modern".
Mohammed, Z. (2019). "Proyek Sudut".
Seshadri, S. (2018). "Angular: Up and Running".
Wilken, J. (2018). "Angular in Action".
sumber