Bagaimana Anda mengotomatiskan minifikasi Javascript untuk aplikasi web Java Anda?


122

Saya tertarik untuk mendengar bagaimana Anda lebih suka mengotomatiskan minifikasi Javascript untuk aplikasi web Java Anda. Berikut beberapa aspek yang sangat saya minati:

  • Bagaimana cara mengintegrasikannya? Apakah ini bagian dari alat build Anda, filter servlet, program mandiri setelah pemrosesan file WAR, atau yang lainnya?
  • Apakah mudah untuk mengaktifkan dan menonaktifkan ? Sangat tidak lucu untuk mencoba dan men-debug skrip yang diperkecil, tetapi juga berguna bagi pengembang untuk dapat menguji bahwa minifikasi tidak merusak apa pun.
  • Apakah itu bekerja secara transparan , atau apakah itu memiliki efek samping (selain yang melekat dalam minifikasi) yang harus saya pertimbangkan dalam pekerjaan saya sehari-hari?
  • Minifier mana yang digunakannya?
  • Apakah itu kekurangan fitur yang dapat Anda pikirkan?
  • Apa yang Anda suka tentang itu?
  • Apa yang tidak kamu suka tentang itu?

Ini sebagian besar akan berfungsi sebagai referensi untuk proyek masa depan saya (dan mudah-mudahan SOer lain akan menemukannya informatif juga), jadi semua jenis alat itu menarik.

(Perhatikan bahwa ini bukan pertanyaan tentang penambang mana yang terbaik . Kami sudah memiliki banyak penambang .)


ini terlihat sangat menarik, belum pernah mendengarnya. Semua alat yang saya temukan dalam pencarian cepat adalah alat manual yang berjalan sekali. Alangkah baiknya jika ada colokan untuk semut atau gagak. Semoga ada yang punya jawaban bagus.
Jay

Dan tampaknya seseorang melakukannya - periksa jawaban dfa: stackoverflow.com/questions/1379856/…
gustafc

Jawaban:


65

minify-maven dan maven yui compressor tidak berfungsi dengan baik dengan fitur ES6 untuk saya pada saat komentar ini
DPM

13

Kami menggunakan tugas Ant untuk mengecilkan file js dengan YUICompressor selama pembuatan produksi dan memasukkan hasilnya ke dalam folder terpisah. Kemudian kami mengunggah file-file itu ke server web. Anda dapat menemukan beberapa contoh bagus untuk integrasi YUI + Ant di blog ini .

Berikut ini contohnya:

<target name="js.minify" depends="js.preprocess">
    <apply executable="java" parallel="false">
        <fileset dir="." includes="foo.js, bar.js"/>
        <arg line="-jar"/>
        <arg path="yuicompressor.jar"/>
        <srcfile/>
        <arg line="-o"/>
        <mapper type="glob" from="*.js" to="*-min.js"/>
        <targetfile/>
    </apply>
</target>

2
Potongan; bagus. Apakah Anda menargetkan ulang script srcpada build dev atau Anda hanya menyalin file non-minified ke direktori / js yang dikompresi?
gustafc

Hanya untuk upload produksi, file terkompresi di atas yang asli di public_html / js. Hal baiknya adalah tidak ada pengkodean atau perubahan jalur antara lokal dan produksi, hal buruknya adalah Anda harus melakukan beberapa pengunggahan dan penimpaan manual (saya yakin ini bisa otomatis, tetapi bagi kami itu tidak sepadan, mengunggah beberapa file js sesekali tidak terlalu penting).
serg

Saya menggunakan kode Anda tetapi itu membuat file yang diperkecil di root proyek saya, saya tetapkan <fileset dir="${generatedScriptsDir}" includes="**/*.js"/>tetapi tidak berhasil. Bagaimana saya bisa menghasilkan file di ${generatedScriptsDir}?
Vadorequest

