Locked History Actions

Closure_Library/closurebuilder

Closure Builder

http://code.google.com/intl/ja/closure/library/docs/closurebuilder.htmlの訳(予定)

ClosureBuilderの使用

Getting Started with the Closure Library illustrates how to start working with Closure Library in your project. This article outlines how to use ClosureBuilder and Closure Compiler with your project to shrink your files into one, small, minimized JavaScript file.

なぜclosurebuilder.py?

If you did the Hello World exercise in Getting Started with the Closure Library, you may have noticed that the browser made several HTTP requests during page load. For each Closure Library file required by goog.require(), a new script tag is created to load the file. Each Closure Library file is loaded as a separate HTTP request.

This works well for development, since one can see the uncompiled source and use existing debugging tools. But it's not good for serving to users. Loading all these files individually is unnecessary and slow.

For a live application serving to real users, you're going to want to serve a "compiled" version of your app. Closure Compiler takes your code and the required Closure Library files, strip comments, does some optimizations, and creates one larger file as output. Your server can then just serve that one file rather than many individual files.

closure/bin/buildディレクトリにあるclosurebuilder.pyツールはコンパイル済JavaScriptを生成するのに使用される。 これは君のファイルとclosure libraryのファイルをスキャンし、依存順序を計算する。 そして、その依存順にスクリプトのファイル名あるいはその中身を出力する、あるいはClosure Compilerにそれらを渡し、コンパイル済バージョンを生成する。

closurebuilder.pyによるClosure Libraryの依存解決

この例では、closurebuilder.pyを使って必要なものすべてを単一のスクリプトファイルに格納する。

まだやっていないようなら、Getting Startedの指示に従って、Closure Libraryをダウンロードして解凍しておくこと。 closure-libraryを格納したディレクトリの中にmyprojectという名称のディレクトリを作成しておこう。

myprojectディレクトリの中にstart.jsを作成し、以下のコードを記述する。

goog.provide('myproject.start');

goog.require('goog.dom');

myproject.start = function() {
  var newDiv = goog.dom.createDom('h1', {'style': 'background-color:#EEE'},
    'Hello world!');
  goog.dom.appendChild(document.body, newDiv);
};

// Ensures the symbol will be visible after compiler renaming.
goog.exportSymbol('myproject.start', myproject.start);

同じディレクトリ中に、このスクリプトを起動するためのmyproject.htmlという単純なHTMLファイルを作成する。

<!doctype html>
<html>
  <head>
    <script src="../closure-library/closure/goog/base.js"></script>
    <script src="start.js"></script>
  </head>
  <body>
    <script>
      myproject.start();
    </script>
  </body>
</html>

このページをブラウザにロードすると、"Hello, World!"というメッセージが表示されるはずだ。

依存の計算

closure-libraryとmyprojectを含むディレクトリで、以下のコマンドを実行してみよう。

closure-library/closure/bin/build/closurebuilder.py \
  --root=closure-library/ \
  --root=myproject/ \
  --namespace="myproject.start"

注意:これらのツールは実行可能Pythonスクリプトで、UNIXシステムでは、/usr/bin/envによって解釈される(訳注?)。Windowsの場合にはpythonドキュメントを参照すること。

出力は以下のようになる(これは、標準出力と標準エラーを混ぜている)。

closure-library/closure/bin/build/closurebuilder.py: Scanning paths...
closure-library/closure/bin/build/closurebuilder.py: 596 sources scanned.
closure-library/closure/bin/build/closurebuilder.py: Building dependency tree..
closure-library/closure/goog/base.js
closure-library/closure/goog/debug/error.js
closure-library/closure/goog/string/string.js
closure-library/closure/goog/asserts/asserts.js
closure-library/closure/goog/array/array.js
closure-library/closure/goog/dom/classes.js
closure-library/closure/goog/object/object.js
closure-library/closure/goog/dom/tagname.js
closure-library/closure/goog/useragent/useragent.js
closure-library/closure/goog/math/size.js
closure-library/closure/goog/math/coordinate.js
closure-library/closure/goog/dom/dom.js
myproject/start.js

何をやっているのか

各-rootフラグはClosureBuilderに.jsファイルをスキャンさせるディレクトリを示す。 各ファイルについてgoog.provide及びgoog.require文がスキャンされるが、これらはnamespaceの供給と、他のファイルによって供給されるnamespaceの要求を示している。

ClosureBuilderは全ファイルをスキャンすることによって、全namespaceの依存ツリーをメモリ上に構築する。 --namespaceフラグにによってClosureBuilderは、このツリー上でmyproject.startというnamespaceから開始して、そのすべての依存を取得するように指示される。

デフォルトでは、その出力は依存順のファイルリストになる。 このリスト中では、すべての要求されるnamespaceは別のファイルによって供給されるが、それらはリストの中で前に現れることになる。

ClosurebuilderとClosure Compilerによるコードの短縮

君のコードのコンパイルされ短縮されたバージョンを得るには、--output_modeを使う(訳注?)。

コンパイル出力を得るには、Closure Compiler実行形式jarファイルが必要であり、ClosureBuilderにその場所を教える必要がある。 リポジトリからjarファイルをダウンロードし、closure-libraryディレクトリのあるディレクトリに置いておこう。

