带有 wro4j 和 Google Closure 编译器的 ECMASCRIPT 5

Posted

技术标签:

【中文标题】带有 wro4j 和 Google Closure 编译器的 ECMASCRIPT 5【英文标题】:ECMASCRIPT 5 with wro4j and Google Closure Compiler 【发布时间】:2012-12-14 03:22:56 【问题描述】:

我们正在使用 wro4j 与 Google Closure 和 Maven 来缩小我们的 JS。默认情况下,它不支持 JS 中的严格模式(“使用严格”;).. 它只是将其剥离。我可以在pom.xml 或其他地方进行任何配置以使其将use strict 留在其中吗?

这是 google 闭包编译器的配置:

--language_in=ECMASCRIPT5_STRICT

不确定如何将其插入 Wro4j。有什么想法吗?

【问题讨论】:

您能否提供一个您尝试最小化的脚本示例。还有什么是预期和实际输出?这可能是谷歌关闭的问题......而不是 wro4j 问题。 【参考方案1】:

创建一个添加 ECMAScript5 的管理器工厂的自定义实现:

public class MyCustomWroManagerFactory
extends DefaultStandaloneContextAwareManagerFactory
  
  @Override 
    protected ProcessorsFactory newProcessorsFactory() 
      
      final SimpleProcessorsFactory factory = new SimpleProcessorsFactory(); 

      factory.addPreProcessor(
           new GoogleClosureCompressorProcessor(
             CompilerOptions.LanguageMode.ECMASCRIPT5_STRICT
                                               )
                        ); 

      return factory;
      
  

在 pom.xml 中引用它作为 wroManagerFactory 节点的值:

<configuration>
  <wroManagerFactory>com.mycompany.MyCustomWroManagerFactory</wroManagerFactory>
</configuration>

根据 Closure Compiler 项目的 John Lenz 所说,如果您直接使用 Compiler API,则应指定 CodingConvention。

参考文献

GoogleClosureCompressorProcessor.java - method setCompilerOptions

GoogleClosureCompressorProcessor.java - optionsPool method

Closure Compiler Service API Reference - language |  Closure Compiler  |  Google Developers

【讨论】:

GoogleClosureCompressorProcessor 似乎没有将 LanguageMode 作为其构造函数的参数。事实上,据我所知,GoogleClosureCompressorProcessor 不再有任何方法来设置 CompilerOptions。 您现在必须继承 GoogleClosureCompressorProcessor 并覆盖 newCompilerOptions() 来设置您的自定义选项。【参考方案2】:

wro4j-maven-plugin 1.8 中稍微复杂一些,但还不错。

您需要添加两个 Java 类。首先覆盖newCompilerOptions of GoogleClosureCompressorProcessor,如下所示:

package com.example.package.wro;

import com.google.javascript.jscomp.CheckLevel;
import com.google.javascript.jscomp.ClosureCodingConvention;
import com.google.javascript.jscomp.CompilerOptions;
import com.google.javascript.jscomp.DiagnosticGroups;
import java.nio.charset.Charset;
import org.apache.commons.lang3.CharEncoding;
import ro.isdc.wro.extensions.processor.js.GoogleClosureCompressorProcessor;

/**
 * Custom processor overriding `newCompilerOptions` to add custom compiler options.
 *
 * Original author: Alex Objelean.
 */
public class CustomGoogleClosureCompressorProcessor extends GoogleClosureCompressorProcessor 

    /**
     * Encoding to use.
     */
    public static final String ENCODING = CharEncoding.UTF_8;

    @Override
    protected CompilerOptions newCompilerOptions() 
        final CompilerOptions options = new CompilerOptions();

        // Set the language_in option on the Google Closure Compiler to prevent errors like:
        // "JSC_TRAILING_COMMA. Parse error. IE8 (and below)"
        options.setLanguageIn(CompilerOptions.LanguageMode.ECMASCRIPT5);

        /**
         * According to John Lenz from the Closure Compiler project, if you are using the Compiler API directly, you should
         * specify a CodingConvention. @link http://code.google.com/p/wro4j/issues/detail?id=155
         */
        options.setCodingConvention(new ClosureCodingConvention());
        // use the wro4j encoding by default
        //options.setOutputCharset(Charset.forName(getEncoding()));
        setEncoding(ENCODING);
        options.setOutputCharset(Charset.forName(ENCODING));
        // set it to warning, otherwise compiler will fail
        options.setWarningLevel(DiagnosticGroups.CHECK_VARIABLES, CheckLevel.WARNING);
        return options;
    

你会注意到我已经注释掉了getEncoding 这一行。这是因为它是私人的。为了以防万一,我还添加了setEncoding

然后我们需要自定义管理器:

package com.example.package.wro;

import ro.isdc.wro.manager.factory.standalone.DefaultStandaloneContextAwareManagerFactory;
import ro.isdc.wro.model.resource.processor.factory.ProcessorsFactory;
import ro.isdc.wro.model.resource.processor.factory.SimpleProcessorsFactory;

/**
 * Custom manger adding custom processor.
 */
public class CustomWroManagerFactory extends DefaultStandaloneContextAwareManagerFactory 

    @Override
    protected ProcessorsFactory newProcessorsFactory() 
        final SimpleProcessorsFactory factory = new SimpleProcessorsFactory();

        factory.addPreProcessor(
            new CustomGoogleClosureCompressorProcessor()
        );

        return factory;
    

然后在 wroManagerFactory 中的 pom.xml 中使用它。像这样:

        <plugin>
            <groupId>ro.isdc.wro4j</groupId>
            <artifactId>wro4j-maven-plugin</artifactId>
            <version>1.8.0</version>
            <executions>
                <execution>
                    <phase>compile</phase>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
            </executions>
            <!-- Google Closure Compiler -->
            <!-- http://www.gzfs020.com/using-google-closure-compiler-with-wro4j-maven-plugin.html -->
            <configuration>
                <contextFolder>$basedir/src/main</contextFolder>
                <wroFile>$basedir/src/main/config/wro.xml</wroFile>
                <destinationFolder>$project.build.directory/$project.build.finalName/min</destinationFolder>
                <!--
                <wroManagerFactory>ro.isdc.wro.extensions.manager.standalone.GoogleStandaloneManagerFactory</wroManagerFactory>
                -->
                <wroManagerFactory>com.example.package.wro.CustomWroManagerFactory</wroManagerFactory>
            </configuration>
        </plugin>

【讨论】:

以上是关于带有 wro4j 和 Google Closure 编译器的 ECMASCRIPT 5的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Google 的 Closure 库不在他们的 CDN 上托管?

使用 Google Closure Compiler 编译的 jQuery

Google Closure 编译器:默认 CompilerOptions

Google Closure:如何渲染 2 个组件

google closure 笔记-SOY template

使用 Google Closure Compiler 时如何防止关键字被混淆?