coba tambahkan atribut 'dir' ke tag 'apply'. pastikan bahwa '$ {generatedScriptsDir}' telah dibuat sebagai 'properti' dengan tujuan yang dirancang
Rajasri.J

12

Saya pikir salah satu alat terbaik dan tepat untuk pekerjaan itu adalah wro4j. Lihat https://github.com/wro4j/wro4j

Itu melakukan semua yang Anda butuhkan:

  • Jaga sumber daya web proyek (js & css) terorganisir dengan baik
  • Gabungkan & minifikasikan saat run-time (menggunakan filter sederhana) atau waktu build (menggunakan plugin maven)
  • Gratis dan open source: Dirilis di bawah lisensi Apache 2.0
  • beberapa alat minifikasi yang didukung oleh wro4j: JsMin, Google Closure Compressor, YUI dll
  • Sangat mudah digunakan. Mendukung Filter Servlet, Java Biasa atau Konfigurasi Pegas
  • Dukungan Javascript dan CSS Meta Frameworks: CoffeeScript, Less, Sass dll
  • Validasi: JSLint, CSSLint dll

Dapat berjalan dalam mode debug serta mode produksi. Cukup tentukan semua file yang harus ditangani / pra-proses dan sisanya akan dilakukan.

Anda cukup menyertakan sumber daya yang digabungkan, diperkecil, dan dikompresi seperti ini:

<script type="text/javascript" src="wro/all.js"></script>

2
Sepertinya memang alat yang bagus. Terima kasih telah memperbarui!
gustafc

Apakah itu menambahkan versi ke file sumber daya untuk memaksa penyegaran di sisi klien? Saya tidak dapat menemukan dokumentasi apa pun tentang fitur ini.
Qiang

Satu-satunya hal yang sangat saya rindukan di wro4j adalah awalan css.
inafalcao

Apakah mungkin untuk menyajikan konten statis (dibuat oleh wrodi server Aplikasi) dari apacheserver web?
HybrisHelp

8

Saya telah menulis makro semut untuk kompiler Penutupan Google dan kompresor Yahoo dan menyertakan file ini dalam proyek web yang berbeda.

<?xml version="1.0" encoding="UTF-8"?>
<!-- CSS and JS minifier. -->
<!DOCTYPE project>
<project name="minifier" basedir=".">

  <property name="gc" value="compiler-r1592.jar" />
  <property name="yc" value="yuicompressor-2.4.6.jar" />

  <!-- Compress single js with Google Closure compiler -->
  <macrodef name="gc-js">
    <attribute name="dir" />
    <attribute name="src" />
    <sequential>
      <java jar="${gc}" fork="true">
        <!--
        - - compilation_level WHITESPACE_ONLY | SIMPLE_OPTIMIZATIONS | ADVANCED_OPTIMIZATIONS
        Specifies the compilation level to use. Default: SIMPLE_OPTIMIZATIONS
        - - warning_level QUIET | DEFAULT | VERBOSE
        Specifies the warning level to use.
        -->
        <arg line="--js=@{dir}/@{src}.js" />
        <arg line="--js_output_file=@{dir}/@{src}-min-gc.js" />
      </java>
    </sequential>
  </macrodef>

  <!-- Compress single js with Yahoo compressor -->
  <macrodef name="yc-js">
    <attribute name="dir" />
    <attribute name="src" />
    <sequential>
      <java jar="${yc}" fork="true">
        <arg value="@{dir}/@{src}.js" />
        <arg line="-o" />
        <arg value="@{dir}/@{src}-min-yc.js" />
      </java>
    </sequential>
  </macrodef>

  <!-- Compress all js in directory with Yahoo compressor -->
  <macrodef name="yc-js-all">
    <attribute name="dir" />
    <sequential>
      <apply executable="java" parallel="false">
        <fileset dir="@{dir}" includes="*.js" excludes="*-min*.js" />
        <arg line="-jar" />
        <arg path="${yc}" />
        <srcfile />
        <arg line="-o" />
        <mapper type="glob" from="*.js" to="@{dir}/*-min-yc.js" />
        <targetfile />
      </apply>
    </sequential>
  </macrodef>

  <!-- Compress all css in directory with Yahoo compressor -->
  <macrodef name="yc-css-all">
    <attribute name="dir" default="${build.css.dir}" />
    <sequential>
      <apply executable="java" parallel="false">
        <fileset dir="@{dir}" includes="*.css" excludes="*-min*.css" />
        <arg line="-jar" />
        <arg path="${yc}" />
        <arg line="-v --line-break 0" />
        <srcfile />
        <arg line="-o" />
        <mapper type="glob" from="*.css" to="@{dir}/*-min.css" />
        <targetfile />
      </apply>
    </sequential>
  </macrodef>
