Як ви автоматизуєте мінімізацію Javascript для веб-додатків Java?


122

Мені цікаво почути, як ви віддаєте перевагу автоматизації мінімізації JavaScript для своїх веб-додатків Java. Ось кілька аспектів, які мене особливо цікавлять:

  • Як вона інтегрується? Це частина вашого інструмента збирання, фільтра сервлетів, окремої програми після обробки файлу WAR чи чогось іншого?
  • Чи легко ввімкнути та відключити ? Дуже смішно намагатися налагоджувати мінімізований сценарій, але розробнику також корисно перевірити, що мініфікація нічого не порушує.
  • Чи працює вона прозоро , чи є якісь побічні ефекти (крім тих, які притаманні мінімізації), які я маю враховувати у своїй щоденній роботі?
  • Який мініфікатор використовує?
  • Чи не вистачає якоїсь функції, яку ви можете придумати?
  • Що вам подобається в цьому?
  • Що вам не подобається в цьому?

Це здебільшого послужить орієнтиром для моїх майбутніх проектів (і, сподіваємось, інші ЗОЗ теж вважають його інформативним), тому всі види інструментів цікаві.

(Зверніть увагу, що це не питання про те, який мініфіксатор найкращий . У нас вже багато таких.)


це виглядає дійсно цікаво, про нього не чули. Усі інструменти, які я знайшов у швидкому пошуку, - це ручні інструменти, які запускаються один раз. Було б добре, якби були мурашки для мурашок чи мавен. Сподіваємось, хтось має хорошу відповідь.
Джей

І виявляється , хто - то - перевірити ДКА відповідь: stackoverflow.com/questions/1379856 / ...
gustafc

Відповіді:


65

13

Ми використовуємо завдання Ant для мінімізації файлів js за допомогою YUICompressor під час складання виробництва та виведення результату у окрему папку. Потім ми завантажуємо ці файли на веб-сервер. У цьому блозі можна знайти кілька хороших прикладів інтеграції YUI + Ant .

Ось приклад:

<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
Знімок; приємно. Ви переорієнтовуєте script srcна версії dev builds чи просто копіюєте неміфіковані файли в стиснутий / js каталог?
gustafc

Тільки для виробництва завантажуйте стислі файли над оригінальними в public_html / js. Хороша річ у тому, що між місцевим та виробництвом немає кодування чи зміни шляху, погано те, що ви повинні зробити завантаження та перезапис вручну (я впевнений, що це може бути автоматизовано, але для нас це не варто, завантажуючи кілька js-файлів раз у раз - це не надто велика угода).
серг

Я використовував ваш код, але він створює мінімізований файл в корені мого проекту, я встановив, <fileset dir="${generatedScriptsDir}" includes="**/*.js"/>але він не працює. Як я можу створити файл у файлі ${generatedScriptsDir}?
Vadorequest

спробуйте додати атрибут "dir" до тегу "застосовувати". переконайтеся, що "$ {generatedScriptsDir}" було створено як "властивість" із призначеним призначенням
Rajasri.J

12

Я вважаю, що один з найкращих і правильних інструментів для роботи розлючений. Перевірте https://github.com/wro4j/wro4j

Він робить все необхідне:

  • Підтримуйте веб-ресурси проекту (js & css) добре організованими
  • Об’єднайте та мінімізуйте їх під час виконання (за допомогою простого фільтра) або часу збору (за допомогою плагін Maven)
  • Вільний та відкритий код: Випущено під ліцензією Apache 2.0
  • кілька інструментів мінімізації, які підтримуються wro4j: JsMin, компресор Google Closing, YUI тощо
  • Дуже простий у використанні. Підтримує фільтр сервлетів, просту Java або конфігурацію весни
  • Підтримка Javascript та CSS Meta Frameworks: CoffeeScript, Less, Sass тощо
  • Перевірка: JSLint, CSSLint тощо

Може працювати як у налагодженні, так і у режимах виробництва. Просто вкажіть усі файли, з якими він повинен оброблятись / попередньо обробляти, і все інше.

