Личный сайт Алексея Григорьева

Организация java script фалов в maven проекте

Организуем код на java script в web проекте в maven:

1. Добавляем все скрипты на страницу

Со временем количество кода в проекте растет, и весь код уже не вмещается в один js файл, и даже — в одну папку. Для того, чтобы избавить себя от добавления всех файлов на страницу вручную, напишем скрипт, который сделает это сам. Файл scripts.jsp:

<%@ page import="java.util.*"%>
<%@ page import="java.io.File"%>
<%@ page pageEncoding="UTF-8"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
 
<%!
public String getRelative(File parent, File child) {
    return parent.toURI().relativize(child.toURI()).getPath();
}
public List<String> goThrough(File mainParent, File dir, List<String> list) {
    for (File file : dir.listFiles()) {
        if (file.isDirectory()) {
            goThrough(mainParent, file, list);
        } else {
            if (file.getName().endsWith("js")) {
                list.add(getRelative(mainParent, file));
            }
        }
    }
    Collections.sort(list);
    return list;
}
%>
 
<%
String pathToJs = config.getServletContext().getRealPath("/resources/js/main/");
File parent = new File(pathToJs);
List<String> list = goThrough(parent, parent, new ArrayList<String>());
 
for (String line : list) { %>
<script type="text/javascript" src="<spring:url value="/resources/js/main/"/><%=line%>"></script>
<%}%>

2. Тестируем

Среди утилит для покрытия java script кода тестами наиболее привлекательной оказалась jsTestDriver. Помещаем конфиг jsTestDriver.conf в корневую папку web проекта и прописываем пути до js файлов:

server: http://localhost:4224

load:
#jquery:
 - src/main/webapp/resources/js/jquery/jquery-1.6.2.js
 - src/main/webapp/resources/js/*.js 
#sources:
 - src/main/webapp/resources/js/main/*.js
 - src/main/webapp/resources/js/main/banners/*.js
 - src/main/webapp/resources/js/main/popups/*.js
#js-mockito:
 - src/test/webapp/resources/test-js/*.js
#tests:
 - src/test/webapp/resources/js/*.js
 - src/test/webapp/resources/js/popups/*.js
 - src/test/webapp/resources/js/social/*.js

И ждем, когда примут патч, позволяющий использовать «**» в путях.

3. Соединяем все файлы в один

Для production версии соединяем все js файлы в один, минифицируем, сжимаем через gzip с помощью yuicompressor-maven-plugin:

<plugin>
    <groupId>net.alchim31.maven</groupId>
    <artifactId>yuicompressor-maven-plugin</artifactId>
    <version>1.2</version>
    <executions>
        <execution>
            <phase>process-resources</phase>
            <goals>
                <goal>compress</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <gzip>true</gzip>
        <preProcessAggregates>true</preProcessAggregates>
        <nosuffix>true</nosuffix>
        <jswarn>false</jswarn>
        <nomunge>true</nomunge>
        <aggregations>
            <aggregation>
                <insertNewLine>true</insertNewLine>
                <inputDir>src/main/webapp/resources/js/main</inputDir>
                <includes>
                    <include>**/*.js</include>
                </includes>
                <output>${project.build.directory}/${project.build.finalName}/resources/js/main.js</output>
            </aggregation>
        </aggregations>
    </configuration>
</plugin>

4. Для продуктовой среды используем сжатый файл

Теперь подменяем файл с подключением скриптов для продуктовой версии на scripts_prod.jsp:

<%@ page pageEncoding="UTF-8"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<script type="text/javascript" src="<spring:url value="/resources/js/main.js"/>"></script>

Лучше всего подмену файла включить в сборку проекта. Заменяем scripts.jsp на scripts_prod.jsp с помощью ant task:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.2</version>
 
    <executions>
        <execution>
            <id>prepare-to-production</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>run</goal>
            </goals>
            <configuration>
                <tasks>
                    <taskdef resource="net/sf/antcontrib/antcontrib.properties"
               classpath="${settings.localRepository}/ant-contrib/ant-contrib/1.0b3/ant-contrib-1.0b3.jar" />
 
                    <echo
                        message="checking if we need to replace debug scripts with the production ones" />
                    <if>
                        <equals arg1="${production}" arg2="true" />
                        <then>
                            <property name="preassembly-web-inf"
                                value="${project.build.directory}/preassembly/WEB-INF" />
                            <echo message="${preassembly-web-inf}" />
                            <echo
                                message="Deleting debug scripts.jsp and replacing it onto production one..." />
                            <copy file="${basedir}/src/main/webapp/WEB-INF/views/scripts_prod.jsp"
                                tofile="${preassembly-web-inf}/views/scripts.jsp" />
                        </then>
                        <else>
                            <echo
                                message="Executed in debug environment, so leaving the scripts unmoved" />
                        </else>
                    </if>
                </tasks>
            </configuration>
        </execution>
    </executions>
</plugin>

Подробнее про генерацию/замену файлов и про использование ant task в maven можно почитать в статье Генерация файлов с помощью Maven и AntTask.

Готово! И не забываем покрывать js-код тестами.

Далее:

Пятница, 04 Май 2012 в 09:50. Вы можете следить за комментариями к этой статье через RSS 2.0.