</project>
  • Integrasi: <import file="build-minifier.xml" />di build.xml Anda, lalu aktifkan tugas semut seperti biasa:<gc-js dir="${build.js.dir}" src="prototype" /> <yc-js-all dir="${build.js.dir}" />

  • Pilihan dua minifier: Google Closure compiler dan Yahoo compressor, Anda harus mengunduhnya secara manual dan meletakkannya di dekat file xml

  • Minifier melewati file yang sudah dikompresi (diakhiri dengan -min*)

  • Biasanya saya membuat tiga versi script: tidak terkompresi (misalnya prototype.js) untuk debugging, dikompresi dengan closure compiler ( prototype-min-gc.js) untuk server produksi, dikompresi dengan Yahoo ( prototype-min-yc.js) untuk troubleshooting karena closure compiler menggunakan optimasi yang berisiko dan terkadang menghasilkan file terkompresi yang tidak valid dan kompresor Yahoo lebih aman

  • Kompresor Yahoo dapat mengecilkan semua file dalam satu dir dengan makro tunggal, kompiler Penutup tidak bisa


8

Saya mencoba dua cara:

  1. menggunakan filter servlet. Saat dalam mode produksi, filter diaktifkan dan itu memampatkan data apa pun yang dibatasi ke URL seperti * .css atau * .js
  2. menggunakan maven dan yuicompressor-maven-plugin ; kompresi dilakukan secara una-tantum, (saat merakit perang produksi )

Tentu saja solusi terakhir lebih baik karena tidak menghabiskan sumber daya pada waktu proses (aplikasi web saya menggunakan mesin aplikasi google) dan tidak mempersulit kode aplikasi Anda. Jadi asumsikan kasus terakhir ini dalam jawaban berikut:

Bagaimana cara mengintegrasikannya? Apakah itu bagian dari alat build Anda, filter servlet, program mandiri setelah pemrosesan file WAR, atau yang lainnya?

menggunakan maven

Apakah mudah untuk mengaktifkan dan menonaktifkan? Sangat tidak lucu untuk mencoba dan men-debug skrip yang diperkecil, tetapi juga berguna bagi pengembang untuk dapat menguji bahwa minifikasi tidak merusak apa pun.

Anda mengaktifkannya hanya saat menyusun perang terakhir; dalam mode pengembangan Anda melihat versi sumber daya Anda yang tidak terkompresi

Apakah itu bekerja secara transparan, atau apakah itu memiliki efek samping (terlepas dari yang melekat dalam minifikasi) yang harus saya pertimbangkan dalam pekerjaan saya sehari-hari?

benar

Minifier mana yang digunakannya?

Kompresor YUI

Apakah itu kekurangan fitur yang dapat Anda pikirkan?

tidak, ini sangat lengkap dan mudah digunakan

Apa yang Anda suka tentang itu?

itu terintegrasi dengan alat favorit saya (maven) dan plugin ada di repositori pusat (warga negara maven yang baik)


Plugin Maven - bagus. Sayang sekali proyek saya saat ini semua menggunakan semut :)
gustafc