Ви можете просто включити об'єднаний, мінімізований та стислий ресурс так:

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

2
Справді, схоже на чудовий інструмент. Дякуємо за оновлення!
gustafc

Чи додає він версії до файлів ресурсів, щоб примусити оновлення на стороні клієнта? Не вдалося знайти жодної документації щодо цієї функції.
Цян

Єдине, чого мені дуже не вистачає в wro4j, це префікс css.
inafalcao

Чи можна подавати статичний контент (створений wroна сервері додатків) з apacheвеб-сервера?
HybrisHelp

8

Я написав макроси мурашок для компілятора Google Closure і компресора Yahoo і включаю цей файл у різні веб-проекти.

<?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>
  • Інтеграція: <import file="build-minifier.xml" />у своєму build.xml виберіть звичайні завдання:<gc-js dir="${build.js.dir}" src="prototype" /> <yc-js-all dir="${build.js.dir}" />

  • Вибір двох мініфікаторів: компілятора Google Closure та компресора Yahoo, ви можете завантажити їх вручну та розмістити біля файлу xml

  • Мініфієри пропускають вже стиснуті файли (закінчуються на -min*)

  • Зазвичай я роблю три версії сценарію: нестиснений (наприклад prototype.js) для налагодження, стиснутий компілятором закриття ( prototype-min-gc.js) для виробничого сервера, стиснутий з Yahoo ( prototype-min-yc.js) для усунення несправностей, оскільки компілятор закриття використовує ризиковані оптимізації, а іноді створює недійсний стислий файл, а компресор Yahoo безпечніший

  • Компресор Yahoo може мінімізувати всі файли в режимі з одним макросом, компілятор закриття не може


8

Я спробував два способи:

  1. за допомогою фільтра сервлетів. У режимі виробництва фільтр активується, і він стискає будь-які дані, обмежені URL-адресами, наприклад * .css або * .js
  2. використання maven та yuicompressor-maven-plugin ; стиснення виконується ун-тантум (при складанні виробничої війни )

Звичайно, останнє рішення є кращим, оскільки воно не споживає ресурсів під час виконання (мій веб-сервер використовує механізм програми Google) і не ускладнює ваш код програми. Тож припустимо цей останній випадок у наступних відповідях:

Як вона інтегрується? Це частина вашого інструмента збирання, фільтра сервлетів, окремої програми після обробки файлу WAR чи чогось іншого?

використовуючи maven

Чи легко ввімкнути та відключити? Дуже смішно намагатися налагоджувати мінімізований сценарій, але розробнику також корисно перевірити, що мініфікація нічого не порушує.

ви активуєте його лише під час збирання остаточної війни; в режимі розробки ви бачите нестиснуту версію своїх ресурсів

Чи працює вона прозоро, чи є якісь побічні ефекти (крім тих, які притаманні мінімізації), які я маю враховувати у своїй щоденній роботі?

абсолютно

Який мініфікатор використовує?

Компресор YUI

Чи не вистачає якоїсь функції, яку ви можете придумати?

ні, вона дуже повна і проста у використанні

Що вам подобається в цьому?

він інтегрований з моїм улюбленим інструментом (maven), а плагін знаходиться в центральному сховищі (хороший громадянин Maven)


Плагін Maven - приємно. Шкода, що всі мої поточні проекти використовують мурашник :)
gustafc

ви можете створити ціль, яка створює "виробничий файл війни", використовуючи завдання мурашки YUI
dfa

4

Я думаю, вам потрібна бібліотека стиснення, наприклад тег Granule.

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

Це gzip та комбінувати javascripts, обгорнуті g: компресувати тег, використовуючи різні методи, також має завдання Ant

зразок коду:

<g: стиснути>
  <script type = "text / javascript" src = "common.js" />
  <script type = "text / javascript" src = "закриття / goog / base.js" />
  <script>
       goog.require ('goog.dom');
       goog.require ('goog.date');
       goog.require ('goog.ui.DatePicker');
  </script>
  <script type = "text / javascript">
      var dp = новий goog.ui.DatePicker ();
      dp.render (document.getElementById ('datepicker'));
  </script>
