LoginSignup
13
13

More than 5 years have passed since last update.

Closure Libraryを使ったJSファイル間の依存関係の記述

Last updated at Posted at 2012-04-08

Google Closure Libraryの依存関係解決ツールは非常に便利。

Closure Libraryのインストール

ファイルをダウンロードしたら解凍しアプリケーションのpublicディレクトリに設置する。ここでいうpublicディレクトリに設置するというのは

application
`-- public
    `-- javascripts
        |-- closure-library
        |   |-- closure
        |   |   |-- bin
        |   |   |   `-- build
        |   |   |       |-- closurebuilder.py
        |   |   |       `-- depswriter.py
        |   |   `-- goog
        |   |       `-- base.js
        |   `-- third_party
        `-- myapp
            |-- base.js
            `-- main.js

のようになっているとしてpublicディレクトリ以下のファイル間のファイルシステム上での相対位置とURIとしての相対位置が同じになることを意味する。

依存関係の記述

Railsのassetsパイプラインにはファイル間の依存関係を書く事ができるが、Closure Libraryではファイル単位ではなくObject単位での依存関係を記述することができる。

使うのはgoog.providegoog.require。これら自体はclosure-library/closure/goog/base.jsに定義されている。一つのファイルが提供・要求するオブジェクトの数に制限は無い。

// base.js
goog.provide('app') // 提供するオブジェクトの宣言

var app = {}

app.version = 1
// main.js
goog.provide('app.run') // 提供するオブジェクトの宣言

goog.require('app') // 必要とするオブジェクトの宣言

var app;

app = app || {};

app.run = function() {
  alert(app.version) // => 1
}

依存ファイルの生成

goog.providegoog.requireから依存関係を抽出する。これにはdepswriter.pyというスクリプトを使う。通常この結果をdeps.jsという名前で保存する。(Closure Library内部の依存関係はclocure-libaray/closure/goog/deps.jsに保存されており、goog/base.jsが読み込まれると自動でこちらも読み込まれるようになっている。)

% python public/javascripts/closure-library/closure/bin/build/depswriter.py \
  --root_with_prefix='public/javascripts/myapp ../../../myapp' \
  --output_file=public/javascripts/myapp/deps.js

root_with_prefixオプションで自分のJSコードの絶対パスとgoog/base.jsからの相対パスを指定する。間にスペースが一つ入っているのに注意。この指定されたディレクトリ以下のファイルが全て調べられoutput_fileディレクトリに結果が保存される。

今回の場合deps.jsは次のようになる

// This file was autogenerated by public/javascripts/closure/bin/build/depswriter.py.
// Please do not edit.
goog.addDependency('../../../myapp/base.js', ['app'], []);
goog.addDependency('../../../myapp/main.js', ['app.run'], ['app']);

ブラウザで実行する(開発時)

goog/base.jsと先ほど作ったdeps.jsと起点となるファイルを読み込む

<!DOCTYPE html>
<html>
  <head>
    <title>myapp</title>
  </head>
  <body>
    <script src="javascripts/closure-library/closure/goog/base.js"></script>
    <script src="javascripts/myapp/deps.js"></script>
    <script src="javascripts/myapp/main.js"></script>
    <script>
      window.onload = app.run
    </script>
  </body>
</html>

この場合main.jsが読み込まれるとClosure Libraryが自動的に依存しているbase.jsを読み込む。

ソースコードを一つにまとめる

本番環境ではソースコードを一つにまとめたい。この用途にはclosurebuilder.pyを使う

% python public/javascripts/closure-library/closure/bin/build/closurebuilder.py \
  --root=public/javascripts \
  --namespace=app.run \
  --output_file=public/javascripts/myapp.js \
  --output_mode=script

namespaceオプションで起点となるオブジェクトを指定する。今回ならmain.jsに提供しているので、このファイルを起点にして依存するファイルをまとめていく。
myapp.jsというJSファイルが生成されているので、これをブラウザで読みこめばいい。下記はファイルの読み込みが一回で済む分だけ、前の例より効率がいい。

<!DOCTYPE html>
<html>
  <head>
    <title>myapp</title>
  </head>
  <body>
    <script src="javascripts/myapp.js"></script>
    <script>
      window.onload = app.run
    </script>
  </body>
</html>

ソースコードを圧縮する

JSファイルを圧縮するツールはいくつかあるが、ここではGoogle Closure Compilerを使う。ダウンロードして解凍すると中にcompiler.jarがあるので適当な場所に設置する。上で使ったclosurebuilder.pyにはオプションでコンパイル時にClosure Compilerで圧縮するオプションがある。

% python public/javascripts/closure-library/closure/bin/build/closurebuilder.py \
  --root=public/javascripts \
  --namespace=app.run \
  --output_file=public/javascripts/myapp.js \
  --output_mode=compiled \
  --compiler_jar=path/to/compiler.jar \
  --compiler_flags='--compilation_level=ADVANCED_OPTIMIZATIONS'

compiler_jarオプションで先程のcompiler.jarを指定する。compiler_flagsは圧縮レベルでWHITESPACE_ONLY SIMPLE_OPTIMIZATIONS ADVANCED_OPTIMIZATIONSの三つの中から選ぶ。

13
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
13