1. 概述

本文将展示如何在构建步骤中压缩JavaScript和CSS资源,并使用Spring MVC提供这些压缩后的文件。我们将使用YUI Compressor作为底层压缩库,并利用YUI Compressor Maven插件将其集成到我们的构建流程中。

2. Maven插件配置

首先,我们需要在pom.xml文件中声明使用压缩器插件,并执行compress目标。这将压缩src/main/webapp目录下的所有.js.css文件,例如foo.js会被压缩为foo-min.jsmyCss.css会被压缩为myCss-min.css

<plugin>
   <groupId>net.alchim31.maven</groupId>
    <artifactId>yuicompressor-maven-plugin</artifactId>
    <version>1.5.1</version>
    <executions>
        <execution>
            <goals>
                <goal>compress</goal>
            </goals>
        </execution>
    </executions>
</plugin>

我们的src/main/webapp目录包含以下文件:

js/
├── foo.js
├── jquery-1.11.1.min.js
resources/
└── myCss.css

执行mvn clean package后,生成的WAR包将包含以下文件:

js/
├── foo.js
├── foo-min.js
├── jquery-1.11.1.min.js
├── jquery-1.11.1.min-min.js
resources/
├── myCss.css
└── myCss-min.css

3. 保持文件名不变

当前,当我们执行mvn clean package时,插件会创建foo-min.jsmyCss-min.css。由于我们在引用文件时原本使用的是foo.jsmyCss.css,所以页面仍然会使用原始未压缩的文件,因为压缩后的文件名称与原始文件不同。

为了防止出现foo.js/foo-min.jsmyCss.css/myCss-min.css的情况,同时让文件在不改变名称的情况下被压缩,我们需要配置插件使用nosuffix选项:

<plugin>
    <groupId>net.alchim31.maven</groupId>
    <artifactId>yuicompressor-maven-plugin</artifactId>
    <version>1.5.1</version>
    <executions>
        <execution>
            <goals>
                <goal>compress</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <nosuffix>true</nosuffix>
    </configuration>
</plugin>

现在执行mvn clean package,生成的WAR包中将包含以下文件:

js/
├── foo.js
├── jquery-1.11.1.min.js
resources/
└── myCss.css

4. WAR插件配置

保持文件名不变的效果是,它会导致WAR插件覆盖压缩后的foo.jsmyCss.css文件,因此最终输出中没有压缩版本的文件。在压缩前,foo.js文件的内容如下:

function testing() {
    alert("Testing");
}

查看生成的WAR包中foo.js文件的内容,我们会发现它仍然包含原始内容,而不是压缩后的内容。为了解决这个问题,我们需要为压缩器插件指定一个webappDirectory,并在WAR插件配置中引用这个目录。

<plugin>
    <groupId>net.alchim31.maven</groupId>
    <artifactId>yuicompressor-maven-plugin</artifactId>
    <version>1.5.1</version>
    <executions>
        <execution>
            <goals>
                <goal>compress</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <nosuffix>true</nosuffix>
        <webappDirectory>${project.build.directory}/min</webappDirectory>
    </configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
    <webResources>
        <resource>
            <directory>${project.build.directory}/min</directory>
        </resource>
    </webResources>
</configuration>
</plugin>

在这里,我们指定了min目录作为压缩文件的输出目录,并配置WAR插件将此目录包含在最终输出中。

现在,生成的WAR包中包含了名为foo.jsmyCss.css的压缩文件。我们可以检查foo.js,确认其内容已压缩为:

function testing(){alert("Testing")};

5. 排除已压缩文件

第三方JavaScript和CSS库可能已经提供了压缩版本供下载。如果你的项目中使用了其中一个,就不需要再次处理它们。

包括已压缩文件在构建项目时会产生警告信息。

例如,jquery-1.11.1.min.js是一个已经压缩的JavaScript文件,构建过程中会产生类似以下的警告信息:

[WARNING] .../src/main/webapp/js/jquery-1.11.1.min.js [-1:-1]: 
Using 'eval' is not recommended. Moreover, using 'eval' reduces the level of compression!
execScript||function(b){a. ---> eval <--- .call(a,b);})
[WARNING] ...jquery-1.11.1.min.js:line -1:column -1: 
Using 'eval' is not recommended. Moreover, using 'eval' reduces the level of compression!
execScript||function(b){a. ---> eval <--- .call(a,b);})

要排除已压缩文件从处理流程中,可以配置压缩器插件使用excludes选项,如下所示:

<plugin>
    <groupId>net.alchim31.maven</groupId>
    <artifactId>yuicompressor-maven-plugin</artifactId>
    <version>1.5.1</version>
    <executions>
        <execution>
            <goals>
                <goal>compress</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <nosuffix>true</nosuffix>
        <webappDirectory>${project.build.directory}/min</webappDirectory>
        <excludes>
            <exclude>**/*.min.js</exclude>
        </excludes>
    </configuration>
</plugin>

这将排除所有以min.js结尾的目录下的所有文件。现在执行mvn clean package不会产生警告信息,也不会尝试压缩已经压缩过的文件。

6. 总结

本文介绍了将JavaScript和CSS文件压缩整合到Maven工作流中的方法。要与Spring MVC应用一起提供这些静态资源,请参阅我们的使用Spring为静态资源提供服务文章。

您可以在GitHub上找到本文的代码示例。


« 上一篇: Spring Boot Starter简介