</ g: стиснути>
...


Так, це виглядає досить вишукано.
gustafc

3

Я дійсно здивований, що ніхто не згадав JAWR - https://jawr.github.io

Він досить зрілий і підтримує всі стандартні функції, яких слід очікувати, і трохи більше. Ось як це суперечить відмінним критеріям ОП.

Як вона інтегрується? Це частина вашого інструмента збирання, фільтра сервлетів, окремої програми після обробки файлу WAR чи чогось іншого?

Спочатку обробка / важкий підйом при запуску програми та сервірування базувався на сервлеті . Починаючи з 3.x, вони додали підтримку інтеграції під час збирання .

Підтримка JSP та Facelet надається за допомогою спеціальної бібліотеки тегів JSP для імпорту оброблених ресурсів. На додаток до цього, реалізовано завантажувач ресурсів JS, який підтримує завантаження ресурсів зі статичних HTML-сторінок .

Чи легко ввімкнути та відключити? Дуже смішно намагатися налагоджувати мінімізований сценарій, але розробнику також корисно перевірити, що мініфікація нічого не порушує.

debug=onОпція доступна для використання перед запуском програми і призначені для користувача GETпараметри можуть бути задані в окремих запитах в виробництві для перемикання режиму відладки вибірково під час виконання для зазначеного запиту.

Який мініфікатор використовує?

Для JS він підтримує YUI Compressor та JSMin, а для CSS я не впевнений.

Чи не вистачає якоїсь функції, яку ви можете придумати?

SASSна думку приходить підтримка. Однак, це робить підтримку LESS.


2

Наш проект вирішив це декількома способами, але ми продовжували використовувати компресор YUI через різні ітерації.

Ми спочатку мали серверту обробку стиснення для JavaScript, коли вперше був доступ до конкретного файлу; Потім це було кешоване. У нас вже була створена система для обробки спеціальних файлів властивостей, тому ми просто оновили наші конфігураційні файли, щоб підтримувати включення або відключення компресора залежно від середовища, в якому ми працювали.

Тепер середовища розробки ніколи не використовують стислий JavaScript для цілей налагодження. Натомість ми обробляємо стиснення в процесі збирання під час експорту нашої програми у файл WAR.

Наш клієнт ніколи не висловлював занепокоєння щодо стиснення, і розробники не помічають цього, поки не вирішать налагоджувати JavaScript. Тому я б сказав, що це досить прозоро, з мінімальними, якщо такі є, побічними ефектами.


Як ви користуєтесь компресором YUI у процесі збирання? Плагін Maven чи щось інше?
gustafc

1
На жаль, ми зараз використовуємо Мурашку. Ось корисне посилання для завдання «Мурашка»: blog.gomilko.com/2007/11/29/yui-compression-tool-as-ant-task
doomspork

1

Це працювало для мене: 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>

Я отримав $ {jar.yui.compressor} з search.maven.org: search.maven.org/…
Зворотний Тарзан

1

Я пишу рамку для управління веб-активами, що називається humpty . Він має на меті бути простішим і сучаснішим, ніж jawr або wro4j, використовуючи WebJars та ServiceLoaders.

Як вона інтегрується? Це частина вашого інструмента збирання, фільтра сервлетів, окремої програми після обробки файлу WAR чи чогось іншого?

У процесі розвитку сервлет обробляє активи за необхідності. Потім активи будуть попередньо скомпільовані перед виробництвом і розміщені у загальнодоступній папці, так що єдина частина, яка використовується, - це генерування правильних включень у HTML.

Чи легко ввімкнути та відключити? Дуже смішно намагатися налагоджувати мінімізований сценарій, але розробнику також корисно перевірити, що мініфікація нічого не порушує.

Це можна зробити шляхом переключення між режимами розробки та виробництва.

Чи працює вона прозоро, чи є якісь побічні ефекти (крім тих, які притаманні мінімізації), які я маю враховувати у своїй щоденній роботі?

Я вважаю, що це прозоро, але дуже підтримує використання WebJars.

