backbone-boilerplateではじめるHTML5アプリケーション開発 その3
backbone-boilerplateが提供するビルド
backbone-boilerplateの特徴の1つとして、ビルドプロセスがしっかり整備されていることがあげられます。今回は、backbone-boilerplateが用意しているビルドの内容について、見てみます。
backbone-boilerplateのビルドの内容を理解することで、Javascriptアプリケーションのビルドの方式について、ひととおり理解することができると思います。
backbone-boilerplateのビルドでやっていること
backbone-boilerplateはビルドにgruntを利用しており、デフォルトで、以下のタスクを実行するように設定されています。
Gruntfile.js
// When running the default Grunt command, just lint the code. grunt.registerTask("default", [ "clean", "jshint", "processhtml", "copy", "requirejs", "styles", "cssmin", //"compress", ]);
jshintタスク
JSHintを利用してappフォルダ配下のJavascriptソースの静的解析を実施します。
grunt からJSHintを実行するためのプラグイン grunt-contrib-jshint を利用しています。
gruntjs/grunt-contrib-jshint · GitHub
boilerplate内のjsファイルに対してjshintを行っても何もエラーはでませんが、ためしに、github-viewer/app/components/user/index.js に以下のようなコードを追記して grunt jshint を実行すると、
var i = 0
以下のように、セミコロンがないことを指摘されます。
Running "jshint:0" (jshint) task Linting app/components/user/index.js ...ERROR [L3:C12] W033: Missing semicolon. var i = 0 Warning: Task "jshint:0" failed. Use --force to continue. Aborted due to warnings.
実際の開発では、 .jshintrc を定義してJSHintのオプションを設定する必要があると思います。
processhtmlタスク
これは、htmlファイルの内容をリリース向けに変更するための処理を行うためのタスクです。
grunt-processhtml を利用して実行しています。
具体的には、index.html の内容を変更しています。
開発時にローカルPCから参照されるindex.html (例: github-viewer/index.html)は、以下のような内容になっています。
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>GitHub Viewer</title> <!-- Application styles. --> <!-- build:[href] /styles.min.css --> <link rel="stylesheet" href="/app/styles/index.css"> <!-- /build --> </head> <body> <!-- Application container. --> <main role="main" id="main"></main> <!-- Application source. --> <!-- build:[src] /source.min.js --> <script data-main="/app/main" src="/vendor/bower/requirejs/require.js"></script> <!-- /build --> </body> </html>
これは、リリースビルド後の dist/index.html だと、以下のように変更されています。
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>GitHub Viewer</title> <!-- Application styles. --> <link rel="stylesheet" href="/styles.min.css"> </head> <body> <!-- Application container. --> <main role="main" id="main"></main> <!-- Application source. --> <script data-main="/app/main" src="/source.min.js"></script> </body> </html>
/app/styles/index.css が、 /styles.min.css に変更されています。
また、 /vendor/bower/requirejs/require.js が、 /source.min.js になっています。
processhtmlが、index.htmlのコメントを参照して、ビルド時に変換してくれています。
<!-- build:[href] /styles.min.css --> <link rel="stylesheet" href="/app/styles/index.css"> ... <!-- build:[src] /source.min.js --> <script data-main="/app/main" src="/vendor/bower/requirejs/require.js"></script>
開発時とリリース時でindex.htmlの内容を変更したいことはよくあると思います。
場合によっては、index.htmlを2重管理したりとか。。
processhtmlを使えば、そういう問題に対応できます。
requirejsタスク
RequireJSを利用して分割したjsファイルを、1つのjsファイルに結合します。ソース内の改行や空白文字の除去(ソース圧縮)も実施されます。
これは、r.js を利用して行われます。また、AMD loaderとしてalmondが指定されています。
// This task uses James Burke's excellent r.js AMD builder to take all // modules and concatenate them into a single file. requirejs: { release: { options: { mainConfigFile: "app/config.js", generateSourceMaps: true, include: ["main"], insertRequire: ["main"], out: "dist/source.min.js", optimize: "uglify2", // Since we bootstrap with nested `require` calls this option allows // R.js to find them. findNestedDependencies: true, // Include a minimal AMD implementation shim. name: "almond", // Setting the base url to the distribution directory allows the // Uglify minification process to correctly map paths for Source // Maps. baseUrl: "dist/app", // Wrap everything in an IIFE. wrap: true, // Do not preserve any license comments when working with source // maps. These options are incompatible. preserveLicenseComments: false } } },
Lo-Dash Template Loader を利用してテンプレートファイルを呼び出しをしている箇所については、そのテンプレートファイルもjsファイル内に結合されます。
これらの処理は、backbone-boilerplateで用意されている、grunt-bbb-requirejs を利用して行われます。
grunt-bbb-requirejsは、grunt-contrib-requirejs と同じ目的をもつプラグインで、実際、grunt-contrib-requirejsからフォークされて開発されたプラグインですが、ソースは完全に異なっていて、処理内容にはいくつか違いがあるようです。
なお、Source Mapsファイル(source.min.js.map)も生成してくれます。
リリースビルドされたアプリを実行していても、Chromeのデベロッパーツールでは最適化前のソースの内容を確認することができます。
stylesタスク
style.css内の @import で指定された別のcssファイルの内容を、style.cssに結合します。
/*-- Bootstrap. -------------------------------------------------------------*/ @import "../../vendor/bower/bootstrap/dist/css/bootstrap.css"; /*-- Application stylesheets. -----------------------------------------------*/ @import "app.styl";
ビルド後、以下のように、bootstrap.cssの内容が埋め込まれた形になります。
article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary {display: block;} audio, canvas, video {display: inline-block;} audio:not([controls]) {display: none; height: 0;} ...省略....
この処理は、grunt-bbb-styles で実施されています。
cssminタスク
style.css の内容を圧縮(改行、空白文字取り除き)して、style.min.css を作成します。
以上が、backbone-boilerplateのデフォルトのビルドで実行されるタスクです。
実際の開発では、他のタスクも必要になってくると思います(jsdocとか)。
Javascriptアプリケーションで必要となりそうな最低限のビルドが用意されており、仮にbackbone-boilerplateを利用しない場合でも、これらのビルドの考えた方は参考になると思います。