사용자 도구

사이트 도구


javascript:performance:closurecompiler

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판 이전 판
다음 판
이전 판
javascript:performance:closurecompiler [2012/10/23 14:16]
kwon37xi [역할]
javascript:performance:closurecompiler [2015/06/18 11:19] (현재)
kwon37xi [설치 사용]
줄 1: 줄 1:
 ====== Google Javascript Closure Compiler ====== ====== Google Javascript Closure Compiler ======
-  * [[https://developers.google.com/closure/compiler/|Google Closure Compiler]]+  * [[https://github.com/google/closure-compiler|Google Closure Compiler]] 
 +  * [[https://github.com/google/closure-compiler/wiki|Closure Compiler Wiki]]
  
 ===== 역할 ===== ===== 역할 =====
   * 불필요한 코드를 삭제하고, 공백등을 제거하여 용량을 줄여준다.   * 불필요한 코드를 삭제하고, 공백등을 제거하여 용량을 줄여준다.
   * 압축시 에러를 일으킬만한 문법(세미콜론 안 쓴 것등)을 자동 보정해준다.   * 압축시 에러를 일으킬만한 문법(세미콜론 안 쓴 것등)을 자동 보정해준다.
-  * 잘못된 코드에 경고를 보여준다. 특히 많이 실수하는 json의 마지막 쉼표 등을 찾아서 오류를 내준다.+  * 잘못된 코드에 경고와 에러를 내 주어서 브라우저까지 확인하지 않아도 오류를 알 수 있다. 특히 많이 실수하는 (IE 8 이하에서 안되는) json의 마지막 쉼표 등을 찾아서 오류를 내준다. 
 + 
 +===== 문제점 ===== 
 +  * ''float''을 키워드로 인식하는 버그가 있다. 
 +    * 이는 ClosureCompiler가 사용하는 Rhino 엔진이 ''float''을 키워드로 지정했기 때문인 것 같다. 
 +    * 웹 브라우저에서는 ''float''을 키워드로 보지 않는다. 
 +    * ''style.float = xx'' 갈은 구문이 있다면 ''style['float'] = xx''로 변경해야 한다. 
 +  * ''outputEncoding'' 을 명시하지 않으면 한글을 Unicode 기호로 바꾼다(\ucXXX 형태). 이 때문에 한글로 된 문자열이 많으면 파일 크기가 오히려 늘어난다. Ant로 할 경우 ''outputEncoding'' 옵션이 지정 안 되는 듯하다. [[http://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/javascript/jscomp/CompilerOptions.java|CompilerOptions]]
  
 ===== 설치 사용 ===== ===== 설치 사용 =====
줄 19: 줄 27:
   * [[https://developers.google.com/closure/compiler/docs/compilation_levels|컴파일 레벨]]   * [[https://developers.google.com/closure/compiler/docs/compilation_levels|컴파일 레벨]]
     * ''WHITESPACE_ONLY'' : 공백과 주석 제거등만 실행     * ''WHITESPACE_ONLY'' : 공백과 주석 제거등만 실행
-    * ''SIMPLE_OPTIMIZATIONS'' : 기본값. 공백제거, 세미콜론 보정등.+    * ''SIMPLE_OPTIMIZATIONS'' : 기본값. 공백제거, 세미콜론 보정등. 가끔 오보정이 일아났다.
     * ''ADVANCED_OPTIMIZATIONS'' : 더 강력한 압축. 불필요한 코드 삭제 등.     * ''ADVANCED_OPTIMIZATIONS'' : 더 강력한 압축. 불필요한 코드 삭제 등.
     * 적용<code sh>     * 적용<code sh>
줄 25: 줄 33:
 </code> </code>
   * Options   * Options
-    * ''--js VAL'' : 컴파일 대상 파일 +    * ''%%--%%js VAL'' : 컴파일 대상 파일 
-    * ''--js_output_file VAL'' : 컴파일 결과 파일. 저장하지 않으면 표준출력. +    * ''%%--%%js_output_file VAL'' : 컴파일 결과 파일. 저장하지 않으면 표준출력. 
-    * ''--charset VAL'' : 입출력 캐릭터셋 +    * ''%%--%%charset VAL'' : 입출력 캐릭터셋 
-    * ''--compilation-level [WHITESPACE_ONLY | SIMPLE_OPTIMIZATIONS | ADVANCED_OPTIMZATIONS]'' : 컴파일 레벨 지정+    * ''%%--%%compilation-level [WHITESPACE_ONLY | SIMPLE_OPTIMIZATIONS | ADVANCED_OPTIMZATIONS]'' : 컴파일 레벨 지정
  
 ===== Ant 연동 ===== ===== Ant 연동 =====
   * [[http://code.google.com/p/closure-compiler/wiki/BuildingWithAnt|Closure Compiler Building With Ant]]   * [[http://code.google.com/p/closure-compiler/wiki/BuildingWithAnt|Closure Compiler Building With Ant]]
   * [[http://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/javascript/jscomp/ant/CompileTask.java|CompileTask.java]]   * [[http://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/javascript/jscomp/ant/CompileTask.java|CompileTask.java]]
 +  * ''outputEncoding'' 적용 되는지 확인해볼 것.
 <code xml> <code xml>
 <?xml version="1.0"?> <?xml version="1.0"?>
줄 66: 줄 74:
 </code> </code>
  
 +
 +===== Closure Compiler API ===== 
 +  * [[https://github.com/eriwen/gradle-js-plugin/blob/master/src/main/groovy/com/eriwen/gradle/js/JsMinifier.groovy|JsMinifier.groovy]]에서 [[https://developers.google.com/closure/compiler/|ClosureCompiler]]의 API 사용법 예제를 볼 수 있다.
 +  * 혹은 ''com.google.javascript.jscomp.CommandLineRunner'' 참조
 +  * 일괄 Minify 예<code java>
 +import java.io.*;
 +import java.nio.charset.Charset;
 +import java.nio.file.*;
 +import java.nio.file.attribute.BasicFileAttributes;
 +import java.util.ArrayList;
 +import java.util.List;
 +
 +import com.google.javascript.jscomp.*;
 +import com.google.javascript.jscomp.Compiler;
 +
 +public class BatchJsMinify {
 +    private static final String[] EXCLUDE_PATTERNS = { ".min.js", "-min.js" };
 +    private static final CompilationLevel DEFAULT_COMPILATION_LEVEL = CompilationLevel.SIMPLE_OPTIMIZATIONS;
 +
 +    private String srcDirName;
 +    private final File srcDir;
 +
 +    private String destDirName;
 +    private final File destDir;
 +
 +    private com.google.javascript.jscomp.Compiler compiler = new Compiler();;
 +    private CompilerOptions options = new CompilerOptions();
 +    private WarningLevel warningLevel = WarningLevel.QUIET;
 +
 +    public BatchJsMinify(String srcDirName, String destDirName) {
 +        this.srcDirName = srcDirName;
 +        this.destDirName = destDirName;
 +        srcDir = new File(srcDirName);
 +        destDir = new File(destDirName);
 +
 +        if (!srcDir.exists() || !srcDir.isDirectory()) {
 +            throw new IllegalArgumentException(srcDirName + " must exist and be a directory.");
 +        }
 +
 +        destDir.mkdirs();
 +    }
 +
 +    public void compile() throws IOException {
 +        options.setCodingConvention(CodingConventions.getDefault());
 +        options.setOutputCharset("UTF-8");
 +
 +        warningLevel.setOptionsForWarningLevel(options);
 +        DEFAULT_COMPILATION_LEVEL.setOptionsForCompilationLevel(options);
 +
 +        final List<SourceFile> jsSourceFiles = getSourceFiles();
 +
 +        if (jsSourceFiles == null || jsSourceFiles.size() == 0) {
 +            System.out.println("Nothing to compile.");
 +            return;
 +        }
 +
 +        final List<SourceFile> defaultExterns = CommandLineRunner.getDefaultExterns();
 +
 +        compiler.disableThreads(); // thread가 활성화 돼 있으면 오히려 종료가 늦게 되었다.
 +        final Result result = compiler.compile(defaultExterns, jsSourceFiles, options);
 +
 +        if (result.success) {
 +            writeToFile(jsSourceFiles);
 +        } else {
 +            printErrors(result);
 +        }
 +
 +    }
 +
 +    private void printErrors(Result result) {
 +        for (JSError error : result.errors) {
 +            System.err.println("Error : " + error.sourceName + ":" + error.lineNumber + " - " + error.description);
 +        }
 +    }
 +
 +    private List<SourceFile> getSourceFiles() throws IOException {
 +        final List<SourceFile> jsSourceFiles = new ArrayList<>();
 +        Files.walkFileTree(Paths.get(srcDirName), new SimpleFileVisitor<Path>() {
 +                @Override
 +                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
 +                throws IOException {
 +                String filename = file.toString();
 +
 +                if (filename.endsWith(".js") && !filename.endsWith(".min.js") && !filename.endsWith("-min.js")) {
 +                final SourceFile sourceFile = SourceFile.fromFile(file.toFile(), Charset.forName("UTF-8"));
 +                jsSourceFiles.add(sourceFile);
 +                }
 +                return FileVisitResult.CONTINUE;
 +                }
 +                });
 +        return jsSourceFiles;
 +    }
 +
 +    private void writeToFile(List<SourceFile> jsSourceFiles) {
 +        final String[] minified = compiler.toSourceArray();
 +
 +        for (int i = 0; i < jsSourceFiles.size(); i++) {
 +            final SourceFile sourceFile = jsSourceFiles.get(i);
 +            String fileRestPath = sourceFile.getOriginalPath().replace(srcDirName, "");
 +            final File destFile = new File(destDir, fileRestPath);
 +            destFile.getParentFile().mkdirs();
 +
 +            System.out.println("Writing minified js file : " + destFile.getAbsolutePath());
 +
 +            try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(destFile), "UTF-8"))) {
 +                writer.write(minified[i]);
 +            } catch (IOException e) {
 +                throw new IllegalStateException("minified js file save error.", e);
 +            }
 +        }
 +    }
 +}
 +</code>
javascript/performance/closurecompiler.1350969363.txt.gz · 마지막으로 수정됨: 2012/10/23 14:16 저자 kwon37xi