Який мініфікатор використовує?

Незалежно від того, який плагін ви поставите на свій класний шлях. В даний час дивлюся на написання плагіна для компілятора закриття Google.

Чи не вистачає якоїсь функції, яку ви можете придумати?

Все ще перед випуском, хоча я використовую його у виробництві. Плагін Maven ще потребує великої роботи.

Що вам подобається в цьому?

Простота додавання залежності для налаштування фреймворку

Що вам не подобається в цьому?

Це моя дитина, я це все люблю;)


1

Дійсно спізнитися на вечірку тут, але подумав, що це може допомогти тому, хто все ще шукає іншої відповіді:

Після спроби використовувати компресор YUI, я був розчарований, що він несумісний з більш новими версіями jQuery і Prism (дві основні сторонні бібліотеки JS, які мені потрібні для мого проекту, які я хотів стиснути в один файл). Тому я вирішив використати Terser , який є роздрібною програмою Uglify-JS, яка підтримує ES6 +. Мені не вдалося змусити його безпосередньо запускатись із <exec>завданням, але принаймні, використовуючи метод командного рядка Windows, працює для Win 10 (принаймні, не кажучи, що це не може працювати інакше, але це була дуже проста робота). Не потрібно додавати нічого іншого до системної змінної Path (як правило, Node.JS додається під час встановлення). Я спочатку використовую <concat>завдання ANT, щоб створити великий, нестиснений файл. Використовуйте, <fileset>оскільки це збереже порядок (якщо це важливо, все одно).

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

Потім використовуйте <exec>завдання для запуску будь-якої програми NPM, наприклад, Terser. Сторінка керівництва Apache в цьому завданні вказала, що це рішення Windows для запуску файлів .bat, але це дійсно дозволяє запускати практично будь-які програми командного рядка (навіть ті, які <exec>загадково не можуть знайти інше).

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

Інтегрувати? Це частина сценарію збірки ANT (плагін DITA Open Toolkit для підтримки користувальницького JavaScript, серед іншого - не веб-додаток Java, як такий, але використання Java для створення вихідного HTML5), тому інтеграція була не набагато більше, ніж додавання цих завдання на нову ціль (є більше коду щодо встановлення значень за замовчуванням та перевірки вхідних параметрів!).

Легко увімкнути / вимкнути? У моєму випадку у мене є параметр, який я передаю до збірки ANT, щоб включити створення та мінімізацію файлу JS. Так, так, вона виконує цю ціль лише в тому випадку, якщо я встановив параметр на "Так". Це досить проста річ для встановлення в збірці ANT.

Прозорий На сьогодні, схоже, це не впливає на жоден із декількох файлів JS, які я включаю. Деякі з них є моїми власними (і я жодним чином не знавець JS), а деякі, як я вже згадував, є загальними бібліотеками JS.

Minifier Terser , але за допомогою цього методу ви можете використовувати практично будь-яку мінімізовану введення командного рядка.

Не вистачає можливостей? Terser працює лише з JavaScript. Якщо я хочу зробити те ж саме для своїх CSS-файлів (що я роблю), я використовую компресор YUI.

Подобається, що це зараз активний проект і має гарну підтримку. Крім того, поточна реалізація (лише виклик її через <exec>ціль ANT ) дозволяє мені міняти міні-фільтри, якщо мені потрібно використовувати щось інше в дорозі.

Не подобається, що для цього потрібен Node.JS. Нічого проти Node.JS, зауважте, тільки що цей конкретний проект не потребує цього в іншому випадку. Я б вважав за краще використовувати для цього файл Java .jar, як YUI Compressor (я можу легко розповсюджувати це за допомогою плагіна).


Ласкаво просимо також запросити! Я погоджуюся, що турбуватись, що проект залежить від двох різних програмних середовищ (Java + Node). Тим не менш, не дивно, що більшість робіт Javascript відбувається в спільноті Node, тому з цим не багато чого робити, і, здається, Терсер в наші дні має велику силу. Дякуємо за ваш внесок!
gustafc
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.