Angular: Gunakan Closure Compiler dengan kompiler template offline

Dibuat pada 9 Mei 2016  ·  105Komentar  ·  Sumber: angular/angular

Kompiler offline baru Angular didemonstrasikan di ng-conf hari 2 keynote oleh @robwormald. Ini menghasilkan kode ES6 yang dapat digoyahkan. Empat langkah kemudian diperlukan:

  • jalankan pengocok pohon untuk menghapus modul ES6 yang tidak dapat dijangkau dari titik masuk, dalam demo kami, kami menunjukkan rollup
  • jalankan bundler untuk mengurangi impor modul menjadi deklarasi dalam satu file; kami menunjukkan system.js
  • down-level ke ES5 - kami menunjukkan ini dengan TypeScript
  • minify untuk mempersingkat nama simbol, kami menggunakan uglify.

Ini menghasilkan file JS 49k, tetapi membutuhkan banyak konfigurasi.

Closure Compiler Google (https://developers.google.com/closure/compiler/) menghasilkan JS yang sangat kecil. Itu melakukan keempat langkah yang diperlukan di atas, jadi konfigurasinya harus jauh lebih sederhana. Kami juga menduga kami bisa mendapatkan ukuran biner yang lebih kecil untuk ng2-hello-world, sekitar 36k.

Pengkabelan ini membutuhkan:

  • [x] tambahkan pembantu anotasi penutupan tsickle ke `ngc
  • [x] memodifikasi distribusi ES6 Angular agar kompatibel dengan kompiler penutupan
  • [x] ?? ubah distro ES6 dari dependensi kami (rxjs, zone.js) agar kompatibel dengan kompilator penutupan
  • [x] cari tahu build minimal (mungkin skrip shell) yang berhasil mengkompilasi aplikasi bersama dengan kerangka kerja dan dependensinya
  • [x] mendokumentasikan bagaimana kami melakukannya sehingga orang lain dapat merepro
  • [x] bundel externs dengan Angular untuk memungkinkan pengujian Busur Derajat (tipe BrowserNodeGlobal )
packaging feature medium

Komentar yang paling membantu

Hari ini kami mendapat rilis rxjs yang berfungsi dengan kompiler penutupan, dan saya telah memperbarui contoh repo
https://github.com/alexeagle/closure-compiler-angular-bundling

Eksternal juga dibersihkan - Angular dan Zone.js mendistribusikan ekstern yang dibutuhkan dalam paket masing-masing.
Kami akan segera menambahkan beberapa dokumentasi dan pengumuman tentang dukungan tersebut.

Semua 105 komentar

Bagian yang menurut saya paling membutuhkan panduan Anda adalah di mana/bagaimana ini cocok dengan proses pembuatan sudut yang lebih besar.
Apakah kita ingin (1) membangun sudut itu sendiri sebagai bundel eksternal yang diperkecil? atau (2) kompilasi kode sudut+pengguna bersama-sama menjadi satu bundel? Dalam kasus terakhir kita harus berintegrasi ke gulp atau apa pun.

Kami mendistribusikan bundel Angular, sebagai ES5 dengan pemuat modul UMD bawaan.
Namun, tidak mungkin untuk memisahkan ini kembali menjadi goyangan pohon
itu, jadi rencana kami adalah #2.
Saya tidak yakin kita harus berkomitmen untuk membangun plugin untuk beberapa yang populer
alat pembuatan userland; orang lain di komunitas akan mengambilnya. saya pikir
"npm run build && npm run closure-compiler" yang lebih sederhana dengan skrip shell adalah
cukup pada titik ini.

Pada Senin, 9 Mei 2016 pukul 11:26 Evan Martin [email protected]
menulis:

Bagian yang menurut saya paling membutuhkan bimbingan Anda adalah di mana / bagaimana ini cocok
proses membangun sudut yang lebih besar.
Apakah kita ingin (1) membangun sudut itu sendiri sebagai bundel eksternal yang diperkecil? atau
(2) kompilasi kode pengguna sudut + bersama-sama menjadi satu bundel? Dalam yang terakhir
kasus kita harus mengintegrasikan ke tegukan atau apa pun.


Anda menerima ini karena Anda yang menulis utas.
Balas email ini secara langsung atau lihat di GitHub
https://github.com/angular/angular/issues/8550#issuecomment -217947352

FYI @jeffbcross mungkin ini bisa buat demo PWA kamu untuk I/O

Ya, itu akan luar biasa jika kita bisa menyelesaikannya pada akhir minggu ini.

Beberapa catatan dari peretasan yang harus saya buat sejauh ini, dengan harapan orang lain dapat mereproduksi:

Closure Compiler tidak menangani semua sintaks modul ES6, dan tidak menganjurkan menggunakannya. Jadi strategi kami sejauh ini adalah menggunakan sintaks goog.module . Itu bukan opsi --module untuk tsc , jadi kami menggunakan tsickle untuk menulis ulang. Itu berarti sudut dan dependensinya harus dipancarkan sebagai "Penutupan ES6".

Perlu membangun kompiler penutupan dari HEAD, lihat https://github.com/google/closure-compiler/blob/master/README.md#building -it-yourself

Untuk membangun sudut ke dalam penutupan ES6, saya memiliki pengeditan lokal di alat ngc untuk menjalankan anotasi penutupan tsickle dan convertCommonJsToGoogModule. Lihat https://github.com/alexeagle/angular/tree/closure_hack2
Bangun sudut dengan cara biasa dengan ./build.sh dan kemudian buat paket-paket tersebut dapat diinstal dengan for pkg in $(find dist/packages-dist -name package.json); do sed -i .bak 's/\$\$ANGULAR_VERSION\$\$/2.0.0-rc.2-snap/g' $pkg; done

Untuk membangun rxjs ke dalam penutupan ES6, saya memiliki suntingan lokal di https://github.com/alexeagle/RxJS/tree/closure - kemudian jalankan npm run build_es6 untuk mendapatkan file yang tepat di dist/es6 . Kemudian npm run generate_packages untuk menyalin package.json .

Kami memerlukan modifikasi untuk menangani solusi https://github.com/ReactiveX/rxjs/issues/1703 - lihat https://github.com/angular/tsickle/tree/closure

Sekarang saya membuat contoh aplikasi. Cuplikan di https://github.com/alexeagle/closure-compiler-angular-bundling
Di direktori vendor saya telah menginstal kompiler penutupan yang dibuat secara lokal.jar, paket angular2, rxjs, dan tsickle, dengan sesuatu seperti
npm install ../angular/dist/packages-dist/{common,compiler_cli,compiler,core,platform-browser,platform-server}
npm install ../rxjs/dist/es6

Jadi Anda hanya dapat npm install dan npm run build untuk mereproduksi bundel penutupan :)

Jadi saya perlu menginstal Java JRE untuk menggabungkan aplikasi hello world Angular2?

Closure Compiler hanyalah salah satu opsi untuk
tree-shake/bundle/Es6-to-5/minify pipeline. Jika Anda memilih penutupan
opsi kompiler, Anda mengambil ketergantungan JRE untuk saat ini. Tapi ada juga JS
versi dalam karya:
https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/gwt/client/GwtRunner.java

Pada Jumat, 13 Mei 2016 pukul 09:44 dpsthree [email protected] menulis:

Jadi saya perlu menginstal Java JRE untuk menggabungkan hello world
Aplikasi Angular2?


Anda menerima ini karena Anda yang menulis utas.
Balas email ini secara langsung atau lihat di GitHub
https://github.com/angular/angular/issues/8550#issuecomment -219096815

Saya menulis beberapa catatan tentang peretasan yang diperlukan untuk membuatnya berfungsi. https://docs.google.com/document/d/17m1GwzXraKgbCkCmH1JnY9IZzPy4cqlpCFVhvlZnOys/edit

Kami mereproduksi karya @alexeagle dan dengan versi Angular yang lebih mutakhir. Seluruh proses pembuatan otomatis, sehingga Anda dapat mengikuti semuanya mulai dari sumber hingga hasil akhir. Anda dapat melihatnya beraksi di https://github.com/lucidsoftware/closure-typescript-example. Instruksi untuk menjalankan contoh dapat ditemukan di README untuk contoh repo. Ada wadah Docker untuk proyek tersebut, jadi hampir semua orang dapat mencobanya.

Contoh di atas menggunakan Angular 2, clutz, dan tsickle. Closure JS digunakan dalam Angular 2 TS, yang dikompilasi ke JS yang kompatibel dengan Penutupan.

Perubahan yang kami buat pada dependensi agar ini berfungsi sebagian besar sama dengan Alex. Ada beberapa perubahan yang kami tambahkan dan beberapa perubahan yang tidak lagi diperlukan. Terlepas dari itu, ide dasarnya sama. Kami menggunakan ngc atau tsickle yang dimodifikasi pada Angular 2 dan dependensinya untuk menghasilkan versi Closure yang kompatibel dari dependensi tersebut.

Kompilator Penutupan

Membangun dari kepala tidak lagi diperlukan. Cukup gunakan salah satu versi dari bulan Juni atau Juli.

sudut

https://github.com/lucidsoftware/angular/tree/closure-bundle

Sebagian besar pekerjaan di sumber Angular 2 adalah memodifikasi ngc untuk menghasilkan Closure compilable js dengan menambahkan beberapa langkah tsickle ke tsc-wrapped. Ada beberapa rintangan yang kami lewati untuk menggunakan sumber yang dimodifikasi sebagai input ke kompiler TypeScript di salah satu tsickle pass. Jika tidak, ini cukup lurus ke depan.

Kami juga mengubah modul Angular tertentu untuk dikompilasi ke JS yang kompatibel dengan Penutupan dengan meletakkan blok angularCompilerOptions di tsconfig.json seperti itu

"angularCompilerOptions": {
  "googleClosureOutput": true
}

Kemudian ketika Anda menjalankan build.sh modul-modul itu memiliki output yang Anda inginkan.

File utilitas pengujian yang menggunakan Selenium-webdriver dimodifikasi karena Selenium-webdriver tidak ada dan kami tidak ingin membuatnya kompatibel dengan penutupan.

RxJS

https://github.com/lucidsoftware/rxjs/tree/closure-hack

Proses pembuatan RxJS dimodifikasi untuk membangun dengan Makefile dari proyek kami. Sekitar setengah dari proses pembuatan ada di JS dan setengahnya lagi di Make. Ini cukup jenaka.

Satu-satunya perubahan lain selain target build adalah beberapa hal kecil untuk membuat RxJS dikompilasi dengan TypeScript dan Closure.

simbol-diamati (ketergantungan RxJS)

https://github.com/lucidsoftware/symbol-observable/tree/closure

RxJS sekarang bergantung pada beberapa kode yang dulunya merupakan bagian dari sumber RxJS dan sekarang menjadi modulnya sendiri. Kami memodifikasi modul itu (yaitu JS) agar kompatibel dengan kompiler Penutupan. Hanya ada dua file, jadi saya melakukannya secara manual.

sabit

https://github.com/lucidsoftware/tsickle/tree/ignore-type-comments

Kami memodifikasi Tsickle dengan dua cara:

  1. Tambahkan opsi --ignoreTypesInComments. Ini mencegah tsickle membuat kesalahan saat menemukan jsdoc di komentar. Ini diperlukan untuk mengkompilasi RxJS yang memiliki banyak komentar jsdoc.
  2. Ubah pathToModuleName agar CLI sama dengan pathToModuleName kita gunakan di ngc. Dengan cara itu modul diberi nama yang sama ketika dijalankan melalui tsickle atau ngc. Ini harus dilakukan di hulu karena pathToModuleName terkadang menghasilkan nama goog.module yang tidak valid.
  • jalankan pengocok pohon untuk menghapus modul ES6 yang tidak dapat dijangkau dari titik masuk, dalam demo kami, kami menunjukkan rollup
  • jalankan bundler untuk mengurangi impor modul menjadi deklarasi dalam satu file; kami menunjukkan system.js
  • down-level ke ES5 - kami menunjukkan ini dengan TypeScript
  • minify untuk mempersingkat nama simbol, kami menggunakan uglify.

Meskipun mungkin tidak dapat menandingi ukuran keluaran akhir dari Closure Compiler, webpack 2 (menggunakan pemuat skrip dan plugin pengoptimalan standar) memberi Anda semua langkah ini.

Saya berpendapat bahwa manfaat dari devs yang sudah menggunakan (berani saya katakan _requiring_) alat seperti webpack di tumpukan mereka, dan karena itu tidak harus menambahkan lebih banyak dependensi (diretas), lebih penting daripada mencukur byte tambahan di muatan akhir.

Akan senang mendengar pikiran Anda!

@jjudd terima kasih banyak telah memposting repo Anda dan catatan ini, ini sangat membantu.

Apakah Anda memiliki ukuran aplikasi yang diperkecil yang dapat Anda bagikan? Mungkin menggunakan kompresi Brotli sehingga kami memiliki perbandingan apel-ke-apel dengan contoh hello world closure-ng2 (yang 26.2k)

@JamesHenry kami setuju bahwa webpack 2 adalah jalan ke depan bagi sebagian besar pengembang. Kompiler penutupan adalah alat ahli dan saya ragu kita dapat membungkusnya dalam paket yang 'berfungsi' untuk pengembang yang belum terbiasa dengan debugging cara yang tidak jelas ADVANCED_OPTIMIZATIONS-nya dapat merusak aplikasi Anda.

@alexeagle Saat ini kami sedang mengupayakan agar ini berfungsi dengan ADVANCED_OPTIMIZATIONS. Ketika kami berhasil, saya akan melanjutkan dan memposting beberapa tolok ukur.

Mengubah masalah tsickle 1 di atas menjadi laporan bug di sana.

kompiler penutupan sekarang tersedia di npm dalam javascript murni: https://www.npmjs.com/package/google-closure-compiler-js

Ingin memberikan pembaruan:

Kami memiliki contoh repo dan editor beta Lucidchart yang bekerja dengan pengoptimalan tingkat lanjut. Kami menjalankan pengujian singkat menggunakan versi kami dengan pengoptimalan sederhana, dan versi kami yang menggunakan pengoptimalan lanjutan akan diluncurkan hari ini atau besok.

Versi Angular yang digunakan dalam contoh repo telah ditingkatkan ke RC5 (HEAD pada Selasa 16 Agustus).

Contoh repo dan wadah Docker yang menyertainya telah diperbarui jika ada yang ingin mencobanya. Berikut tautan ke contoh repo https://github.com/lucidsoftware/closure-typescript-example

Ukuran bundel

Ukuran bundel akhir untuk proyek contoh menggunakan kompilasi lanjutan tercantum di bawah ini. Catatan: contoh repo menyertakan kode dari js -> ts using clutz dan kemudian ts -> js using tsickle. Ini sedikit lebih besar dari sekadar aplikasi hello world sederhana.

Uncompressed: 112K
Brotli quality 10: 29K
Gzip: 34K

Catatan tentang Membuat Ini Bekerja

Berikut adalah catatan tentang apa yang diperlukan agar pengoptimalan tingkat lanjut berfungsi. Jika saya lupa sesuatu, saya akan memberikan tautan ke semua garpu kami, yang memiliki semua komitmen kami.

Contoh repo

File eksternal untuk Zone, Reflect, dan Jasmine disertakan dalam proses build, sehingga panggilan fungsi tersebut tidak diganti namanya.

Untuk mengatasi bug Closure Compiler di mana metode statis hilang, kami memiliki perintah sed yang benar-benar hacky yang kami jalankan pada file Angular js yang dibangun, mengganti semua baris yang menyertakan kata kunci statis dengan baris yang didahului oleh /** @nocollapse */ . Berikut tautan ke bug Penutupan: https://github.com/google/closure-compiler/issues/1776

sudut

Perubahan terbesar yang kami buat pada Angular adalah membuatnya menggunakan output beranotasi Tsickle selama kompilasi. Kami pikir kami melakukan ini terakhir kali, tetapi kami memiliki bug di mana output beranotasi dibuang: D

Ada beberapa tempat yang Angular sebut sebagai fungsi string. Fungsi-fungsi ini dirujuk di tempat lain menggunakan notasi titik. Dengan demikian, beberapa referensi diganti namanya dan yang lainnya tidak. Kami mengubah Angular untuk menggunakan notasi titik di mana-mana untuk fungsi tersebut, sehingga mereka selalu berganti nama.

Kami juga memperbarui Angular/Tsickle untuk tidak membubuhi keterangan pada file .d.ts.

Kami membuat Angular bermain dengan baik dengan ES6, sehingga berfungsi dalam mode tidak dikompilasi. Kami mengubah beberapa tempat di mana .apply digunakan pada konstruktor untuk menggunakan kata kunci baru.

Tickle

Kami memperbaiki bug di tsickle di mana CLI tidak selalu menyertakan semua file sumber selama anotasi. Daftar nama file dari Program TypeScript seharusnya digunakan, sebagai gantinya kami menggunakan daftar nama file yang berbeda.

Tautan ke semua cabang proyek kami untuk membuat ini berfungsi

Sudut: https://github.com/lucidsoftware/angular/tree/closure-bundle
Tsickle: https://github.com/lucidsoftware/tsickle/tree/closure-bundle
RxJS: https://github.com/lucidsoftware/rxjs/tree/closure-hack
simbol-diamati: https://github.com/lucidsoftware/symbol-observable/tree/closure
Clutz: https://github.com/lucidsoftware/clutz

Jadi kami memiliki beberapa contoh cara kerja ini, ditambah kami menggunakan JSCompiler secara internal di Google sehingga kami memiliki banyak aplikasi yang melakukan ini (meskipun menggunakan sistem pembuatan Bazel dan beberapa aturan Bazel yang belum dirilis).

@robwormald @mprobst haruskah kita mencoba mengemas ini dengan cara yang lebih mudah direproduksi untuk pengguna eksternal? Saya rasa kita belum bisa mengklaim kesuksesan dan menyelesaikan masalah ini.

Kompiler penutupan JS terlihat sangat keren. Namun, saya telah melihat masalah di mana proses kehabisan memori saat menargetkan proyek AOT berukuran sedang melalui Rollup. Pernahkah Anda mengalami ini dalam pengujian Anda?

Versi Java tampaknya tidak mengalami masalah ini.

https://github.com/google/closure-compiler-js/issues/23

Aku juga pernah mendengarnya. Kami harus memanggil node dengan
--max-old-space-size=4096 untuk membuat beberapa alat berfungsi di masa lalu.

Pada Sel, 20 Sep 2016 jam 11:27 Torgeir Helgevold [email protected]
menulis:

Kompiler penutupan JS terlihat sangat keren. Namun, saya telah melihat masalah
di mana proses kehabisan memori dengan menargetkan AOT berukuran sedang
proyek. Pernahkah Anda mengalami ini dalam pengujian Anda?

Versi Java tampaknya tidak mengalami masalah ini.

google/penutupan-kompiler-js#23
https://github.com/google/closure-compiler-js/issues/23


Anda menerima ini karena Anda ditugaskan.

Balas email ini secara langsung, lihat di GitHub
https://github.com/angular/angular/issues/8550#issuecomment -248389501
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AAC5I_FDlMdHvHO2YCvypXju9wR8onzuks5qsCWmgaJpZM4IaZIi
.

Saya mencoba max-old-space-size dengan 8000 dan 14000 pada Mac dengan ram 16GB, tetapi saya masih kehabisan memori dalam proyek sampel saya.
Versi Java berfungsi.

wah sepertinya jelek :)
bisakah Anda mengajukan bug di https://github.com/google/closure-compiler/issues

Pada Selasa, 20 Sep 2016 pukul 11:52 Torgeir Helgevold [email protected]
menulis:

Saya mencoba max-old-space-size dengan 8000 dan 14000 pada Mac dengan ram 16GB,
tapi saya masih kehabisan memori dalam proyek sampel saya.
Versi Java berfungsi.


Anda menerima ini karena Anda ditugaskan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/angular/angular/issues/8550#issuecomment -248396986,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AAC5I25uOXJ-Pt8a9WzQQUO1zRx4j1YUks5qsCthgaJpZM4IaZIi
.

Yup, saya sudah memiliki masalah aktif di sana
https://github.com/google/closure-compiler-js/issues/23

@thelgevold yang mungkin terkait dengan bug TypeScript...coba buat dengan Typescript nightly build... (sayangnya, ngc tidak mendukung TS 2.1, jadi Anda harus bolak-balik antara itu dan 2.0.2).

@qdouble Hm menarik.. Apakah Anda mengatakan itu mungkin terkait dengan JavaScript yang diproduksi oleh TS 2.0.2?
Karena pada saat kode saya masuk ke tanah compiler rollup/closure, kode tersebut sudah dalam format JS.

@thelgevold ah, dengan ada bug yang dapat menghentikan pembuatan kode Anda jika Anda memiliki banyak kontrol formulir dan hal-hal dengan 2.0.2...jika file Anda sudah JS sebelum Anda menemukan bug, maka itu mungkin sesuatu lain ... tapi saya kira Anda bisa mencoba menggunakan TypeScript setiap malam untuk mengubahnya menjadi JS dan melihat apakah ada bedanya.

Hai Guys, semua ini terdengar sangat menarik dan kami sedang mencari ini untuk meningkatkan kinerja situs web kami. Apa status saat ini dari pembuatan sudut khusus yang Anda buat. Apakah Anda akan membuat build untuk Angular v 2.0.0 ?

Saya akan mencoba memperbarui ini untuk ngEurope ...

Pada Jum, 7 Okt 2016, 1:48 Gerard A Lamusse [email protected]
menulis:

Hai Teman-teman, semua ini terdengar sangat menarik dan kami sedang menyelidiki ini
untuk meningkatkan kinerja situs web kami. Apa status saat ini
bangunan sudut khusus yang Anda buat. Apakah Anda akan membuat bangunan untuk
Sudut v 2.0.0 ?


Anda menerima ini karena Anda ditugaskan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/angular/angular/issues/8550#issuecomment -252186017,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AAC5I1TZZEGiuBu8zJe2BtYEzilr-VPHks5qxgdTgaJpZM4IaZIi
.

Hai @ u12206050 , saya mengambil celah untuk meningkatkan ini ke Angular 2.0.1 beberapa akhir pekan yang lalu. Saya mendapatkannya sekitar 2/3 perjalanan ke sana. Contoh berfungsi dengan pengoptimalan sederhana, tetapi tidak dengan pengoptimalan lanjutan.

Saya tidak lagi secara aktif mengerjakan ini, tetapi tim lain di sini di Lucid yang saya ajak bicara hari ini ingin segera mengatasinya. Jika saya mendapatkan akhir pekan gratis lagi, saya ingin menyelesaikannya dengan memindahkannya ke 2.0.1. Jadi siapa pun yang mendapatkannya lebih dulu.

Sementara itu, jika Anda ingin sedikit lebih banyak info tentang ini, Anda dapat melihat posting blog yang kami tulis di https://www.lucidchart.com/techblog/2016/09/26/improving-angular-2 -load-kali/. Saya harap itu membantu.

Jika Anda mengalami masalah dan ingin melontarkan beberapa pertanyaan dari saya, silakan. Ini mungkin akan menjadi sedikit petualangan untuk menghubungkannya ke sistem build Anda. Semoga berhasil! :)

ada update dari ngeurope?

setelah menyadari bahwa goyangan pohon webpack2 tidak _not_ pohon mengguncang ekspor ulang, dan sudut memerlukan impor dari ekspor ulang, ini cukup mengecewakan

pikiran saya yang jelas adalah oh, tsickle! saya pikir saya akan mem-pipe ngc -> tsickle -> webpack -> gcc advanced (bukan hanya ngc -> webpack -> gcc simple) hanya untuk mewujudkan tsickle converts import/require to goog.require, jadi tidak ada webpack yang mudah (atau bundler non-google lainnya, sungguh) integrasi di sini saat ini

inti sudut + formulir + router + browser platform + umum mengambil ~30% dari bundel utama kami dengan ngc + webpack2. itu ~ 100kb diperkecil dan di-gzip, aduh

Saya ingin melihat tsickle bekerja dengan webpack, karena jelas bahkan tim angular cli menganggap webpack adalah pilihan yang bagus. Saya terbuka untuk saran yang satu ini. Kalau tidak, saya akan melihat lebih dalam pada karya @jjudd , tetapi saya tidak ingin membuang waktu jika solusi resmi ada di depan mata (mungkin dengan @ngtools/webpack ?)

https://docs.google.com/presentation/d/1SaHtM1_mpBZuN74wxAJSPQRB0sPbWRSJPQZsxx4_BpE/preview

Umpan Twitter mereka tampaknya memiliki beberapa konten.

Dapatkan Outlook untuk Androidhttps://aka.ms/ghei36

Pada Jumat, 28 Okt 2016 pukul 12:52 +0200, "Steve Sewell" < [email protected] [email protected] > menulis:

ada update dari ngeurope?

setelah menyadari bahwa goyangan pohon webpack tidak mengekspor ulang pohon, dan angular memerlukan impor dari reekspor, ini cukup mengecewakan

pikiran saya yang jelas adalah oh, tsickle! pikir saya akan menyalurkan ngc -> tsickle -> webpack (bukan hanya ngc -> webpack) hanya untuk menyadari tsickle mengonversi impor/memerlukan goog.require, jadi tidak ada integrasi webpack yang mudah di sini saat ini

inti sudut + formulir + router + browser platform + umum mengambil ~30% dari bundel utama kami dengan webpack2. itu ~ 100kb diperkecil dan di-gzip, aduh

terbuka untuk saran yang satu ini. jika tidak, saya akan melihat lebih dalam pada karya @j juddhttps://github.com/jjudd , tetapi saya tidak ingin membuang waktu jika solusi resmi ada di depan mata

Anda menerima ini karena Anda berlangganan utas ini.
Balas email ini secara langsung, lihat di Gi tHubhttps://github.com/angular/angular/issues/8550#issuecomment -256791543, atau matikan suara saat membacahttps://github.com/notifications/unsubscribe-auth/AAABN_sAdZ1RDtPIk1Zt4QJr7oq4SqbIgaZ4QJr7oUdg723ks

Pembaruan: kami melakukan diskusi serius di ngEurope, dengan @robwormald dan @hansl dan lainnya.
@pkozlowski-opensource skeptis bahwa komunitas eksternal akan merangkul rantai alat baru, daripada meningkatkan yang sudah ada.
Jadi saya pikir langkah pertama adalah angular-cli akan bekerja untuk meningkatkan webpack untuk melakukan pekerjaan yang lebih baik.

Pada saat yang sama, saya masih ingin memiliki proyek benih kanonik yang menunjukkan menggunakan kompiler penutupan. @steve8708 Saya tidak yakin apa yang Anda maksud tentang goog.require melanggar bundler, karena kompiler penutupan _is_ bundler. Tidak ada pernyataan goog.require yang muncul di outputnya. @jjudd apakah ada orang di Lucidchart yang tertarik untuk berkolaborasi membuka gulungan peretasan kami dan memungkinkan komunitas eksternal untuk mereproduksi aplikasi 26k ng2?

@alexeagle saat ini kami menggunakan webpack untuk banyak hal - bundling, code splitting, preprocessing, linting, hashing, gzipping, dan banyak lagi, mirip dengan apa yang dilakukan oleh angular CLI dan banyak open source populer yang dilakukan oleh angular + webpack starter

Saya sangat ingin menyimpan webpack untuk semua yang dilakukannya (terutama karena kami dapat memanfaatkan banyak plugin komunitas untuk membuat beberapa tugas kompleks menjadi sederhana dan dapat dikonfigurasi) daripada mengimplementasikan kembali semua yang kami lakukan saat ini (misalnya dengan gcc + tegukan).

Saya ingin hanya dapat menukar tsickle dengan tsc untuk menambahkan anotasi jsdoc selama transpilasi yang diperlukan untuk minifikasi mode lanjutan (saat ini kami menggunakan plugin webpack

Sangat menghargai pembaruan Anda, dan sangat ingin melacak kemajuan yang dibuat oleh tim angular-cli dengan rantai alat webpack mereka!

@ steve8708 alat mana yang Anda inginkan untuk dapat beroperasi pada kode ES6 goog-modul beranotasi penutupan sebelum Anda menyerahkannya ke plugin gcc Anda?

@alexeagle Terima kasih atas pembaruannya. Saya akan berbicara dengan orang-orang di sini dan melihat minat apa yang ada.

Sebagai contoh, apakah contoh repo yang kami buat untuk ini seperti yang Anda pikirkan? https://github.com/lucidsoftware/closure-typescript-example

Ini terdengar seperti hal yang hebat untuk CLI. Ini membungkus Webpack dan banyak plugin lain yang sudah ada dan yang baru. Akan luar biasa jika CLI dapat menggunakan kompiler Penutupan di bawah tenda alih-alih uglifier. Ini diabstraksikan dari pengguna dengan cara apa pun.

@jjudd ya itu yang terbaik yang kami miliki saat ini, tetapi disematkan ke versi ng2 (lama) tertentu dan dependensinya, bukan?
Kami juga perlu menjelaskan cara menggunakan eksternal sehingga Anda dapat memiliki dependensi yang tidak kompatibel dengan penutupan.

Benar. Kami secara aktif bekerja untuk pindah ke versi terbaru Angular sekarang. Mudah-mudahan harus segera dilakukan. Saya akan memposting pembaruan ketika kami menyelesaikannya.

@alexeagle sejujurnya webpack dibangun di sekitar modul commonjs/AMD/es6, jadi banyak fitur tidak berfungsi dengan baik (jika ada) jika modul tidak dalam format ini. beberapa yang cepat muncul di pikiran

  • pemuat url. Kami mengimpor aset dalam TypeScript (atau html) sebagai require('./asset.png') dan hanya dengan melakukan itu webpack menangani penyalinan, hashing, kompresi, dan pemuatan gambar jika diperlukan
  • pemisahan kode otomatis (misalnya menggunakan pemuat router angular2 seperti ini ) dan System.import lainnya di seluruh kode Anda untuk memudahkan pemuatan lambat konten apa pun
  • berbagai pemuat lainnya - misalnya kami menggunakan pemuat impor untuk bahan angular2 karena bahan saat ini memiliki referensi jendela untuk menemukan pembantu TypeScript seperti __extends jadi kami harus menulis ulang itu menjadi global ( contoh ). Bahkan hal-hal seperti ini benar-benar hanya bekerja paling elegan (atau, kurang hackily) dengan webpack ketika Anda menangani bundling Anda seperti yang dimaksudkan
  • berbagai plugin lain - misalnya plugin html akan menghasilkan index.html dasar kami setelah menjalankan build/bundel lengkap karena dari melakukan itu ia mengetahui entri file javascript apa yang telah dibuat (termasuk path dan hash lengkapnya) dan menghasilkan root kami templat html dengan url skrip yang benar dengan hash, dll dengan tepat

terus terang saya telah menerapkan hal-hal yang sama (atau serupa) ini berkali-kali dengan apa pun mulai dari make/jakefiles, grunt, gulp, dll, tetapi saya tidak pernah memiliki pengalaman pembuatan perkakas yang mulus dan solid seperti menggunakan webpack (terutama untuk jumlah kode yang harus Anda tulis dan pertahankan untuk build Anda), jadi saya ingin melihat tsickle memungkinkan format modul yang lebih umum (di open source land) yang dapat diintegrasikan dengan alat seperti webpack

tl; dr, webpack hanya bergantung pada penggunaan commonjs, amd, atau es impor, dan mereka memiliki sistem pemuat dan plugin yang cukup mengagumkan yang dapat melakukan banyak hal hebat selama webpack dapat memahami modul Anda di salah satu javascript umum format, yang sayangnya tidak menyertakan modul goog.*

lmk jika ada hal lain yang dapat saya bantu untuk menjawab di sini atau bahkan kontribusi kode yang dapat saya buat untuk mencoba dan menggunakan tsickle dengan alat lain seperti webpack. Saya sangat bersemangat untuk menjalankan ini sebisa mungkin!

dan terimakasih!

@steve8708 alasan kami saat ini menyerahkan sintaks goog.module ke kompiler penutup adalah karena ia memiliki bug/fitur yang hilang untuk modul ES6. Terakhir kali saya memeriksa mereka tidak memiliki dukungan untuk export * misalnya. Tim telah mengindikasikan bahwa mereka tidak tertarik untuk mendukung modul ES6 karena mereka tidak bekerja secara native di sebagian besar browser.

Jika Anda perlu mengambil kode TS melalui langkah-langkah ini sebelum bundling/treeshaking/minifying dengan kompilator penutupan, kita harus memperbaiki semua dukungan modul ES6 di kompilator penutupan. Saya tidak berpikir ada orang yang memiliki ini sekarang.

Senang tahu, terima kasih @alexeagle

Saya baru saja menemukan beberapa dokumen yang menyarankan gcc mendukung modul commonjs juga. Saya akan mengujinya sedikit dan mencari tahu apakah mungkin itu lebih diimplementasikan atau kurang buggy daripada modul es6 saat ini.

Jika demikian saya akan melihat-lihat dan melihat apakah mungkin untuk membuat konversi modul goog opsional di tsickle dan jika ada cara untuk mendapatkan manfaat dari minifikasi lanjutan gcc dengan anotasi tipe jsdoc yang ditarik dari TypeScript tetapi dengan modul commonjs atau es6. Saya pikir itu pasti akan menyenangkan bagi saya dan seluruh komunitas!

Terima kasih sekali lagi atas infonya, sangat membantu!

Dibahas lagi di sini secara langsung ... jika satu-satunya bug dengan kompiler penutupan adalah export * , kita dapat dengan mudah membuat opsi tsickle untuk meratakannya menjadi export {symbol1, symbol2, ...} pada langkah pasca-pemrosesan. Kami juga dapat menambahkan anotasi JSDoc (dan menyertakan ini dalam distribusi ES6 kami).

@alexeagle itu akan luar biasa untuk mendapatkan anotasi jsdoc di distribusi ES6!

Dari beberapa pengujian hari ini saya menemukan bahwa tsickle sebenarnya sudah mengonversi format export * ke export { a, b, c } untuk modul es6, jadi itu adalah berita bagus!

Lebih baik lagi, saya mengkloning tsickle secara lokal dan mengomentari konversi ke modul goog dan bisa membuat tsickle + gcc maju bekerja dengan sempurna dengan build webpack kami seperti yang diharapkan!

Ini membuat bundel utama kami turun 15% lebih kecil, dan itu belum ada anotasi di @angular/* . Ini terlihat sangat menarik dan menjanjikan

Selain itu, dari penyelidikan yang saya lakukan hari ini, saya melihat bahwa ketika Anda melakukan transpile dengan modul es6 tidak ada yang diganti dengan goog.require, hanya panggilan biasa yang memerlukan. Ini benar-benar berita bagus karena ini berarti proyek dapat menggunakan tsickle apa adanya hari ini dengan alat yang mendukung esmodul seperti rollup dan webpack2 selama mereka mengganti panggilan _all_ commonjs require dengan impor es6.

Untungnya ts 2.0 membuat ini lebih mudah dengan declare module '*' , menghilangkan kebutuhan untuk menggunakan require untuk kode non-typescript

Saya sangat ingin melihat berapa banyak lagi yang dapat kita hemat ketika distribusi @angular/* es memiliki anotasi jenis dari tsickle juga! Terutama sementara webpack2 masih tidak tree shake mengekspor kembali penghematan dari menghapus banyak kode inti/umum/etc sudut yang dibundel tetapi tidak digunakan di sini bisa sangat besar!

Memutuskan untuk mencoba ini juga.

Kloning terbaru tsickle , tetapi masih mengalami beberapa masalah:

Bagi saya ada dua kategori kesalahan:
1) export * kesalahan kompilasi dari penutupan - Kesalahan yang sama dijelaskan oleh orang lain di atas...

node_modules/@angular/common/src/location.js:9 (JSC_CANNOT_CONVERT_YET)
ES6 transpilation of ''Wildcard export'' is not yet implemented.
export * from './location/location_strategy';

Apakah solusinya adalah menerbitkan sumber Angular tanpa export * sini?

2) kata kunci penutupan dalam komentar kode sumber sudut menyebabkan kesalahan kompilasi

node_modules/@angular/core/src/metadata/ng_module.js:15 (JSC_PARSE_ERROR)
Parse error. illegal use of unknown JSDoc tag "stable"; ignoring it
 * <strong i="16">@stable</strong>

Saya melakukan bundling saya menggunakan rollup dengan plugin kompiler penutupan. Saya menggunakan rxjs-es alih-alih rxjs karena saya mengalami beberapa masalah dengan konversi commonJS.

Saya ingin tahu tentang rencana tsickle vs nGC. Dari apa yang saya dapat memberitahu Anda sekarang harus menjalankannya bersama-sama ngc -> tsickle . Apakah ada rencana untuk menggabungkannya untuk mengurangi ini menjadi satu langkah?

Saya sangat tertarik untuk melihat seberapa jauh ini bisa berjalan. Saya kira itu benar-benar bermuara pada struktur kode, tetapi mungkin ada potensi pengurangan kode yang sangat besar. Melakukan POC non sudut dengan penutupan di sini: http://www.syntaxsuccess.com/viewarticle/tree-shaking-in-javascript

Dari apa yang saya tahu, Closure memiliki potensi yang sangat besar dalam hal pengoptimalan kode. Sampel saya mengurangi beberapa kelas menjadi satu liner, tetapi masih belum jelas seberapa baik ini akan diterjemahkan ke aplikasi Angular. Berharap meskipun!

Sekarang PR masuk sehingga Anda dapat menggunakan

    "@angular/common": "angular/common-builds",
    "@angular/compiler": "angular/compiler-builds",
    "@angular/compiler-cli": "angular/compiler-cli-builds",
    "@angular/core": "angular/core-builds",
    "@angular/platform-browser": "angular/platform-browser-builds",
    "@angular/platform-server": "angular/platform-server-builds",
    "@angular/tsc-wrapped": "angular/tsc-wrapped-builds",

dan tidak ada export * dan semua kode memiliki JSDoc untuk penutupan.

@thelgevold @steve8708 mau coba lagi?
Saya akan menyelidiki https://github.com/cramforce/splittable dengan @robwormald

@alexeagle luar biasa!

Saya mencoba ini sekarang dan ketika menggunakan versi -builds saya mendapatkan kesalahan ini dari ngc:

Error: Metadata version mismatch for module [path to a project .ts file], found version 1, expected 2

Saya tidak sepenuhnya yakin dengan maksud pesan ini, apakah Anda memiliki pemikiran tentang cara mengatasinya?

@tbosch membuat perubahan setelah saya. Dia memperbarui kolektor metadata, dan sekarang Angular mengharapkan untuk membaca metadata versi 2. Namun, ketika metadata versi 1 ditemukan, itu harus ditingkatkan di tempat. Sepertinya bug, saya akan membiarkan Tobias mengkonfirmasi ...

satu hal untuk dicoba, apakah Anda memiliki file .metadata.json dihasilkan dalam proyek Anda? coba bersihkan dan coba lagi?

@alexeagle Saya telah bermain-main dengan ini sedikit, tetapi saya mengalami masalah kompilasi dengan impor bernama seperti @angular/core

Saya pikir saya telah membaca di suatu tempat bahwa penutupan saat ini tidak menangani impor bernama. Jika saya melewati dan mengonversi impor ke jalur absolut, sepertinya itu memperbaiki kesalahan kompilasi. Ada terlalu banyak kesalahan untuk memperbaiki semuanya secara manual.

Mengonversi referensi seperti @angular/core ke ../../core/index dalam kode sudut/aplikasi tampaknya berfungsi....

Berikut adalah contoh kesalahan:

node_modules/@angular/common/src/pipes/slice_pipe.js:8: ERROR - required "module$$angular$core" namespace never provided
import { Pipe } from '@angular/core';

Mencoba repo Anda juga dan sepertinya hal yang sama juga terjadi di sana.

Saya ingin tahu apakah sesuatu dapat ditambahkan ke penutupan untuk menyelesaikan impor bernama seperti @angular/core ke jalur fisik yang sesuai.

@thelgevold saya menemukan itu juga. Masalahnya adalah node_modules/@angular/core/index.js terdaftar sebagai module$$angular$core$index . Karena semantik ESModule tidak terdefinisi, tidak ada spesifikasi yang mengatakan bahwa "foo/index.js" dapat diimpor dengan "foo". Karena CommonJS mengizinkan ini, rollup dan systemjs mendukungnya, tetapi tidak ditentukan. Oleh karena itu tanggapan dari tim penutupan adalah bahwa ini adalah masalah pemuat modul, dan mereka tidak mendukung ini. https://github.com/google/closure-compiler/issues/1710 (dan juga mengobrol dengan @MatrixFrog)
Saya menduga bahwa mengubah import {} from '@angular/core' menjadi from '@angular/core/index' memecahkan ini juga, meskipun itu bukan solusi yang berguna karena kode pengguna harus melakukan ini juga.

Saya membayangkan bahwa mengonversi sintaks modul ke commonjs adalah pendekatan lain, meskipun menambahkan alat untuk melakukan ini membuat build jauh lebih sulit bagi siapa pun untuk mereproduksi secara andal.

Ya, sayangnya itu masalah yang sama yang saya tutup sekarang dan tidak yakin apakah benar-benar ada solusi langsung :(

Kita mungkin harus menyerah pada tsickle lagi karena meskipun untuk impor kita sendiri, kita menambahkan /index ke akhir jalur, mengimpor dalam perpustakaan (misalnya @angular/platform-browser mengimpor dari @angular/core , dll) juga tidak akan memiliki jalur yang benar untuk dukungan gcc

Saya akan memikirkannya lebih lanjut tetapi sementara itu sepertinya gcc advanced mungkin bukan kemungkinan untuk pengguna umum dalam waktu dekat kecuali ada orang lain yang punya ide lain

Apakah mungkin untuk memiliki nGC keluaran JS dengan notasi tangan panjang untuk impor untuk melindungi pengguna dari menggunakannya dalam kode TypeScript mereka sendiri.

Kemudian sebagai bagian dari rilis A2 lakukan hal yang sama untuk kode sudut? Pada dasarnya terbitkan versi dengan impor bentuk panjang?

Itu ide yang bagus - secara internal kami memiliki konversi tsickle ke goog.module
sintaks, jadi kita harus dapat menggunakan konversi yang berbeda untuk memberikan eksplisit
impor dari /index.js

Pada Rabu, 30 Nov 2016 pukul 11:35 Torgeir Helgevold [email protected]
menulis:

Apakah mungkin untuk memiliki nGC keluaran JS dengan notasi tangan panjang untuk
impor untuk melindungi pengguna dari menggunakannya dalam kode TypeScript mereka sendiri.

Kemudian sebagai bagian dari rilis A2 lakukan hal yang sama untuk kode sudut? Pada dasarnya
mempublikasikan versi dengan impor bentuk panjang?


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/angular/angular/issues/8550#issuecomment-263971981 ,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AAC5Iy255poYsJTn8ZdBAgVZWbagFwzAks5rDdARgaJpZM4IaZIi
.

Ah itu ide yang luar biasa!

Saya bertanya-tanya, apakah/bisakah itu juga mencakup perpustakaan non-sudut? Yaitu apakah tsickle mem-parsing modul non TypeScript/angular sehingga juga dapat mengonversi import { foo } from 'other-lib' menjadi import { foo } from 'other-lib/index' jika diperlukan?

Demikian juga, satu elemen resolusi modul lainnya yang digunakan beberapa pemuat utama dalam meniru resolusi modul simpul jika other-lib memiliki bidang main dalam package.json mereka, katakanlah menunjuk ke main.js , apakah itu juga (secara teori, jika diterapkan) dapat mengonversi impor dari paket itu menjadi import { foo } from 'other-lib/main' ?

Ini sebagian besar hanya tergantung pada seberapa dalam tsickle melintasi kode Anda saat dijalankan dari baris perintah. Menurut saya jika tidak melintasi semua masalah resolusi modul ini masih akan menjadi masalah bagi lib pihak ketiga lainnya yang mungkin digunakan orang

Jika ini semua mungkin, itu akan sangat luar biasa dan berarti kemampuan untuk menggunakan tsickle dapat dimasukkan kembali ke radar kami yang akan luar biasa!

Secara umum, hanya perpustakaan yang dipelihara dengan hati-hati yang dapat dioptimalkan dengan penutupan, itu merusak yang lain. Jadi penggunaan tipikalnya adalah

  • Penutupan kompilasi kode Anda, Angular dan deps-nya (terutama rxjs) menjadi satu atau lebih bundel
  • berikan file penutupan eksternal untuk perpustakaan lain yang Anda perlukan untuk berinteraksi ke/dari bundel penutupan
  • Muat bundel perpustakaan lain menggunakan distribusi js yang diperkecil dalam tag skrip terpisah

Ini juga yang kami lakukan di Google. Jadi seharusnya tidak perlu menjalankan tsickle, cukup ngc.

Ah begitu, terima kasih telah memperhatikan @alexeagle!

Kalau-kalau kita beruntung, saya meminta TS untuk melakukan ini:
https://github.com/Microsoft/TypeScript/issues/12597
Sementara itu, mungkin kita bisa melakukannya di tsickle, saya sedang mencobanya sekarang. Inilah masalah untuk itu:
https://github.com/angular/tsickle/issues/288

Pembaruan: masalah tsickle itu teratasi. Membangun sudut dari cabang ini:
https://github.com/alexeagle/angular/tree/closure
Saya sekarang menghasilkan distro ES6 dengan semua import {} from '@angular/core/index' eksplisit

Masalah selanjutnya adalah kita membutuhkan distro rxjs yang kompatibel. @jayphelps telah melihat kisah pengemasan rxjs, yang telah ditunda hingga setelah 5.0.0-final. Kami mungkin masih membutuhkan distro eksperimental khusus rxjs untuk sementara waktu.

Ini pekerjaan yang sangat bagus @alexeagle

Saya memotong proyek Anda dan menambahkan beberapa sampel "lanjutan". Kabar baiknya adalah bahwa bagian kompilator penutupan benar-benar transparan dan tidak menghalangi kami sama sekali.

Saya menambahkan Dynamic Forms (Reactive Forms) dan sampel Recursive Treeview dan semuanya bekerja dengan baik.

Hanya tweak yang harus saya lakukan adalah beberapa tambahan pada konfigurasi kompiler penutupan untuk mendapatkan akses ke arahan Formulir dan ngIF, ngFor dll

Garpu:
https://github.com/thelgevold/closure-compiler-angular-bundling/tree/add-samples

Saya juga menyebarkan versi sampel di sini:
http://www.syntaxsuccess.com/a2-closure/

Luar biasa, terima kasih telah mengambil ini dengan sangat cepat @thelgevold
Untuk orang lain yang menonton utas: Saya memperbarui contoh repo hari ini, kami memiliki penyiapan kompiler penutupan yang berfungsi lagi, dan sekarang tidak ada skrip polyfills terpisah. Zone.js dibangun ke dalam bundel penutupan.

Saya pikir langkah selanjutnya adalah mencoba ini dalam beberapa skenario dunia nyata. Ionic juga melakukan ini. Kemudian sekitar bulan depan kami akan mencoba untuk mendapatkan tim Penyusun Penutupan di sebuah ruangan bersama kami dan menyelesaikan masalah kegunaan terbesar. Sementara itu @mhevery membantu menunjukkan kode yang dipertahankan tetapi seharusnya

Pertanyaan:
Saya melihat termasuk lib pihak ketiga saat melakukan kompilasi penutupan.

Tantangan di sana untuk menormalkan jalur impor menggunakan kompiler TypeScript adalah bahwa lib pihak ketiga kemungkinan besar diterbitkan hanya dengan sumber JS.
Ini membuatnya lebih rumit untuk menormalkan impor barel tanpa index di akhir jalur.

Apakah ada diskusi tentang membalikkan rekomendasi untuk mendukung node moduleResolution ?

Saya pikir tidak akan terlalu buruk untuk menggunakan moduleResolution klasik dan selalu menyertakan index di jalur impor.

Saya menduga mungkin ada penalti kinerja selama kompilasi dalam proyek-proyek besar. Terutama jika kompiler harus melakukan pencarian untuk setiap impor untuk mendeteksi apakah harus menulis ulang agar kompatibel dengan impor kompiler penutupan.

Karena itu, kompilasi kompiler penutupan (ADVANCED_OPTIMIZATION) secara terpisah biasanya merupakan langkah yang memakan waktu. Mungkin waktu tambahan tidak terlalu terlihat?

Pikiran?

Saya setuju, waktu kompilasi kami dipengaruhi oleh pencarian indeks yang saya tambahkan
tsickle - untuk setiap impor kita harus melakukan moduleResolution lagi.
Secara internal kami mengonversi modul commonJS ke goog.module/goog.require - I
bayangkan akan terlalu lambat bagi kita untuk melakukan langkah ekstra di dev
mode.

Kita dapat mendiskusikan pertanyaan tentang mendukung resolusi gaya node_module selanjutnya
minggu, kami memiliki hari hackathon dengan tim Closure Compiler.

Yang mengatakan, bahkan jika kompiler penutupan memahami sintaks modul untuk
perpustakaan pihak ketiga, kode tipikal rusak oleh ADVANCED_OPTIMIZATIONS,
sebagian besar karena sintaks akses properti (sintaks titik diganti namanya, persegi
sintaks braket tidak). Jadi saya pikir perpustakaan pihak ketiga harus tetap
di luar kompilasi penutupan. Secara internal, kami hanya mengambil -min.js mereka
distro dan gabungkan ke ujung penutupan yang dibundel JS.

Kami telah membayangkan akan sangat bagus jika beberapa file atau paket dapat memilih keluar
dari optimasi penutupan. Salah satu cara praktis yang bisa saya bayangkan melakukan ini adalah
untuk menambahkan "closureCompilerCompatible: true" ke package.json perpustakaan
yang telah memverifikasi kompatibilitas pengoptimalan lanjutan penutupan mereka. Kemudian sebuah bangunan
alat dapat memilih perpustakaan yang dikompilasi ke dalam bundel, vs.
yang diselesaikan menggunakan ekstern penutupan.

Pada Kam, 12 Jan 2017 pukul 18:59 Torgeir Helgevold [email protected]
menulis:

Pertanyaan:
Saya melihat termasuk lib pihak ketiga saat melakukan kompilasi penutupan.

Tantangan di sana untuk menormalkan jalur impor menggunakan TypeScript
compiler adalah bahwa lib pihak ketiga kemungkinan besar diterbitkan hanya dengan JS
sumber.
Ini membuatnya lebih rumit untuk menormalkan impor barel tanpa indeks
di ujung jalan.

Apakah ada diskusi tentang membalikkan rekomendasi ke
mendukung node moduleResolution.

Saya pikir tidak akan terlalu buruk untuk menggunakan klasik
moduleResolution dan selalu sertakan indeks di jalur impor.

Saya menduga mungkin ada penalti kinerja selama kompilasi di
proyek besar. Terutama jika kompiler harus melakukan pencarian untuk setiap
impor untuk mendeteksi apakah harus menulis ulang agar kompatibel dengan penutupan
impor kompiler.

Yang mengatakan, kompilasi kompiler penutupan (ADVANCED_OPTIMIZATION) di
isolasi biasanya merupakan langkah yang memakan waktu. Mungkin waktu tambahannya tidak
semua yang terlihat?

Pikiran?


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/angular/angular/issues/8550#issuecomment-272348788 ,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AAC5I49thgsBW1VGc3oyFVvEchxI2D6Zks5rRuivgaJpZM4IaZIi
.

Terima kasih balasannya. Saya senang mengikuti perkembangan proyek ini.

Ya, saya pasti melihat beberapa tantangan ketika berintegrasi dengan lib pihak ketiga - terutama yang ditulis tanpa kompiler penutup. Saya suka proposal untuk memasukkan semacam flag kompatibilitas kompiler penutupan.

Pengalaman saya dengan kompiler penutupan adalah bahwa ia berpotensi menawarkan pengoptimalan yang luar biasa, tetapi memaksakan beberapa konvensi pada Anda. Saya masih melihatnya sebagai alat ahli, tetapi saya ingin tahu apakah ada cara di ngc untuk menyederhanakan berbagai hal dengan membuat kode yang sesuai dengan beberapa konvensi ini. Externs akan kasus per kasus berdasarkan konstanta perpustakaan tertentu, tetapi kasus penggunaan umum lainnya adalah panggilan http.

Saat berhadapan dengan panggilan http ....
Cara saya melihatnya, kita harus "kurung persegi" melindungi beberapa properti model kita untuk mencegah kompiler Penutupan memperpendek nama properti dalam referensi ke objek payload. Jika tidak, versi yang dipersingkat tidak akan lagi cocok dengan nilai runtime dari muatan http yang sebenarnya.

Saya umumnya melindungi properti sesuai kebutuhan dengan menggunakan notasi kurung siku {'firstName': 'Joe'} .
Pendekatan ini bekerja dengan baik untuk saya, tetapi beberapa orang mungkin tidak suka bahwa kita harus menulis kode seperti ini. Mungkin dekorator atau sejenisnya bisa menjadi isyarat untuk ngc untuk menghasilkan JS dalam format ini dalam kasus di mana nama properti harus dilindungi?

Dalam tsickle kami telah membuatnya begitu
mendeklarasikan antarmuka Pengguna { firstName: string; }
(dengan "deklarasi") menginformasikan kompiler Penutupan untuk tidak merusak penggunaan
bidang 'nama depan'.

Ini samar-samar konsisten dengan cara kerjanya di TS, di mana "deklarasikan"
digunakan untuk mewakili jenis hal yang berada di luar kode TS Anda.

@evmar Itu luar biasa! Terima kasih telah memberitahuku tentang ini.

Saya telah memperbarui garpu saya untuk menggunakan snapshot baru dari repo sudut. https://github.com/thelgevold/closure-compiler-angular-bundling

Sejauh yang saya tahu satu-satunya ketergantungan non-standar pada saat ini adalah custom rxjs build.

Untuk mencoba skenario yang lebih realistis, saya mulai mem-porting komponen demo saya ke garpu kompilator penutupan.

Berikut adalah dua build jika Anda tertarik dengan perbandingan antara rollup build standar dan build compiler penutupan komponen saya:

http://www.syntaxsuccess.com/closure-compiler-demo
http://www.syntaxsuccess.com/rollup-compare-demo

Saya tidak dikenal dengan keterampilan css, jadi demonya benar-benar tidak memiliki gaya, tetapi menarik untuk membandingkan dua ukuran wrt build:

Berikut adalah statistik ukuran:
Gulungan: 130k
Penutupan: 79.2k

Dalam build Penutupan, Anda juga dapat melewati core-js shim jika browser Anda mendukung es6 (Chrome, Edge, dll). Rollup build membutuhkan shim terlepas dari dukungan es6 di browser. Ini adalah efek samping dari tidak mengguncang dekorator.

Saya akan memperluas demo ini dari waktu ke waktu. Saat ini menggunakan The Router, Forms dan ReactiveForms.

Sejauh ini relatif mudah untuk membuat kode terhadap kompiler penutupan. Satu-satunya waktu saya harus membuat tweak khusus untuk membuatnya bekerja adalah di demo "sortable grid". Kisi melakukan pencarian dinamis dengan nama kolom yang tidak kompatibel dengan mangling nama properti.

Seperti yang telah dibahas sebelumnya, mungkin untuk mencegah kerusakan properti dengan menggunakan antarmuka dengan declare
mantan:

export declare interface Person {
  firstName: string;
  lastName: string;
  age: number;
}

Ini mungkin menjadi masalah di pihak saya, tetapi antarmuka dengan declare tampaknya tidak meninggalkan isyarat untuk kompiler Penutupan yang akan mencegah mangling. Sebagai solusinya, saya telah "kurung persegi" melindungi nama properti. Ini berfungsi dengan baik, tetapi akan lebih baik untuk menyelesaikannya dengan antarmuka saja.

Berikut adalah statistik ukuran:
Gulungan: 130k
Penutupan: 79.2k

Aku terkejut. Setelah menggunakan kompilator penutupan dalam mode lanjutan selama bertahun-tahun, saya akan berpikir perbedaannya akan lebih besar ... Tapi saya kira Angular adalah kerangka kerja yang besar.

Dalam kasus saya, pemisahan antara Angular vs Application code / rxjs kira-kira 70/30.

Berikut adalah tampilan penjelajah peta sumber ke dalam bundel: http://www.syntaxsuccess.com/closure-compiler-demo-map

@b-strauss Misko percaya bahwa sekitar setengah dari berat Angular harus diguncang, tetapi Penutupan tidak memahami beberapa pola pengkodean kami bebas efek samping sehingga kami kehilangan beberapa pengoptimalan. Harapkan bahwa jumlah penutupan turun mungkin 20k atau lebih dari waktu ke waktu relatif terhadap alternatif.

@thelgevold secara teknis Angular seharusnya hanya bergantung pada janji dan koleksi ES6 (mungkin dapat diubah tapi saya pikir itu opsional), tidak semua es6-shim. https://github.com/angular/angular/blob/master/modules/tsconfig.json#L22

@thelgevold ya, kita harus menghubungkan penutupan eksternal, seharusnya tidak sulit (setelah kita mendapatkan beberapa perubahan tsickle terkait dengan peningkatan TS 2.1 yang di-rebase dan digabungkan)
https://github.com/angular/angular/issues/14325

@alexeagle Apakah akan lebih dioptimalkan untuk entah bagaimana mengubah ke braket persegi yang setara untuk kasus ini?

Tidak yakin apakah itu akan berhasil, tetapi pemahaman saya adalah bahwa externs harus dibatasi pada referensi kerangka kerja eksternal seperti variabel global "dimiliki" oleh kerangka kerja lain.

Saya pikir Penutupan dapat melakukan pekerjaan yang lebih baik dalam mengoptimalkan alat peraga yang dikutip melalui kombinasi satu referensi panjang penuh, dan referensi internal yang dipersingkat ke properti yang sama.

Saya percaya eksternal kurang dioptimalkan karena tidak akan menyentuh referensi apa pun ke nama properti. Artinya 50 referensi ke firstName akan tetap sebagai firstName, sementara tanda kurung siku mungkin meninggalkan satu referensi publik sebagai firstName dan merusak 49 referensi internal lainnya.

@thelgevold itu benar, pendekatan externs menandai nama properti itu sebagai tidak dapat diubah namanya di mana-mana.
Kami tidak memiliki cara untuk menulis ulang akses titik ke akses dikutip secara otomatis, meskipun saya kira dengan sistem tipe kami dapat melihat declare interface dan tahu kapan harus melakukannya.

Tapi setelah kompresi, itu mungkin tidak masalah? Jika firstName masuk ke kamus di header file terkompresi, mungkin tidak banyak perbedaan berapa kali dirujuk dalam kode.

FWIW ini adalah pendekatan yang kami ambil sekarang secara internal di Google. Tapi saya pikir kita harus bereksperimen dengan saran Anda jika kita punya waktu.

Saya cukup yakin penutupan tidak mengoptimalkan alat peraga yang dikutip dengan cara apa pun. Penutupan hanya menghapus notasi kurung siku dari ini: model['firstname'] menjadi x.firstname .

AFAIK cara "bersih" dengan file eksternal dan cara notasi persegi memang menghasilkan hasil yang sama.

masalahnya adalah notModel.firstName juga akan menjadi y.firstname bukannya y.z

Penutupan harus dapat membedakan secara nominal tipe-tipe instans ini dengan tipe-tipe yang disediakan di eksternal. Begitulah cara kerjanya di dunia "global" lama. Saya tidak tahu cara menghasilkan eksternal untuk kelas yang memiliki nama yang sama tetapi berasal dari modul yang berbeda.

@alexeagle Anda mungkin benar. Mungkin tidak ada banyak keuntungan setelah gzip.

Mungkin akan rumit juga karena Anda kemungkinan besar harus menemukan semua referensi firstName "yang sama" dan menulis ulang ke ['firstName'] sepenuhnya. Kalau tidak, akan ada campuran notasi .firstName dan ['firstName'] , yang akan rusak saat runtime.

@b-strauss Penutupan akan mengonversi ['firstName'] menjadi .firstName. Namun, inilah teori pengoptimalan di balik [''] vs eksternal: https://developers.google.com/closure/compiler/docs/api-tutorial3
Saya telah melihat perilaku ini dalam beberapa eksperimen saya, tetapi mungkin tidak sepadan dengan usaha di sini.

Untuk file sumber JS seluler yang lebih besar masih akan memakan waktu lebih lama untuk diurai. Ini bukan hanya masalah ukuran posting gzip.

@thelgevold Saya tahu teori di baliknya. :)

Saya baru saja menulis tes kecil:

Kode aplikasi ini:

/**
 * <strong i="9">@constructor</strong>
 */
function NotMyModel() {
  this.firstname = 'foo';
}

console.log(new NotMyModel().firstname);
console.log(new MyModel().firstname);

bersama dengan kode pihak ketiga ini:

<script>
  function MyModel() {
    this.firstname = 'foo';
  }
</script>

dan eksternal ini:

/**
 * <strong i="16">@constructor</strong>
 */
function MyModel() {
}

/**
 * <strong i="17">@type</strong> {string|null}
 */
MyModel.prototype.firstname;

menghasilkan keluaran berikut:

(function () {
  console.log("foo");
  console.log((new MyModel).firstname);
})();

Closure mampu membedakan dua nama depan berdasarkan jenis nominalnya, bahkan sebaris dengan yang pertama. Seperti yang saya katakan, di dunia "global" lama ini bukan masalah, karena praktik terbaik adalah selalu mengawali tipe Anda com.bstrauss.MyClass .

Pertanyaannya adalah bagaimana seharusnya tsickle menghasilkan eksternal di dunia di mana tipe dari dua modul berbeda dapat memiliki nama yang sama?

AFAIK tidak ada goog.module setara untuk eksternal.

@b-strauss Terima kasih, telah berbagi eksperimen itu.

Komentar asli saya lebih tentang bagaimana [''] dapat mengoptimalkan beberapa referensi ke properti MyModel.firstName . Tidak terlalu banyak tentang mengoptimalkan crossover dengan nama yang sama di seluruh objek model yang berbeda.

Pemahaman saya adalah bahwa jika Anda memiliki 10 referensi MyModel().firstname dalam kode Anda, menggunakan [''] berpotensi memungkinkan Penutupan untuk membuat alias versi pendek internal. Dengan begitu ukuran bersih lebih kecil karena mempertahankan firstName di mana kode lain mengharapkannya, tetapi mendapat manfaat dari nama yang lebih pendek untuk referensi pribadi/lokal. Ini pemahaman saya bahwa eksternal tidak akan memberi Anda manfaat itu karena meninggalkan semua referensi saja.

@b-strauss rencana saya adalah untuk mengatasi ini di https://github.com/angular/tsickle/issues/352 , dengan merusak nama eksternal dan kemudian aliasing secara lokal. Yaitu, untuk file foo/bar/baz.ts :

/** <strong i="8">@externs</strong> */
function tsickle_from_foo_bar_baz_ts_MyModel() {}
/** <strong i="9">@type</strong> {string} */
tsickle_from_foo_bar_baz_ts_MyModel.prototype.firstName;

Dan di situs penggunaan:

goog.module('foo.bar.baz');

// Alias:
var MyModel = tsickle_from_foo_bar_baz_ts_MyModel;

// ... later on ...
new MyModel().firstName;

Mari kita bahas masalah itu, utas ini menjadi sedikit tidak fokus.

Beberapa waktu lalu di utas ini ada penyebutan diskusi tentang seberapa baik diterimanya rantai build berbasis Closure Compiler oleh komunitas. Bahkan jika itu tetap sekunder secara numerik ke tumpukan Webpack di Angular-CLI, saya menduga itu masih akan mendapatkan adopsi yang layak jika memberikan output yang lebih kecil. Ukuran masih sangat penting, terutama di seluler.

@alexeagle re "perpustakaan pihak ketiga harus tetap berada di luar kompilasi penutupan" - Itu mungkin titik awal yang baik, tetapi jika semuanya dibersihkan di mana Penutupan dapat digunakan hampir secara sepele pada kode aplikasi Angular, saya yakin ini akan menciptakan tekanan yang cukup besar pada Pembuat perpustakaan tambahan sudut (meskipun mungkin bukan ekosistem yang lebih luas) untuk memverifikasi barang-barang mereka berfungsi dengan Penutupan. Hal yang sama telah terjadi selama beberapa bulan terakhir mengenai AOT, di awal musim gugur sebagian besar perpustakaan add-on mengatakan "AOT?" tetapi hari ini sebagian besar dari mereka yang saya temukan memiliki hal-hal yang bekerja dengan AOT atau sangat sadar dan menuju ke arah itu.

Jika ada yang mengikuti pekerjaan ini di berbagai repo yang ditautkan dalam masalah ini selama setahun terakhir, saya pikir yang terbaru yang saya lihat di atas masih menunjuk pada paket "-builds", yang diperlukan hingga saat ini. Tapi sekarang Angular 4 rc dikirimkan dengan modul ES2015, sehingga tidak lagi diperlukan. Inilah cabang yang telah saya perbarui untuk bekerja dengan yang terbaru, dalam proses memahami apa yang terjadi dengan penggunaan Penutupan.

https://github.com/kylecordes/closure-compiler-angular-bundling/tree/update-versions

Rasanya seperti kita berada di ambang rantai pembuatan Angular tingkat produksi yang hanya terdiri dari ngc (dengan tsc di dalamnya) plus Penutupan. Itu bagus, tumpukan pendek.

Saya menerbitkan repositori berikut yang menunjukkan cara menggunakan 4rc.2, ngc (AOT), Closure Compiler:

https://github.com/OasisDigital/angular-aot-closure

Secara teknologi ini memiliki sedikit untuk menawarkan atas Alex, tetapi memiliki tujuan yang berbeda. Saya mencoba membuat repositori ini berisi banyak komentar dan teks yang menjelaskan bagaimana dan mengapa semuanya terjadi. Oleh karena itu jangan ragu untuk membuka masalah tentang itu, jika ada sesuatu yang tidak cukup dijelaskan di komentar atau README.

@nosachamos Tebakan liar: sesuatu di rantai alat (mungkin tsickle atau Penutupan?) tidak mengantisipasi parameter bernama this . Saran saya adalah:

  • Edit salinan lokal sumber RxJS Anda, ubah nama parameter itu, konfirmasikan tetap. Jika demikian maka...
  • Masukkan masalah (atau bahkan PR) ke RxJS untuk mengganti nama this dan parameter this serupa. Semoga tim RxJS akan melihat manfaat dalam perubahan seperti itu;mungkin kata yang baik dari tim Angular ( @alexeagle ?) tentang masalah seperti itu akan membantu.
  • Masukkan masalah dengan kasus repro sederhana ke Penutupan, tentang parameter bernama this ... dan itu tidak terjadi di sana, cari di tempat lain di rantai alat (tsickle?).

@kylecordes Ops, saya menemukan masalah saya dan menghapus komentar yang saya kira saat Anda mengetik.

Sebagai catatan, masalah saya adalah bahwa argumen bernama "ini" telah dihapus selama transpilasi.

Ternyata, penutupan menjalankan fungsi itu menggunakan call , jadi this sebenarnya diatur seperti itu dan tidak perlu diteruskan. Jika saya mengganti nama "ini" menjadi "ini2", argumennya adalah disimpan. Saya kira transpiler lebih pintar dari yang saya kira.

Masalah saya adalah dalam efek ngrx, bukan rxjs. Ngrx/efek mengakses efek melalui namanya, menggunakan notasi tanda kurung, yang dipecah oleh kompilator penutupan ketika mengganti nama semua hal. Untuk mencegah masalah, di konstruktor kelas Anda yang berisi efek Anda, tetapkan namanya ke "ini" menggunakan notasi tanda kurung:

export class MyEffects {

  @Effect()
  doSomething$: Observable<Action> = this.actions$ ...

  constructor() {
    this['doSomething$'] = this.doSomething$;
  }

}

Jadi saya hampir menjalankan dan menjalankan aplikasi dunia nyata menggunakan tumpukan ngrx. Saya sedang menulis apa yang saya yakini sebagai extern manual terakhir yang diperlukan untuk kasus saya. Jika ini semua berjalan dengan baik, saya akan membuat cabang pada aplikasi sampel di sini dengan tumpukan ngrx sebagai demo. Saya menggunakan garpu ngrx/core dan ngrx/store saya sendiri sementara PR saya untuk memperluas ekspor wildcard tidak digabungkan, tetapi selain itu, saya pikir ini akan berjalan dengan baik.

Aku akan membuat kalian diposting.

Bisakah Anda mengajukan bug terhadap tsickle dengan informasi lebih lanjut tentang masalah this ? Maksud kami adalah Anda tidak perlu mengganti nama variabel secara manual seperti ini.

Apakah mungkin untuk memperbaiki ngrx agar tidak menggunakan tanda kurung?

@nosachamos berdasarkan komentar Anda yang dihapus, dan komentar saya yang mungkin harus dihapus, apakah ada masalah untuk dilaporkan? (per @evmar )

@kylecordes Mungkin,
tapi menurut saya apa yang terjadi adalah bahwa transpiler dapat mengetahui fungsi memiliki "ini" yang disetel oleh pemanggilan call . Jadi dalam hal ini dapat menghapus argumen dengan aman, karena this akan menjadi apa pun yang diteruskan ke call . Itu tidak akan benar jika argumen diganti namanya, jadi argumennya tetap ada. Saya pikir dalam kasus khusus "ini", transpiler baik-baik saja. Faktanya, mengganti nama argumen tidak menyelesaikan masalah, karena masalah sebenarnya adalah akses braket.

@evmar saya percaya begitu. Akses braket ini cukup sentral untuk operasi mereka, tetapi saya menduga membuat anotasi kamus yang mendasarinya dengan anotasi @dict penutupan akan cukup untuk memperbaiki masalah ini. Saya akan mencoba ini dan mengirimkan PR kepada mereka jika itu berhasil. Lain, saya akan mengirimkan PR ke README mereka dengan catatan tentang solusi braket saat menggunakan ngrx/efek dengan penutupan.

Perhatikan bahwa anotasi jenis Penutupan apa pun yang ditambahkan ke kode TS dihapus oleh Tsickle, jadi menambahkan @dict di sana tidak akan membantu.

Masalah saya adalah dalam efek ngrx, bukan rxjs. Ngrx/efek mengakses efek melalui namanya, menggunakan notasi tanda kurung, yang dipecah oleh kompilator penutupan ketika mengganti nama semua hal. Untuk mencegah masalah, di konstruktor kelas Anda yang berisi efek Anda, tetapkan namanya ke "ini" menggunakan notasi tanda kurung:

@nosachamos Tidakkah masalah yang sama akan terjadi dengan @Input() dan @Output() ? Pertanyaan lain adalah: haruskah penutupan mengganti nama bidang yang didekorasi?

@evmar Saya transpiling dengan removeComments: false dan semua anotasi penutupan saya diteruskan ke kode ES6 yang saya berikan penutupan, jadi itu akan baik-baik saja. Saya menggunakan @dict di tempat lain, dan tidak masalah.

@awerlang tidak, @dict adalah anotasi gaya jsdoc, bukan anotasi sebenarnya seperti @Input. Anotasi penutupan ini berlanjut pada komentar.

@nosachamos test case kami adalah input ini https://github.com/angular/tsickle/blob/master/test_files/jsdoc/jsdoc.ts menghasilkan output ini
https://github.com/angular/tsickle/blob/master/test_files/jsdoc/jsdoc.js
di mana Anda akan melihat kami mengoceh sebagian besar anotasi. Mungkin ada bug sekalipun.

@evmar oh, saya mengkompilasi dengan ngc dan menggunakan

    "target": "es6",
    "module": "es2015",

dan

  "angularCompilerOptions": {
    "skipMetadataEmit": true,
    "annotationsAs": "static fields",
    "annotateForClosureCompiler": true
  },

Jadi saya hanya mendapatkan ES6, tidak ada goog.modules.. jadi semuanya tampak berfungsi sebagaimana mestinya, dan saya mendapatkan anotasi penutupan. Ini untuk RxJs. Untuk paket yang berinteraksi dengan angular (komponen, modul, dll), maka skipMetadataEmit diatur ke false .

@nosachamos seperti yang saya mengerti, langkah tsickle tidak dapat melakukannya, dan tidak akan melakukan hal itu ketika dijalankan melalui ngc , kecuali jika Anda menggunakan "module": "common" . Tsickle memberlakukan batasan ini ketika dijalankan oleh CLI-nya sendiri, apakah ia memperoleh kemampuan untuk bekerja dengan keluaran modul es2015 ketika dijalankan melalui ngc ? Apakah Anda melihat JSDoc yang dihasilkan tsickle di keluaran modul es2015?

@kylecordes ya, saya mendapatkan hasil yang sama persis dengan yang Anda dapatkan di demo repo yang Anda posting di atas dikompilasi dengan tsc-wrapped dan rxjs-tsickle tsconfig.

bisakah kita memindahkan bug ke masalah lain? itu tidak skala untuk mengatasi masalah individu pada masalah pelacakan. Terima kasih!

@alexeagle benar-benar. Saya memposting di sini awalnya karena saya pikir ini relevan (masalah bagaimana rxjs mendeklarasikan argumen bernama "ini" yang hilang). Tidak ada yang perlu ditindaklanjuti, tetapi jika sesuatu muncul, kami akan melakukannya di edisi terpisah.

@nosachamos Memang... Saya baru saja menemukan bahwa memang, tsickle-via-ngc atau -cli-wrapped dapat menangani module:es2015 .

@alexeagle Ah,

Lihat lagi bundel yang dihasilkan. Perhatikan bahwa pasti ada ruang untuk pengurangan kode lebih lanjut di sini.

Tidak selalu mudah bagi Closure untuk mengidentifikasi kode yang tidak perlu karena struktur kode yang ada terkadang membuatnya tampak seperti kode yang dibutuhkan.

Berdasarkan aplikasi POC di repo @alexeagle , saya memilih beberapa elemen yang tidak perlu disertakan dan membuat beberapa penyesuaian sementara pada sumber untuk memaksanya keluar dari bundel.

Sepertinya ada beberapa pola berulang di sini:

Kelas layanan mungkin tidak diperlukan oleh aplikasi, tetapi jika layanan ditambahkan ke array penyedia di sepanjang jalan, itu dapat menyebabkan kelas membuatnya menjadi bundel. Contohnya adalah AnimationDriver dan AnimationQueue . Dengan menghapus referensi penyedia ke kelas-kelas ini, saya bisa mengeluarkan kelas-kelas ini dari bundel.

Aplikasi sampel di repo Alex tidak melakukan kueri QueryList apa pun, tetapi banyak kode terkait Kueri masih dalam bundel.
Dalam hal ini, Penutupan tidak dapat mengecualikan kode karena kode berada dalam pernyataan sakelar di mana beberapa skenario ditangani.
Lihatlah createViewNodes di core.js dan klausa NodeType.Query pada khususnya.

case NodeType.Query:
       nodeData = (createQuery());
       break;

Kondisi dalam metode ini diselesaikan saat runtime , jadi Penutupan harus menyertakan semua kode untuk memenuhi semua kondisi di sakelar. Saya menghapus klausa khusus ini dan kode dikecualikan dari bundel.

Ini hanyalah dua contoh sederhana, tetapi jika Anda terus menyusuri jalan ini, akhirnya akan menambah pengurangan ukuran yang nyata. Saya tidak melangkah terlalu jauh dengan sampel ini, tetapi saya mungkin menghapus kira-kira 1k dengan menangani 4-5 kasus seperti ini.

Saya juga melakukan percobaan kedua di mana saya menghapus banyak kode secara manual (tanpa menggunakan Penutupan). Saya menurunkan aplikasi saya menjadi 16.6k dan saya yakin masih ada ruang untuk menghapus lebih banyak. Ini contohnya: http://www.syntaxsuccess.com/viewarticle/minimal-angular-application . Eksperimen khusus ini adalah peretasan besar, tetapi setidaknya ini membuktikan bahwa Anda dapat membuat aplikasi Angular dengan kode yang sangat sedikit.

Untuk membantu mengatasi beberapa tantangan ini, saya pikir mungkin masuk akal untuk memperluas AoT untuk menghasilkan lebih banyak kode kerangka kerja - bukan hanya kode tampilan.

Hanya berpikir keras di sini, tetapi tidak bisakah kompiler ngc secara teori menghasilkan kode untuk hal-hal seperti createViewNodes berdasarkan kebutuhan aplikasi tertentu. Dengan begitu jika aplikasi Anda tidak memerlukan Pipes, QueryList, atau apa pun, pernyataan kasus tertentu tersebut akan dihilangkan dari kode yang dihasilkan.

Pikiran?

Berdasarkan apa yang saya pelajari dari menghapus kode secara manual di bundel, saya telah menerapkan modifikasi serupa pada bundel di garpu penutup.

Saya meletakkan tweak di cabang jika Anda tertarik melihat hasilnya: https://github.com/thelgevold/closure-compiler-angular-bundling-old/tree/tweaking-src

Berikut adalah perbedaan dari bundel asli vs bundel tweak: https://github.com/thelgevold/closure-compiler-angular-bundling-old/commit/d1b3954e7e8a5b2dbb193683f9a3057322870d60

Jika Anda ingin mencobanya, ganti saja bundel bawaan dengan yang dimodifikasi. Saya mengasumsikan Angular 4.0.0 untuk percobaan ini.

Berikut adalah nomor dengan bundel baru:

Ukuran baru sekarang ~15rb gzip, dan sedikit lebih kecil dengan brotli.

++ ls -alH dist/bundle.js dist/bundle.js.brotli dist/bundle.js.gz dist/bundle.js.map
-rw-r--r--  1 tor  staff   47487 Mar 26 13:58 dist/bundle.js
-rw-r--r--  1 tor  staff   13979 Mar 26 13:58 dist/bundle.js.brotli
-rw-r--r--  1 tor  staff   15482 Mar 26 13:58 dist/bundle.js.gz
-rw-r--r--  1 tor  staff  133888 Mar 26 13:58 dist/bundle.js.map
++ for script in dist/bundle.js node_modules/zone.js/dist/zone.min.js
++ gzip --keep -f node_modules/zone.js/dist/zone.min.js
++ bro --force --quality 10 --input node_modules/zone.js/dist/zone.min.js --output node_modules/zone.js/dist/zone.min.js.brotli
++ ls -alH node_modules/zone.js/dist/zone.min.js node_modules/zone.js/dist/zone.min.js.brotli node_modules/zone.js/dist/zone.min.js.gz
-rw-r--r--  1 tor  staff  29634 Mar 25 11:00 node_modules/zone.js/dist/zone.min.js
-rw-------  1 tor  staff   8759 Mar 26 13:58 node_modules/zone.js/dist/zone.min.js.brotli
-rw-r--r--  1 tor  staff   9516 Mar 25 11:00 node_modules/zone.js/dist/zone.min.js.gz

Jelas sulit untuk mereplikasi ini tanpa merestrukturisasi sumber Angular, tetapi setidaknya menarik untuk melihat seberapa kecil aplikasi dasar.

Tidak yakin seberapa berguna ini, tapi setidaknya eksperimen yang menyenangkan :-)

Singkatnya:
Banyak penghematan berasal dari penghapusan kode dari struktur switch/if-else. Penutupan saat ini tidak dapat menyimpulkan bahwa beberapa opsi tidak dimungkinkan saat runtime untuk aplikasi tertentu. Kasus lain adalah array penyedia yang diisi dengan layanan yang tidak digunakan.

Seperti yang saya pahami dari karya @thelgevold , ada pengurangan ukuran output yang cukup besar, dengan penyesuaian yang relatif kecil hingga sedang ke Angular:

  • Mengakomodasi lebih sedikit fitur dengan if dan beralih dalam kode sumber.
  • Akses pra-konfigurasi lagi ke lebih sedikit fitur tersebut, dalam array penyedia bawaan.
  • Sesuaikan kompiler (mempengaruhi JIT dan AOT) untuk menghasilkan bit kode tambahan untuk menghubungkan fitur/penyedia tersebut dalam kode yang dihasilkan ... jika fitur tersebut benar-benar digunakan.

Saya tertarik pada apa yang dipikirkan seseorang di tim inti tentang ini, apakah itu benar-benar kecil hingga sedang dan apakah ada minat untuk menempuh jalan ini.

Hari ini kami mendapat rilis rxjs yang berfungsi dengan kompiler penutupan, dan saya telah memperbarui contoh repo
https://github.com/alexeagle/closure-compiler-angular-bundling

Eksternal juga dibersihkan - Angular dan Zone.js mendistribusikan ekstern yang dibutuhkan dalam paket masing-masing.
Kami akan segera menambahkan beberapa dokumentasi dan pengumuman tentang dukungan tersebut.

Sekarang setelah semua ini selesai, pada titik ini apakah Anda memiliki gagasan tentang bagaimana itu akan berintegrasi dengan sisa perkakas yang ada?

misalnya mungkin pada akhirnya ada opsi yang ditambahkan ke @ngtools/webpack untuk secara otomatis menjalankan output AOT melalui Penutupan (dan/atau beberapa langkah konfigurasi terdokumentasi untuk webpack-closure-compiler)? Atau apakah ini sesuatu yang harus menggantikan webpack?

Apakah mungkin untuk mengimplementasikan ngx-bootstrap dengan Penutupan?

https://github.com/valor-software/ngx-bootstrap

Ingin memberikan pembaruan:

Kami memiliki contoh repo dan editor beta Lucidchart yang bekerja dengan pengoptimalan tingkat lanjut. Kami menjalankan pengujian singkat menggunakan versi kami dengan pengoptimalan sederhana, dan versi kami yang menggunakan pengoptimalan lanjutan akan diluncurkan hari ini atau besok.

Versi Angular yang digunakan dalam contoh repo telah ditingkatkan ke RC5 (HEAD pada Selasa 16 Agustus).

Contoh repo dan wadah Docker yang menyertainya telah diperbarui jika ada yang ingin mencobanya. Berikut tautan ke contoh repo https://github.com/lucidsoftware/closure-typescript-example

Ukuran bundel

Ukuran bundel akhir untuk proyek contoh menggunakan kompilasi lanjutan tercantum di bawah ini. Catatan: contoh repo menyertakan kode dari js -> ts using clutz dan kemudian ts -> js using tsickle. Ini sedikit lebih besar dari sekadar aplikasi hello world sederhana.

Uncompressed: 112K
Brotli quality 10: 29K
Gzip: 34K

Catatan tentang Membuat Ini Bekerja

Berikut adalah catatan tentang apa yang diperlukan agar pengoptimalan tingkat lanjut berfungsi. Jika saya lupa sesuatu, saya akan memberikan tautan ke semua garpu kami, yang memiliki semua komitmen kami.

Contoh repo

File eksternal untuk Zone, Reflect, dan Jasmine disertakan dalam proses build, sehingga panggilan fungsi tersebut tidak diganti namanya.

Untuk mengatasi bug Closure Compiler di mana metode statis hilang, kami memiliki perintah sed yang benar-benar hacky yang kami jalankan pada file Angular js yang dibangun, mengganti semua baris yang menyertakan kata kunci statis dengan baris yang didahului oleh /** @nocollapse */ . Berikut tautan ke bug Penutupan: google/closure-compiler#1776

sudut

Perubahan terbesar yang kami buat pada Angular adalah membuatnya menggunakan output beranotasi Tsickle selama kompilasi. Kami pikir kami melakukan ini terakhir kali, tetapi kami memiliki bug di mana output beranotasi dibuang: D

Ada beberapa tempat yang Angular sebut sebagai fungsi string. Fungsi-fungsi ini dirujuk di tempat lain menggunakan notasi titik. Dengan demikian, beberapa referensi diganti namanya dan yang lainnya tidak. Kami mengubah Angular untuk menggunakan notasi titik di mana-mana untuk fungsi tersebut, sehingga mereka selalu berganti nama.

Kami juga memperbarui Angular/Tsickle untuk tidak membubuhi keterangan pada file .d.ts.

Kami membuat Angular bermain dengan baik dengan ES6, sehingga berfungsi dalam mode tidak dikompilasi. Kami mengubah beberapa tempat di mana .apply digunakan pada konstruktor untuk menggunakan kata kunci baru.

Tickle

Kami memperbaiki bug di tsickle di mana CLI tidak selalu menyertakan semua file sumber selama anotasi. Daftar nama file dari Program TypeScript seharusnya digunakan, sebagai gantinya kami menggunakan daftar nama file yang berbeda.

Tautan ke semua cabang proyek kami untuk membuat ini berfungsi

Sudut: https://github.com/lucidsoftware/angular/tree/closure-bundle
Tsickle: https://github.com/lucidsoftware/tsickle/tree/closure-bundle
RxJS: https://github.com/lucidsoftware/rxjs/tree/closure-hack
simbol-diamati: https://github.com/lucidsoftware/symbol-observable/tree/closure
Clutz: https://github.com/lucidsoftware/clutz

Kami mereproduksi karya @alexeagle dan dengan versi Angular yang lebih mutakhir. Seluruh proses pembuatan otomatis, sehingga Anda dapat mengikuti semuanya mulai dari sumber hingga hasil akhir. Anda dapat melihatnya beraksi di https://github.com/lucidsoftware/closure-typescript-example. Instruksi untuk menjalankan contoh dapat ditemukan di README untuk contoh repo. Ada wadah Docker untuk proyek tersebut, jadi hampir semua orang dapat mencobanya.

Contoh di atas menggunakan Angular 2, clutz, dan tsickle. Closure JS digunakan dalam Angular 2 TS, yang dikompilasi ke JS yang kompatibel dengan Penutupan.

Perubahan yang kami buat pada dependensi agar ini berfungsi sebagian besar sama dengan Alex. Ada beberapa perubahan yang kami tambahkan dan beberapa perubahan yang tidak lagi diperlukan. Terlepas dari itu, ide dasarnya sama. Kami menggunakan ngc atau tsickle yang dimodifikasi pada Angular 2 dan dependensinya untuk menghasilkan versi Closure yang kompatibel dari dependensi tersebut.

Kompilator Penutupan

Membangun dari kepala tidak lagi diperlukan. Cukup gunakan salah satu versi dari bulan Juni atau Juli.

sudut

https://github.com/lucidsoftware/angular/tree/closure-bundle

Sebagian besar pekerjaan di sumber Angular 2 adalah memodifikasi ngc untuk menghasilkan Closure compilable js dengan menambahkan beberapa langkah tsickle ke tsc-wrapped. Ada beberapa rintangan yang kami lewati untuk menggunakan sumber yang dimodifikasi sebagai input ke kompiler TypeScript di salah satu tsickle pass. Jika tidak, ini cukup lurus ke depan.

Kami juga mengubah modul Angular tertentu untuk dikompilasi ke JS yang kompatibel dengan Penutupan dengan meletakkan blok angularCompilerOptions di tsconfig.json seperti itu

"angularCompilerOptions": {
  "googleClosureOutput": true
}

Kemudian ketika Anda menjalankan build.sh modul-modul itu memiliki output yang Anda inginkan.

File utilitas pengujian yang menggunakan Selenium-webdriver dimodifikasi karena Selenium-webdriver tidak ada dan kami tidak ingin membuatnya kompatibel dengan penutupan.

RxJS

https://github.com/lucidsoftware/rxjs/tree/closure-hack

Proses pembuatan RxJS dimodifikasi untuk membangun dengan Makefile dari proyek kami. Sekitar setengah dari proses pembuatan ada di JS dan setengahnya lagi di Make. Ini cukup jenaka.

Satu-satunya perubahan lain selain target build adalah beberapa hal kecil untuk membuat RxJS dikompilasi dengan TypeScript dan Closure.

simbol-diamati (ketergantungan RxJS)

https://github.com/lucidsoftware/symbol-observable/tree/closure

RxJS sekarang bergantung pada beberapa kode yang dulunya merupakan bagian dari sumber RxJS dan sekarang menjadi modulnya sendiri. Kami memodifikasi modul itu (yaitu JS) agar kompatibel dengan kompiler Penutupan. Hanya ada dua file, jadi saya melakukannya secara manual.

sabit

https://github.com/lucidsoftware/tsickle/tree/ignore-type-comments

Kami memodifikasi Tsickle dengan dua cara:

  1. Tambahkan opsi --ignoreTypesInComments. Ini mencegah tsickle membuat kesalahan saat menemukan jsdoc di komentar. Ini diperlukan untuk mengkompilasi RxJS yang memiliki banyak komentar jsdoc.
  2. Ubah pathToModuleName agar CLI sama dengan pathToModuleName kita gunakan di ngc. Dengan cara itu modul diberi nama yang sama ketika dijalankan melalui tsickle atau ngc. Ini harus dilakukan di hulu karena pathToModuleName terkadang menghasilkan nama goog.module yang tidak valid.

hai saya menginstal proyek Anda tetapi kapan "make run" mendapatkan Kesalahan:
'tools/@angular/tsc-wrapped/src/compiler_host.ts(55,32): error TS2345: Argumen tipe 'ts.Program' tidak dapat ditetapkan ke parameter tipe 'ts.Program'.'
Bisakah kamu membantuku?

Masalah ini telah dikunci secara otomatis karena tidak ada aktivitas.
Silakan ajukan masalah baru jika Anda mengalami masalah serupa atau terkait.

Baca lebih lanjut tentang kebijakan penguncian percakapan otomatis kami.

_Tindakan ini telah dilakukan secara otomatis oleh bot._

Apakah halaman ini membantu?
0 / 5 - 0 peringkat