Anda dapat membuat target yang membangun "file perang produksi", menggunakan tugas ant YUI
dfa

4

Saya pikir Anda memerlukan pustaka kompresi, misalnya tag Granule.

http://code.google.com/p/granule/

Itu gzip dan menggabungkan javascript yang dibungkus oleh tag g: kompres menggunakan metode yang berbeda, juga memiliki tugas Ant juga

contoh kode adalah:

<g: kompres>
  <script type = "text / javascript" src = "common.js" />
  <script type = "text / javascript" src = "closure / goog / base.js" />
  <script>
       goog.require ('goog.dom');
       goog.require ('goog.date');
       goog.require ('goog.ui.DatePicker');
  </script>
  <script type = "text / javascript">
      var dp = new goog.ui.DatePicker ();
      dp.render (document.getElementById ('datepicker'));
  </script>
</ g: kompres>
...


Ya, itu terlihat cukup bagus.
gustafc

3

Saya sangat terkejut tidak ada yang menyebut JAWR - https://jawr.github.io

Ini cukup matang dan mendukung semua fitur standar yang diharapkan, dan lebih banyak lagi. Berikut adalah bagaimana hal itu sesuai dengan kriteria OP yang sangat baik.

Bagaimana cara mengintegrasikannya? Apakah itu bagian dari alat build Anda, filter servlet, program mandiri setelah pemrosesan file WAR, atau yang lainnya?

Ini awalnya melakukan pemrosesan / pengangkatan berat saat startup aplikasi dan penyajian didasarkan pada servlet . Dimulai dengan 3.x, mereka menambahkan dukungan untuk pengintegrasian pada waktu pembuatan .

Dukungan untuk JSP dan Facelet disediakan melalui pustaka tag JSP kustom untuk mengimpor sumber daya yang diproses. Selain itu, pemuat sumber daya JS diimplementasikan yang mendukung pemuatan sumber daya dari halaman HTML statis .

Apakah mudah untuk mengaktifkan dan menonaktifkan? Sangat tidak lucu untuk mencoba dan men-debug skrip yang diperkecil, tetapi juga berguna bagi pengembang untuk dapat menguji bahwa minifikasi tidak merusak apa pun.

Sebuah debug=onopsi tersedia untuk digunakan sebelum aplikasi dimulai, dan GETparameter khusus dapat ditentukan pada permintaan individu dalam produksi untuk beralih mode debug secara selektif pada waktu proses untuk permintaan tersebut.

Minifier mana yang digunakannya?

Untuk JS mendukung YUI Compressor dan JSMin, untuk CSS saya tidak yakin.

Apakah itu kekurangan fitur yang dapat Anda pikirkan?

SASSdukungan datang ke pikiran. Yang mengatakan, itu mendukung LESS.


2

Proyek kami telah menanganinya dengan berbagai cara tetapi kami terus menggunakan Kompresor YUI melalui iterasi yang berbeda.

Kami awalnya memiliki servlet yang menangani kompresi untuk JavaScript saat pertama kali file tertentu diakses; itu kemudian di-cache. Kami sudah memiliki sistem untuk menangani file properti khusus jadi kami cukup memperbarui file konfigurasi kami untuk mendukung pengaktifan atau penonaktifan kompresor tergantung pada lingkungan tempat kami bekerja.

Sekarang lingkungan pengembangan tidak pernah menggunakan JavaScript terkompresi untuk tujuan debugging. Sebagai gantinya, kami menangani kompresi dalam proses pembuatan kami saat mengekspor aplikasi kami ke file WAR.

Klien kami tidak pernah menyuarakan kekhawatiran tentang kompresi dan pengembang tidak menyadarinya sampai mereka memutuskan untuk men-debug JavaScript. Jadi saya akan mengatakan itu agak transparan dengan minimal, jika ada, pengaruh samping.


Bagaimana Anda menggunakan kompresor YUI dari proses pembuatan Anda? Plugin Maven atau yang lainnya?
gustafc