closurebuilder.pyには二つのフラグを与える。つまり、コンパイル済出力の要求とcompiler.jarの位置の指示だ。

closure-library/closure/bin/build/closurebuilder.py \
  --root=closure-library/ \
  --root=myproject/ \
  --namespace="myproject.start" \
  --output_mode=compiled \
  --compiler_jar=compiler.jar \
  > myproject/start-compiled.js

ClosureBuilderはコンパイラの出力を標準出力に書きこむ。 これをstart-compiled.jsというファイルにリダイレクトする。 --output_filesフラグを使う方法もある(Unixスタイルのパイプに親しみの無い場合はこの方が簡単だろう)。

start-compiled.jsファイルをmyproject.htmlと同じ場所に置き、コンパイル済バージョンを使うようにhtmlを変更しよう。

<!doctype html>
<html>
  <head>
    <script src="start-compiled.js"></script>
  </head>
  <body>
    <script>
      myproject.start();
    </script>
  </body>
</html>

このファイルは君のオリジナルのコードと同一のふるいまいをするはずだが、しかし、ダウンロードすべきJavaScriptは一つの小さなものになる。

ClosureBuilderをWebサーバ中とビルドシステム中にて使用する

Generally, developers using Closure Library implement the ability to serve in debug and compiled modes.

  • In debug mode, the server serves the uncompiled files. In the HTML, the head tag includes script tags that point at Closure Library's base.js and the project .js files, as in the example above. There may also be additional dependency files as described in the DepsWriter documentation. In compiled mode, the server does not serve the uncompiled files. In the head tag, there is just one script tag that points at the compiled JavaScript file, as in the example above.

The served web page should have the appropriate <script> tags for each mode.

It's much easier to work with uncompiled code when developing. You can edit and save your files and reload to see changes. Errors give correct line numbers and you can use in-browser debuggers with uncompiled, unobfuscated source.

But when serving your application, the compiled version is preferable. Compiled output loads quickly and speed is very important when you serve to users. The compiler optimizes the size of the JavaScript and puts it in one small file rather than many uncompiled files.

Closure Compiler also offers Closure Inspector, a Firefox plugin that can help debug compilation problems.

ビルドシステムでの使用

ClosureBuilder is provided as a standalone command-line tool so that it can be incorporated into different build systems. You can set up ClosureBuilder's output to be a step in your build system. Additional flags to Closure Compiler

Closure Compiler takes its own additional flags for particular features, so ClosureBuilder has a way of specifying flags to pass along to the compiler. This can be done using the --compiler_flags flag. For example, we can tell the compiler to use its advanced optimization mode by including this additional flag:

closure-library/closure/bin/build/closurebuilder.py \
  --root=closure-library/ \
  --root=myproject/ \
  --namespace="myproject.start" \
  --output_mode=compiled \
  --compiler_jar=compiler.jar \
  --compiler_flags="--compilation_level=ADVANCED_OPTIMIZATIONS" \
  > start-compiled.js

See Advanced Compilation and Externs in the Closure Compiler documentation for more information about using ADVANCED_OPTIMIZATIONS.

ClosureBuilderのオプション

There are other options for ClosureBuilder that aren't documented here. You can always get a full list by using the --help flag.

closure-library/closure/bin/build/closurebuilder.py --help

For convenience, the output is copied here:

$ closure/bin/build/closurebuilder.py --help
Usage: Utility for Closure Library dependency calculation.

ClosureBuilder scans source files to build dependency info.  From the
dependencies, the script can produce a deps.js file, a manifest in dependency
order, a concatenated script, or compiled output from the Closure Compiler.

Paths to files can be expressed as individual arguments to the tool (intended
for use with find and xargs).  As a convenience, --root can be used to specify
all JS files below a directory.

usage: closurebuilder.py [options] [file1.js file2.js ...]


Options:
  -h, --help            show this help message and exit
  -i INPUTS, --input=INPUTS
                        One or more input files to calculate dependencies for.
                        The namespaces in this file will be combined with
                        those given with the -n flag to form the set of
                        namespaces to find dependencies for.
  -n NAMESPACES, --namespace=NAMESPACES
                        One or more namespaces to calculate dependencies for.
                        These namespaces will be combined with those given
                        with the -i flag to form the set of namespaces to find
                        dependencies for.  A Closure namespace is a dot-
                        delimited path expression declared with a call to
                        goog.provide() (e.g. "goog.array" or "foo.bar").
  --root=ROOTS          The paths that should be traversed to build the
                        dependencies.
  -o OUTPUT_MODE, --output_mode=OUTPUT_MODE
                        The type of output to generate from this script.
                        Options are "list" for a list of filenames, "script"
                        for a single script containing the contents of all the
                        files, or "compiled" to produce compiled output with
                        the Closure Compiler.  Default is "list".
  -c COMPILER_JAR, --compiler_jar=COMPILER_JAR
                        The location of the Closure compiler .jar file.
  -f COMPILER_FLAGS, --compiler_flags=COMPILER_FLAGS
                        Additional flags to pass to the Closure compiler.
  --output_file=OUTPUT_FILE
                        If specified, write output to this path instead of
                        writing to standard output.