【工具推荐】告别YUI Compressor,ES6代码压缩实战,让你的静态资源节约50%的空间

现状

一次在公司的旧项目中的JavaScript使用了es6的语法如let时,打包代码出现了问题:

[ERROR] ...\src\main\webapp\pages\modules\main\order.js:line 81:column 16:missing ; before statement
					let formObj = this.getForm();
[ERROR] ...\src\main\webapp\pages\modules\main\order.js:line 1:column 0:Compilation produced 1 syntax errors.

[ERROR] Failed to execute goal net.alchim31.maven:yuicompressor-maven-plugin:1.3.0:compress (default) on project ydt-web: Execution default of goal net.alchim31.maven:yuicompressor-maven-plugin:1.3.0:compress failed: Compilation produced 1 syntax errors. -> [Help 1]

问题分析

  • YUI Compressor(下文简称为YUI)不支持es6语法,且已经很长时间不更新了
    YUI插件不支持对ES6语法的JavaScript进行压缩
  • Maven插件yuicompressor-maven-plugin也已经在2022年进入归档状态,不再维护,因为该插件的维护者都认为YUI已经不适用于主流的JavaScript开发了
    YUI maven插件的作者归档了项目
  • 而我们的项目也因为每次有新员工修改它时都会遇到语法的这个问题,所以我们想彻底解决它。

需求

  1. 线上的JavaScriptCSS文件需要压缩减小体积,提升网页打开的效率
  2. 支持es6语法,降低开发复杂度
  3. 只在打包时压缩代码,开发时的源代码不压缩,避免代码混乱难以维护
  4. 使用的插件最好近期有更新维护,避免遇到问题无法获得技术支持

方案搜寻

  1. YUIissue中找到了另一个支持压缩es6语法的插件minify-maven-plugin,但这个插件我使用的时候出现了一个问题,写了如下的代码会报错:
// 花括号的最后一个元素不能有逗号
var a = {
    test1: 1,
    test2: 2,
}

虽然后面也在issue中找到了解决方法(设置closureLanguage),但发现这个项目已经很久没再维护,使用手册也已经404了,因此这个插件也被pass掉

  1. 再之后看到resources-optimizer-maven-plugin的作者自荐,发现这个插件满足我们上面的需求,而且表明修复了YUI的问题,就决定采用这个插件
    在这里插入图片描述

下面是添加resources-optimizer-maven-plugin插件依赖的代码:

<plugin>
    <groupId>org.primefaces.extensions</groupId>
    <artifactId>resources-optimizer-maven-plugin</artifactId>
    <!-- 目前支持jdk8的最新版本 -->
    <version>2.4.4</version>
</plugin>

项目在打包过程中看到控制台输出了以下内容说明成功引入:
执行压缩
完成后会显示压缩情况,在我们的项目中的JavaScriptCSS压缩了50%+
压缩完成后会显示总压缩量

实现过程的踩坑

  1. 使用resources-optimizer-maven-plugin后源代码被压缩
    • 在maven的生命周期maven-resources-plugin中进行操作
    • 修改压缩代码的来源目录
  2. 打包成war包后,里面的JavaScript却是未压缩的源码
    • JavaScript文件在压缩之后,到maven的生成war包环节时会重新将JavaScriptCSS等内容复制,因此我们需要在maven-war-plugin中配置不复制JavaScriptCSS文件(见下文代码实现的构建期间<build>配置)

代码实现

在进行了一圈的搜罗后,使用了resources-optimizer-maven-plugin插件,并在pom.xml文件中加入如下配置:

压缩插件引入及配置

<plugin>
    <groupId>org.primefaces.extensions</groupId>
    <artifactId>resources-optimizer-maven-plugin</artifactId>
    <!-- 支持jdk8下的最新版本,再往上的版本就不支持jdk8了 -->
    <version>2.4.4</version>
    <executions>
        <execution>
            <id>optimize</id>
            <!-- 只在准备打包时执行 -->
            <phase>prepare-package</phase>
            <goals>
                <goal>optimize</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <!-- 是否不执行压缩 -->
        <skip>false</skip>
        <!-- 压缩级别 -->
        <compilationLevel>SIMPLE_OPTIMIZATIONS</compilationLevel>
        <!-- js规范版本 -->
        <languageIn>ECMASCRIPT_2015</languageIn>
        <resourcesSets>
            <resourcesSet>
                <!-- js文件所在的目录,如果不配置的话会将全部js进行压缩 -->
                <inputDir>${project.build.directory}/${package.name}</inputDir>
                <includes>
                   <!-- 需要压缩的文件,支持通配符 -->
                   <include>**/*.js</include>
                   <include>**/*.css</include>
                </includes>
                <excludes>
                   <!-- 不压缩的文件,支持通配符 -->
                   <exclude>**/*.min.js</exclude>
                </excludes>
            </resourcesSet>
        </resourcesSets>
    </configuration>
</plugin>

构建期间配置

<build>
    <plugins>
        <!-- 打为war包时 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <configuration>
                <!--
                    如果不增加此配置   src/main/webapp 下面的内容 会重新复制到target输出目录 覆盖掉编译后的内容
                    这样编译的还是未压缩过的内容,增加上此过滤  打war包就不会内容覆盖-->
                <warSourceExcludes>**/*.js, **/*.css</warSourceExcludes>
            </configuration>
        </plugin>
        <!-- 处理静态资源目录时 -->
        <plugin>
            <!-- 在maven的构建阶段把js文件复制到target目录下 -->
            <artifactId>maven-resources-plugin</artifactId>
            <executions>
                <execution>
                    <id>copy-js-resources</id>
                    <phase>generate-resources</phase>
                    <goals>
                        <goal>copy-resources</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${project.build.directory}/${package.name}</outputDirectory>
                        <resources>
                            <resource>
                                <directory>${project.basedir}/src/main/webapp</directory>
                                <filtering>true</filtering>
                                <includes>
                                    <include>**/*.js</include>
                                    <include>**/*.css</include>
                                </includes>
                            </resource>
                        </resources>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

总结

使用resources-optimizer-maven-plugin插件的优势如下:

  1. 更多的压缩方式:支持Google Closure CompilerJavaScript编译压缩方式和YUICSS的压缩方式
  2. 对于新语法有更好的支持Google Closure Compiler对于es6支持良好,其JavaScript的压缩效果也比YUI更好
  3. 更好的技术支持:此插件最近一次维护时间是2024年10月1日,目前所有issue已经是解决状态,反观minify-maven-pluginyuicompressor-maven-plugin都已经多年未维护,所以推荐有需要的可以看看这个新插件

带来的问题思考

  1. Google Closure Compiler对于JavaScript的编写会更严格,当存在不规范的写法时会报错,如同一个方法名在一个JavaScript文件中出现两次
  2. 前后端分离的项目应该用不上这个插件,现在的vue项目都有webpack之类的自动压缩转换JavaScript的工具,因此这个插件可能更多用于老项目上

参考链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值