1
Maaf, kami menggunakan Ant saat ini. Berikut ini tautan yang berguna untuk Tugas Semut: blog.gomilko.com/2007/11/29/yui-compression-tool-as-ant-task
doomspork

1

Ini berhasil untuk saya: https://bitbucket.org/m6_russell_francis/yui-compressor-ant-task/wiki/Home

<!-- minimize all static *.css & *.js content -->
<target name="static-content-minify">

    <taskdef name="yuicompressor"
             classname="com.metrosix.yuicompressor.anttask.YuiCompressorTask">
        <classpath>
            <pathelement location="${jar.yui.compressor}"/>
            <pathelement location="${jar.yui.anttask.compressor}" />
        </classpath>
    </taskdef>

    <yuicompressor todir="${build.static.content.min}" charset="utf-8" 
        preserveallsemicolons="true" munge="true" >
        <fileset dir="${src.static.content}">
            <include name="**/*.css"/>
            <include name="**/*.js"/>
        </fileset>
    </yuicompressor>
</target>

Saya mendapatkan $ {jar.yui.compressor} dari search.maven.org: search.maven.org/…
Membalikkan Tarzan

1

Saya sedang menulis kerangka kerja untuk mengelola aset web, yang disebut humpty . Ini bertujuan untuk menjadi lebih sederhana dan lebih modern daripada jawr atau wro4j dengan menggunakan WebJars dan ServiceLoaders.

Bagaimana cara mengintegrasikannya? Apakah itu bagian dari alat build Anda, filter servlet, program mandiri setelah pemrosesan file WAR, atau yang lainnya?

Dalam pengembangan, servlet memproses aset sesuai kebutuhan. Aset kemudian akan dikompilasi sebelumnya sebelum produksi dan ditempatkan di folder publik, sehingga satu-satunya bagian yang digunakan adalah membuat penyertaan yang benar dalam HTML.

Apakah mudah untuk mengaktifkan dan menonaktifkan? Sangat tidak lucu untuk mencoba dan men-debug skrip yang diperkecil, tetapi juga berguna bagi pengembang untuk dapat menguji bahwa minifikasi tidak merusak apa pun.

Itu akan dilakukan dengan beralih antara mode pengembangan dan produksi.

Apakah itu bekerja secara transparan, atau apakah itu memiliki efek samping (terlepas dari yang melekat dalam minifikasi) yang harus saya pertimbangkan dalam pekerjaan saya sehari-hari?

Saya yakin ini transparan, tetapi sangat mendukung penggunaan WebJars.

Minifier mana yang digunakannya?

Plugin mana pun yang Anda tempatkan di classpath Anda gunakan. Saat ini sedang menulis plugin untuk Google Closure Compiler.

Apakah itu kekurangan fitur yang dapat Anda pikirkan?

Masih pra-rilis, meskipun saya menggunakannya dalam produksi. Plugin maven masih membutuhkan banyak pekerjaan.

Apa yang Anda suka tentang itu?

Kesederhanaan hanya dengan menambahkan dependensi untuk mengonfigurasi kerangka kerja

Apa yang tidak kamu suka tentang itu?

Ini bayiku, aku suka semuanya;)


1

Terlambat banget ke pesta di sini, tapi menurutku ini mungkin bisa membantu seseorang yang masih mencari jawaban berbeda:

Setelah mencoba menggunakan YUI Compressor, saya kecewa karena itu tidak kompatibel dengan versi jQuery dan Prism yang lebih baru (dua pustaka JS pihak ketiga utama yang saya butuhkan untuk proyek saya yang ingin saya kompres menjadi satu file). Jadi saya memutuskan untuk menggunakan Terser , yang merupakan cabang dari Uglify-JS yang mendukung ES6 +. Saya tidak bisa membuatnya berjalan langsung menggunakan <exec>tugas, tetapi menggunakan metode baris perintah Windows berfungsi untuk Win 10, setidaknya (tidak mengatakan itu tidak dapat berfungsi sebaliknya, tetapi ini adalah penyelesaian yang sangat mudah). Tidak perlu menambahkan apa pun ke variabel sistem Path (karena Node.JS biasanya ditambahkan selama instalasi). Saya pertama kali menggunakan <concat>tugas ANT untuk membuat file besar dan tidak terkompresi. Gunakan <fileset>karena akan menjaga ketertiban (jika itu penting, bagaimanapun).

