为 java/spring/maven 应用程序组合和压缩 javascript/css 的不显眼方式?

Posted

技术标签:

【中文标题】为 java/spring/maven 应用程序组合和压缩 javascript/css 的不显眼方式?【英文标题】:Unobtrusive way to combine and compress javascript/css for java/spring/maven applications? 【发布时间】:2012-01-02 23:03:49 【问题描述】:

我想添加某种库、maven 插件或“某些东西”来组合和压缩我的 javascript 和 css 源文件。

但是,我认为使用 Java 很难不引人注意地做到这一点。 Rails 的人几乎解决了这个问题……它使用未连接/未压缩的文件进行开发,然后在生产过程中压缩所有内容。它不显眼地做到这一点,因为您不必更改 html 标头或类似的东西 - 它适用于测试和生产。这或多或少是我想要的。它甚至存在于 Java 空间中吗?

我想要的最后一件事是注释和取消注释用于开发和生产的 freemarker/html 代码行 - 我希望一切都相同。理想情况下,我希望能够让 Tomcat 继续运行并编写我的 javascript 和 css 代码,并立即看到我的更改——没有延迟或中断。我也不想每次进行更改时都必须手动运行命令来生成新的 javascript... 甚至让一些守护进程不断更新它(因为在我测试时它可能不是即时的)。同时,如果我要打包我的战争进行生产,我希望它使用连接和压缩的文件。

这甚至可能吗?如果是这样,我应该看什么工具?我知道有不少人这样做了,但他们在“不引人注目”方面做得不够。

谢谢

【问题讨论】:

【参考方案1】:

一个对我有用的解决方案是使用maven-minify-plugin(groupId 是com.samaxes.maven),但用于生产。使用构建属性来指定您是否处于开发模式。 Link to plugin

然后你可以有这样的东西(我不知道freemarker,所以我只是粘贴一些JSP代码,但我确信它可以很容易地转换):

<c:choose>
    <c:when test="$developmentMode">
        <link rel="stylesheet" type="text/css" href="<c:url value="/css/custom1.css"/>"/>
        <link rel="stylesheet" type="text/css" href="<c:url value="/css/custom2.css"/>"/>
        <link rel="stylesheet" type="text/css" href="<c:url value="/css/another1.css"/>"/>
        <link rel="stylesheet" type="text/css" href="<c:url value="/css/another2.css"/>"/>
        <script type="text/javascript" src="<c:url value="/js/mylibrary.js"/>"></script>
        <script type="text/javascript" src="<c:url value="/js/more.js"/>"></script>
        <script type="text/javascript" src="<c:url value="/js/util.js"/>"></script>
        <script type="text/javascript" src="<c:url value="/js/whatever.js"/>"></script>
        <script type="text/javascript" src="<c:url value="/js/more.js"/>"></script>
    </c:when>
    <c:otherwise>
        <link rel="stylesheet" type="text/css" href="<c:url value="/css/minified.css"/>"/>
        <script type="text/javascript" src="<c:url value="/js/minified.js"/>"></script>
    </c:otherwise>
</c:choose> 

这种方式在开发时使用非缩小/组合的 JS/css,而缩小的 css 仅在构建生产时使用。

编辑:这里要求的是在 ServletContext 上公开 Spring 定义的 bean 的代码:

<bean class="org.springframework.web.context.support.ServletContextAttributeExporter">
    <property name="attributes">
        <map>
            <!-- Obviously this can be changed to read from properties file -->
            <entry key="developmentMode" value="false" /> 
        </map>
    </property>
</bean>

【讨论】:

那么我是否有一个spring mvc拦截器将developmentMode变量传递给所有控制器视图?这是唯一的方法吗? 有什么...我不知道...有点工业实力?我将拥有至少 50 个 javascript 文件……可能是 100-150 个。 我认为不需要拦截器。我使用 org.springframework.web.context.support.ServletContextAttributeExporter 将 Spring 定义的对象公开为 SerletContext 属性。 啊,我不知道你能做到这一点。你能剪切/粘贴你必须启用的代码吗? ServletContextAttributeExporter的bean定义更新问题。【参考方案2】:

Jawr 是一个提供 css/js 文件压缩和合并的库。它为 html include 语句提供了一个标签。 这使得可以使用相同的未修改 JSP 页面进行开发(使用未修改的 css/js)和生产(合并和缩小)。

wro4j 接缝到相似的特征。

【讨论】:

【参考方案3】:

使用maven-minify-plugin也为我工作。

但我设法找到了一种比使用c:when 之类的条件标签更不打扰的方式,方法是将它与maven-war-plugin 结合使用。

这段代码sn-p可以直接使用:

首先,首先缩小 CSS/JS 而不使用后缀(意味着文件保留其名称)

<plugin>
    <groupId>com.samaxes.maven</groupId>
    <artifactId>minify-maven-plugin</artifactId>
    <version>1.7.2</version>
    <executions>
        <execution>
            <id>default-minify</id>
            <phase>prepare-package</phase>
            <configuration>
               <charset>UTF-8</charset>
               <skipMerge>true</skipMerge> <!-- do not create one big file -->
               <nosuffix>true</nosuffix> <!-- do not use suffix like 'min' -->

               <cssSourceDir>css</cssSourceDir>
               <cssSourceIncludes>
                   <cssSourceInclude>*.css</cssSourceInclude>
               </cssSourceIncludes>

               <jsSourceDir>js</jsSourceDir>
               <jsSourceIncludes>
                   <jsSourceInclude>*.js</jsSourceInclude>
               </jsSourceIncludes>

           </configuration>
           <goals>
               <goal>minify</goal>
           </goals>
       </execution>
   </executions>

然后,在构建 war 文件时,不要覆盖 CSS/JS 文件(它们已经在目标中由 minify 目标生成)

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.4</version>
    <configuration>
        <!-- in order to use minify filed listed bellow -->
        <warSourceExcludes>**/*.css, **/*.js</warSourceExcludes>
    </configuration>
</plugin>

构建的战争将包含完全相同的文件,但已压缩。 (这可能不是执行缩小的最佳方式,但不会改变开发中的任何内容)

希望这会有所帮助...

【讨论】:

以上是关于为 java/spring/maven 应用程序组合和压缩 javascript/css 的不显眼方式?的主要内容,如果未能解决你的问题,请参考以下文章

Spring AOP + AspectJ maven 插件 - 内部方法调用不起作用

如何使用 Netflix DGS graphql-dgs-extended-scalars JSON 标量(java/spring-boot,maven)?

flyway 后的 Flyway 迁移错误:基线

为 Lync 响应组启用呼叫转接

将功能应用于每个组,其中组被拆分为多个文件,而不连接所有文件

Firebase 云消息传递为一组用户发送通知