Kompiler penutupan adalah alat untuk membuat unduhan JavaScript dan berjalan lebih cepat. Ini adalah kompiler sejati untuk JavaScript. Alih -alih menyusun dari bahasa sumber ke kode mesin, ia dikompilasi dari javascript ke javascript yang lebih baik. Ini mem -parsing javascript Anda, menganalisisnya, menghapus kode mati dan menulis ulang dan meminimalkan apa yang tersisa. Ini juga memeriksa sintaks, referensi variabel, dan jenis, dan memperingatkan tentang jebakan javascript umum.
Mode kompilasi selain ADVANCED
selalu menjadi renungan dan kami telah mencela mode -mode itu. Kami percaya bahwa alat lain berkinerja sebanding untuk mode yang tidak ADVANCED
dan lebih baik diintegrasikan ke dalam ekosistem JS yang lebih luas.
Kompiler penutupan tidak cocok untuk javascript sewenang -wenang. Untuk mode ADVANCED
untuk menghasilkan JavaScript yang berfungsi, kode input JS harus ditulis dengan pemasukan penutupan.
Compiler Closure adalah pengoptimal "seluruh dunia". Ia berharap untuk secara langsung melihat atau setidaknya menerima informasi tentang setiap kemungkinan penggunaan setiap variabel global atau yang diekspor dan setiap nama properti.
Ini akan secara agresif menghapus dan mengganti nama variabel dan properti untuk membuat kode output sekecil mungkin. Ini akan mengakibatkan JS output yang rusak, jika penggunaan variabel atau properti global disembunyikan darinya.
Meskipun seseorang dapat menulis file eksternal khusus untuk memberi tahu kompiler agar beberapa nama tidak berubah sehingga mereka dapat dengan aman diakses dengan kode yang bukan bagian dari kompilasi, ini sering membosankan untuk dipertahankan.
Penutupan penggantian nama properti Compiler mengharuskan Anda untuk secara konsisten mengakses properti dengan obj[p]
atau obj.propName
, tetapi tidak keduanya.
Saat Anda mengakses properti dengan tanda kurung persegi (misalnya obj[p]
) atau menggunakan beberapa metode tidak langsung lainnya seperti let {p} = obj;
Ini menyembunyikan nama literal properti yang dirujuk dari kompiler. Tidak dapat mengetahui apakah obj.propName
mengacu pada properti yang sama dengan obj[p]
. Dalam beberapa kasus akan melihat masalah ini dan menghentikan kompilasi dengan kesalahan. Dalam kasus lain itu akan mengganti nama propName
menjadi sesuatu yang lebih pendek, tanpa memperhatikan masalah ini, menghasilkan kode JS output yang rusak.
Kompiler Penutupan secara agresif memasukkan variabel global dan meratakan rantai nama properti pada variabel global (misalnya myFoo.some.sub.property
-> myFoo$some$sub$property
), untuk membuat alasan tentang mereka lebih mudah untuk mendeteksi kode yang tidak digunakan.
Ia mencoba untuk mundur dari melakukan ini atau berhenti dengan kesalahan saat melakukannya akan menghasilkan output JS yang rusak, tetapi ada kasus di mana ia akan gagal mengenali masalah dan hanya menghasilkan JS yang rusak tanpa peringatan. Ini jauh lebih mungkin terjadi dalam kode yang tidak secara eksplisit ditulis dengan mempertimbangkan kompiler penutupan.
Kompiler penutupan dan eksternal yang digunakannya secara default mengasumsikan bahwa lingkungan target adalah jendela browser web.
Webworker juga didukung, tetapi kompiler kemungkinan akan gagal memperingatkan Anda jika Anda mencoba menggunakan fitur yang sebenarnya tidak tersedia untuk pekerja web.
Beberapa file dan fitur eksternal telah ditambahkan ke Compiler Penutupan untuk mendukung lingkungan NodeJS, tetapi mereka tidak didukung secara aktif dan tidak pernah bekerja dengan baik.
JavaScript yang tidak menggunakan goog.module()
dan goog.require()
dari base.js
untuk mendeklarasikan dan menggunakan modul tidak didukung dengan baik.
Sintaks import
dan export
ECMascript tidak ada sampai 2015. Kompiler Penutupan dan closure-library
mengembangkan cara mereka sendiri untuk mendeklarasikan dan menggunakan modul, dan ini tetap satu-satunya cara yang didukung dengan baik untuk mendefinisikan modul.
Kompiler memang menerapkan beberapa pemahaman tentang modul ecmascript, tetapi mengubah proyek Google untuk menggunakan sintaksis yang lebih baru tidak pernah menawarkan manfaat yang sepadan dengan biaya perubahan. Kode TypeScript Google menggunakan modul ecmascript, tetapi mereka dikonversi ke sintaks goog.module()
sebelum kompiler penutupan melihatnya. Jadi, secara efektif dukungan modul ecmascript tidak digunakan dalam Google. Ini berarti kami tidak mungkin memperhatikan atau memperbaiki bug dalam dukungan untuk modul ecmascript.
Dukungan untuk modul CommonJS sebagai input ditambahkan di masa lalu, tetapi tidak digunakan dalam Google, dan kemungkinan akan sepenuhnya dihapus sekitar tahun 2024.
Kompiler Penutupan digunakan oleh Google Projects untuk:
Secara drastis mengurangi ukuran kode aplikasi javascript yang sangat besar
Periksa kode JS untuk kesalahan dan untuk kesesuaian dengan praktik terbaik umum dan/atau khusus proyek.
Tentukan pesan yang terlihat pengguna dengan cara yang memungkinkan untuk menggantinya dengan versi yang diterjemahkan untuk membuat versi aplikasi yang terlokalisasi.
Transpile fitur JS yang lebih baru ke dalam bentuk yang akan berjalan di browser yang tidak memiliki dukungan untuk fitur -fitur tersebut.
Pecahkan aplikasi output menjadi potongan yang mungkin dimuat secara individual sesuai kebutuhan.
CATATAN: Potongan -potongan ini adalah skrip JavaScript biasa. Mereka tidak menggunakan sintaks ecmascript import
dan export
.
Untuk mencapai tujuan -tujuan ini, penyusun penutupan menempatkan banyak pembatasan pada inputnya:
Gunakan goog.module()
dan goog.require()
untuk mendeklarasikan dan menggunakan modul.
Dukungan untuk sintaks import
dan export
yang ditambahkan dalam ES6 tidak dipertahankan secara aktif.
Gunakan anotasi dalam komentar untuk mendeklarasikan informasi jenis dan memberikan informasi yang dibutuhkan kompiler untuk menghindari melanggar beberapa pola kode (misalnya @nocollapse
dan @noinline
).
Baik hanya menggunakan dot-access (misalnya object.property
) atau hanya menggunakan akses dinamis (misalnya object[propertyName]
atau Object.keys(object)
) untuk mengakses properti dari jenis objek tertentu.
Mencampur ini akan menyembunyikan beberapa penggunaan properti dari kompiler, menghasilkan kode output yang rusak saat mengganti nama properti.
Secara umum kompiler mengharapkan untuk melihat seluruh aplikasi sebagai kompilasi tunggal. Antarmuka harus dibangun dengan hati -hati dan eksplisit untuk memungkinkan interoperasi dengan kode di luar unit kompilasi.
Kompiler mengasumsikan dapat melihat semua penggunaan semua variabel dan properti dan akan secara bebas mengganti nama atau menghapusnya jika tampak tidak digunakan.
Gunakan file eksternal untuk menginformasikan kompiler dari variabel atau properti apa pun yang tidak boleh dihapus atau diganti nama.
Ada file eksternal default yang menyatakan JS standar dan API global DOM. Lebih banyak file eksternal diperlukan jika Anda menggunakan API yang kurang umum atau mengharapkan beberapa kode JavaScript eksternal untuk mengakses API dalam kode yang Anda kompilasi.
Cara termudah untuk menginstal kompiler adalah dengan NPM atau benang:
yarn global add google-closure-compiler
# OR
npm i -g google-closure-compiler
Manajer paket akan menautkan biner untuk Anda, dan Anda dapat mengakses kompiler dengan:
google-closure-compiler
Ini memulai kompiler dalam mode interaktif. Jenis:
var x = 17 + 25 ;
Tekan Enter
, lalu Ctrl+Z
(pada Windows) atau Ctrl+D
(pada Mac/Linux), lalu Enter
lagi. Kompiler akan merespons dengan output yang dikompilasi (menggunakan mode SIMPLE
secara default):
var x = 42 ;
Rilis kompiler yang telah dikompilasi sebelumnya juga tersedia melalui Maven.
Kompiler penutupan memiliki banyak opsi untuk membaca input dari file, menulis output ke file, memeriksa kode Anda, dan menjalankan optimisasi. Berikut adalah contoh sederhana untuk mengompresi program JS:
google-closure-compiler --js file.js --js_output_file file.out.js
Kami mendapatkan manfaat paling besar dari kompiler jika kami memberikan semua kode sumber kami (lihat menyusun beberapa skrip), yang memungkinkan kami untuk menggunakan optimasi ADVANCED
:
google-closure-compiler -O ADVANCED rollup.js --js_output_file rollup.min.js
Catatan: Output di bawah ini hanyalah sebuah contoh dan tidak terus-menerus. Halaman wiki bendera dan opsi diperbarui selama setiap rilis.
Untuk melihat semua opsi kompiler, ketik:
google-closure-compiler --help
--flag | Keterangan |
---|---|
--compilation_level (-O) | Menentukan level kompilasi yang akan digunakan. Opsi: BUNDLE , WHITESPACE_ONLY , SIMPLE (default), ADVANCED |
--env | Menentukan himpunan eksternal builtin untuk dimuat. Opsi: BROWSER , CUSTOM . Default ke BROWSER . |
--externs | File yang berisi eksternal JavaScript. Anda dapat menentukan beberapa |
--js | Nama file JavaScript. Anda dapat menentukan beberapa. Nama bendera adalah opsional, karena ARG ditafsirkan sebagai file secara default. Anda juga dapat menggunakan pola Glob gaya miniMatch. Misalnya, gunakan --js='**.js' --js='!**_test.js' untuk secara rekursif memasukkan semua file js yang tidak berakhir di _test.js |
--js_output_file | Nama file output primer. Jika tidak ditentukan, output ditulis ke stdout. |
--language_in | Menetapkan spek bahasa ke sumber input mana yang harus sesuai. Opsi: ECMASCRIPT3 , ECMASCRIPT5 , ECMASCRIPT5_STRICT , ECMASCRIPT_2015 , ECMASCRIPT_2016 ECMASCRIPT_NEXT ECMASCRIPT_2017 , ECMASCRIPT_2018 , STABLE , ECMASCRIPT_2019 |
--language_out | Mengatur spek bahasa yang harus disesuaikan dengan output. Opsi: ECMASCRIPT3 , ECMASCRIPT5 , ECMASCRIPT5_STRICT , ECMASCRIPT_2015 , ECMASCRIPT_2016 , ECMASCRIPT_2017 , ECMASCRIPT_2018 , ECMASCRIPT_2019 , STABLE |
--warning_level (-W) | Menentukan tingkat peringatan untuk digunakan. Opsi: QUIET , DEFAULT , VERBOSE |
Anda dapat mengakses kompiler dalam program JS dengan mengimpor google-closure-compiler
:
import closureCompiler from 'google-closure-compiler' ;
const { compiler } = closureCompiler ;
new compiler ( {
js : 'file-one.js' ,
compilation_level : 'ADVANCED'
} ) ;
Paket ini akan memberikan akses terprogram ke biner Graal asli dalam banyak kasus, dan akan kembali ke versi Java sebaliknya.
Jika Anda memiliki banyak skrip, Anda harus mengkompilasi semuanya bersama dengan satu perintah kompilasi.
google-closure-compiler in1.js in2.js in3.js --js_output_file out.js
Anda juga dapat menggunakan globs bergaya miniMatch.
# Recursively include all js files in subdirs
google-closure-compiler ' src/**.js ' --js_output_file out.js
# Recursively include all js files in subdirs, excluding test files.
# Use single-quotes, so that bash doesn't try to expand the '!'
google-closure-compiler ' src/**.js ' ' !**_test.js ' --js_output_file out.js
Kompiler penutupan akan menggabungkan file dalam urutan yang mereka lewati di baris perintah.
Jika Anda menggunakan Globs atau banyak file, Anda dapat mulai mengalami masalah dengan mengelola ketergantungan antar skrip. Dalam hal ini, Anda harus menggunakan lib/base.js yang disertakan yang menyediakan fungsi untuk menegakkan dependensi antara skrip (yaitu goog.module
dan goog.require
). Kompiler penutupan akan memesan ulang input secara otomatis.
Pelepasan Kompiler Penutupan dengan Lib/Base.js yang menyediakan fungsi dan variabel JavaScript yang berfungsi sebagai primitif yang memungkinkan fitur tertentu dari kompiler penutupan. File ini adalah turunan dari basis.js yang dinamai identik di perpustakaan penutupan yang akan segera ditinggalkan. base.js
ini.js akan didukung oleh compiler penutupan ke depan dan mungkin menerima fitur baru. Itu dirancang untuk hanya mempertahankan bagian intinya yang dirasakan.
Untuk membangun kompiler sendiri, Anda akan membutuhkan yang berikut:
Prasyarat | Keterangan |
---|---|
Java 11 atau lebih | Digunakan untuk mengkompilasi kode sumber kompiler. |
NodeJS | Digunakan untuk menghasilkan sumber daya yang digunakan oleh kompilasi java |
Git | Digunakan oleh Bazel untuk mengunduh dependensi. |
Bazelisk | Digunakan untuk membangun berbagai target kompiler. |
Bazelisk adalah pembungkus di sekitar Bazel yang secara dinamis memuat versi Bazel yang sesuai untuk repositori yang diberikan. Menggunakannya mencegah kesalahan palsu yang dihasilkan dari menggunakan versi Bazel yang salah untuk membangun kompiler, serta membuatnya mudah untuk menggunakan versi bazel yang berbeda untuk proyek lain.
Bazelisk tersedia melalui banyak manajer paket. Jangan ragu untuk menggunakan mana pun yang paling Anda sukai.
Instruksi untuk menginstal Bazelisk.
$ bazelisk build //:compiler_uberjar_deploy.jar
# OR to build everything
$ bazelisk build //:all
Tes dapat dieksekusi dengan cara yang sama. Perintah berikut akan menjalankan semua tes dalam repo.
$ bazelisk test //:all
Ada ratusan target tes individu, sehingga perlu beberapa menit untuk menjalankan semuanya. Saat berkembang, biasanya lebih baik untuk menentukan tes tepat yang Anda minati.
bazelisk test //: $path_to_test_file
Lihat integrasi Bazel IDE.
Setelah kompiler dibangun, stoples yang dikompilasi akan berada di bazel-bin/
direktori. Anda dapat mengaksesnya dengan panggilan ke java -jar ...
atau dengan menggunakan skrip package.json:
# java -jar bazel-bin/compiler_uberjar_deploy.jar [...args]
yarn compile [...args]
src/com/google/javascript/jscomp/CommandLineRunner.java
atau buat versi tambahan kelas Anda sendiri.Bagaimanapun Anda memilih untuk berkontribusi, harap patuhi kode perilaku kami untuk menjaga komunitas kami tempat yang sehat dan ramah.
Hak Cipta 2009 Penulis Penutupan Penutupan.
Berlisensi di bawah lisensi Apache, versi 2.0 ("lisensi"); Anda tidak boleh menggunakan file ini kecuali sesuai dengan lisensi. Anda dapat memperoleh salinan lisensi di http://www.apache.org/licenses/license-2.0.
Kecuali diharuskan oleh hukum yang berlaku atau disepakati secara tertulis, perangkat lunak yang didistribusikan di bawah lisensi didistribusikan berdasarkan "sebagaimana adanya", tanpa jaminan atau ketentuan dalam bentuk apa pun, baik tersurat maupun tersirat. Lihat lisensi untuk bahasa spesifik yang mengatur izin dan batasan di bawah lisensi.
Jalur kode | src/com/google/javascript/rhino , test/com/google/javascript/rhino |
Url | https://developer.mozilla.org/en-us/docs/mozilla/projects/rhino |
Versi | 1.5R3, dengan modifikasi berat |
Lisensi | Lisensi Publik Netscape dan Lisensi Ganda MPL / GPL |
Keterangan | Salinan parsial Mozilla Rhino. Mozilla Rhino adalah implementasi JavaScript untuk JVM. Struktur data Parse Tree JavaScript diekstraksi dan dimodifikasi secara signifikan untuk digunakan oleh kompiler JavaScript Google. |
Modifikasi lokal | Paket -paket telah diganti rugi. Semua kode yang tidak relevan dengan pohon parse telah dihapus. Parser JSDOC dan sistem pengetikan statis telah ditambahkan. |
Url | http://args4j.kohsuke.org/ |
Versi | 2.33 |
Lisensi | Mit |
Keterangan | Args4j adalah perpustakaan kelas Java kecil yang memudahkan untuk menguraikan opsi/argumen baris perintah dalam aplikasi CUI Anda. |
Modifikasi lokal | Tidak ada |
Url | https://github.com/google/guava |
Versi | 31.0.1 |
Lisensi | Lisensi Apache 2.0 |
Keterangan | Perpustakaan Java Inti Google. |
Modifikasi lokal | Tidak ada |
Url | https://github.com/findbugsproject/findbugs |
Versi | 3.0.1 |
Lisensi | Lisensi BSD |
Keterangan | Anotasi untuk Deteksi Cacat Perangkat Lunak. |
Modifikasi lokal | Tidak ada |
Url | http://junit.org/junit4/ |
Versi | 4.13 |
Lisensi | Lisensi Publik Umum 1.0 |
Keterangan | Kerangka kerja untuk menulis dan menjalankan tes otomatis di Java. |
Modifikasi lokal | Tidak ada |
Url | https://github.com/google/protobuf |
Versi | 3.0.2 |
Lisensi | Lisensi BSD Baru |
Keterangan | Pustaka pendukung untuk buffer protokol, pengkodean data terstruktur. |
Modifikasi lokal | Tidak ada |
Url | https://github.com/google/re2j |
Versi | 1.3 |
Lisensi | Lisensi BSD Baru |
Keterangan | Waktu linear pencocokan ekspresi reguler di java. |
Modifikasi lokal | Tidak ada |
Url | https://github.com/google/truth |
Versi | 1.1 |
Lisensi | Lisensi Apache 2.0 |
Keterangan | Kerangka Pernyataan/Proposisi untuk Tes Unit Java |
Modifikasi lokal | Tidak ada |
Url | https://ant.apache.org/bindownload.cgi |
Versi | 1.10.11 |
Lisensi | Lisensi Apache 2.0 |
Keterangan | Semut adalah alat build berbasis Java. Secara teori itu seperti "Make" tanpa kerutan Make dan dengan portabilitas penuh kode java murni. |
Modifikasi lokal | Tidak ada |
Url | https://github.com/google/gson |
Versi | 2.9.1 |
Lisensi | Lisensi Apache 2.0 |
Keterangan | Perpustakaan Java untuk mengonversi JSON ke objek Java dan sebaliknya |
Modifikasi lokal | Tidak ada |
Jalur kode | contrib/nodejs |
Url | https://github.com/dcodeio/node.js-closure-compiler-externs |
Versi | E891B4FBCF5F466CC4307B0FA842A7D8163A073A |
Lisensi | Lisensi Apache 2.0 |
Keterangan | Ketik Kontrak untuk API NodeJS |
Modifikasi lokal | Perubahan substansial untuk membuatnya kompatibel dengan NPMCommandlinerner. |