<concat destfile="${js-big-file}" encoding="UTF-8" outputencoding="UTF-8" fixlastline="true">
   <filelist refid="js-input-filelist"/>
</concat>

Kemudian gunakan <exec>tugas untuk menjalankan program NPM apa pun, seperti Terser. The Apache halaman manual pada tugas ini mengindikasikan ini adalah Windows atasi untuk menjalankan kelelawar file, tapi itu benar-benar memungkinkan Anda menjalankan apa saja aplikasi baris perintah (bahkan mereka yang <exec>misterius tidak dapat menemukan sebaliknya).

<exec executable="cmd">
   <arg value="/c"/>
   <arg value="terser"/>
   <arg value="${js-big-file}" />
   <arg value="-o" />
   <arg value="${smaller-js-file}"/>  
</exec>

Mengintegrasikan? Ini adalah bagian dari skrip build ANT (plugin DITA Open Toolkit untuk mendukung JavaScript kustom, antara lain - bukan aplikasi Web Java, tetapi menggunakan Java untuk membuat output HTML5), jadi integrasi tidak lebih dari sekadar menambahkan itu. tugas ke target baru (ada lebih banyak kode mengenai pengaturan default dan memeriksa parameter input!).

Mudah Diaktifkan / Nonaktifkan? Dalam kasus saya, saya memiliki parameter yang saya berikan ke ANT Build untuk menyertakan membangun dan mengecilkan file JS. Jadi ya, itu hanya melakukan target ini jika saya menyetel param ke 'Ya'. Itu adalah hal yang cukup mudah untuk disiapkan dalam build ANT.

Transparan Sejauh ini, tampaknya tidak berpengaruh pada salah satu dari beberapa file JS yang saya sertakan. Beberapa di antaranya adalah milik saya (dan saya bukan ahli JS, dengan cara apa pun) dan beberapa, seperti yang saya sebutkan, pustaka JS umum.

Minifier Terser, tetapi Anda bisa menggunakan apa saja yang diperkecil dengan input baris perintah dengan metode ini.

Kekurangan fitur? Terser hanya bekerja dengan JavaScript. Jika saya ingin melakukan hal yang sama untuk file CSS saya (yang saya lakukan), saya menggunakan YUI Compressor.

Seperti Itu, ini adalah proyek yang sedang aktif dan memiliki dukungan yang baik. Plus, implementasi saat ini (hanya memanggilnya melalui <exec>target ANT ) memungkinkan saya untuk menukar minifier jika saya perlu menggunakan sesuatu yang lain di jalan.

Tidak suka Itu membutuhkan Node.JS. Tidak ada yang melawan Node.JS, ingatlah, hanya saja proyek khusus ini tidak membutuhkannya sebaliknya. Saya lebih suka menggunakan file Java .jar seperti YUI Compressor untuk ini (saya dapat dengan mudah mendistribusikannya dengan plugin jika saya perlu).


Yang terlambat juga dipersilakan! Saya setuju bahwa merepotkan untuk memiliki proyek yang bergantung pada dua lingkungan pemrograman yang berbeda (Java + Node). Namun, tidak mengherankan bahwa sebagian besar pekerjaan Javascript terjadi di komunitas Node, jadi tidak banyak yang bisa dilakukan tentangnya, dan Terser tampaknya memiliki banyak momentum akhir-akhir ini. Terima kasih atas kontribusi Anda!
gustafc
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.