yeoman, grunt, bowerで静的サイト構築(第五回)
yeoman, grunt, bowerで静的サイト構築(第四回)の続き
今回はデプロイの処理の流れを追ってみたいと思います。処理を追うことで、gruntのタスクに関する理解が深まると思います。
「-v」オプションを付けて、より詳細な動作ログを出力して確認します。
$ grunt build -v
さっそく、上から順に見ていきます。
Registering Gruntfile tasks
Initializing Command-line options: --verbose Reading "Gruntfile.js" Gruntfile...OK Registering Gruntfile tasks. Registering "grunt-contrib-copy" local Npm module tasks. Reading /app/dev/mobile/node_modules/grunt-contrib-copy/package.json...OK Parsing /app/dev/mobile/node_modules/grunt-contrib-copy/package.json...OK Loading "copy.js" tasks...OK + copy Registering "grunt-contrib-concat" local Npm module tasks. Reading /app/dev/mobile/node_modules/grunt-contrib-concat/package.json...OK Parsing /app/dev/mobile/node_modules/grunt-contrib-concat/package.json...OK Loading "concat.js" tasks...OK + concat
Gruntfile.js を読み込んで、各モジュールのタスクの読み込みを行っているようです。
clean
Running "clean:dist" (clean) task Verifying property clean.dist exists in config...OK Files: .tmp Options: force=false Options: force=false Cleaning ".tmp"...Deleting .tmp...OK OK
.tmpのディレクトリを削除しています。
.tmpにはcoffeeスクリプトやsassなどのコンパイル済みファイル(js, cssなど)を配置するように、各コンパイルタスクとして設定されています。
リコンパイルするので、作業ディレクトリ(.tmp)をきれいに掃除しているのです。
usemin
Running "useminPrepare" task Running "useminPrepare:html" (useminPrepare) task Verifying property useminPrepare.html exists in config...OK Files: app/index.html -> html Options: dest="dist" Going through app/index.html to update the config Looking for build script HTML comment blocks Reading app/index.html...OK Found a block: <!-- build:js scripts/vendor/modernizr.js --> <script src="bower_components/modernizr/modernizr.js"></script> <!-- endbuild --> Updating config with the following assets: - app/bower_components/modernizr/modernizr.js Found a block: <!-- build:js scripts/main.js --> <script src="bower_components/jquery/jquery.js"></script> <script src="scripts/main.js"></script> <!-- endbuild --> Updating config with the following assets: - app/bower_components/jquery/jquery.js - app/scripts/main.js
usemin関連のタスクが実行されています。
useminはuseminPrepare, imagemin, svgmin, cssmin, htmlmin, rev, concat, uglifyなどが関連性を持って実行されるので、動作を理解するのが大変かもしれません。
useminPrepare
app/index.htmlを読んで、
<!-- build --> <!-- endbuild -->
のブロックの内容を取得しています。
これはブロック内に記載したjs, cssを、指定したファイルに出力するためのタグです。
つまり、ファイルマッピング情報を生成しているのです。
Configuration is now: cssmin: { dist: { files: { '<%= yeoman.dist %>/styles/main.css': [ '.tmp/styles/{,*/}*.css', 'app/styles/{,*/}*.css' ] } } } concat: { 'dist/scripts/vendor/modernizr.js': [ 'app/bower_components/modernizr/modernizr.js' ], 'dist/scripts/main.js': [ 'app/bower_components/jquery/jquery.js', 'app/scripts/main.js' ], 'dist/scripts/coffee.js': [ '.tmp/scripts/hello.js' ], 'dist/scripts/async-local-storage.js': [ 'app/scripts/async.localStorage.js', 'app/scripts/async.localStorage.examples.js' ], 'dist/scripts/fullscreensnippet.js': [ 'app/scripts/fullscreensnippet.js' ], 'dist/scripts/fastclick.js': [ 'app/scripts/fastclick.js', 'app/scripts/fastclick.example.js' ] } uglify: { 'dist/scripts/vendor/modernizr.js': 'dist/scripts/vendor/modernizr.js', 'dist/scripts/main.js': 'dist/scripts/main.js', 'dist/scripts/coffee.js': 'dist/scripts/coffee.js', 'dist/scripts/async-local-storage.js': 'dist/scripts/async-local-storage.js', 'dist/scripts/fullscreensnippet.js': 'dist/scripts/fullscreensnippet.js', 'dist/scripts/fastclick.js': 'dist/scripts/fastclick.js' }
ファイルマッピング情報ができました。
concurrent
Running "concurrent:dist" (concurrent) task Verifying property concurrent.dist exists in config...OK Files: [no src] -> dist Running "imagemin:dist" (imagemin) task Done, without errors. Running "htmlmin:dist" (htmlmin) task File dist/404.html created. File dist/index.html created. Done, without errors. Running "coffee:dist" (coffee) task File .tmp/scripts/hello.js created. Running "coffee:test" (coffee) task Done, without errors. Running "svgmin:dist" (svgmin) task Done, without errors. Running "compass:dist" (compass) task Done, without errors.
並列処理で各種リソースのコンパイル及び圧縮処理を行っています。
cssmin
Running "cssmin:dist" (cssmin) task Verifying property cssmin.dist exists in config...OK Files: app/styles/main.css -> dist/styles/main.css Options: report=false Reading app/styles/main.css...OK Reading app/styles/main.css...OK Writing dist/styles/main.css...OK File dist/styles/main.css created.
app/styles/main.cssを圧縮して、dist/styles/main.cssを生成しています。
responsive_images
Running "responsive_images:dev" (responsive_images) task Verifying property responsive_images.dev exists in config...OK Options: separator="-", sizes=[{"width":320},{"width":640},{"width":1024}]
画像を配置していないので、何も動作していませんが、指定した画像サイズで画像を自動生成することができます。
concat
Running "concat:dist/scripts/main.js" (concat) task Verifying property concat.dist/scripts/main\.js exists in config...OK Files: app/bower_components/jquery/jquery.js, app/scripts/main.js -> dist/scripts/main.js Options: separator="\n", banner="", footer="", stripBanners=false, process=false Reading app/bower_components/jquery/jquery.js...OK Reading app/scripts/main.js...OK Writing dist/scripts/main.js...OK File "dist/scripts/main.js" created.
app/bower_components/jquery/jquery.js, app/scripts/main.js を連結して dist/scripts/main.js を生成しています。
uglify
Running "uglify:dist/scripts/main.js" (uglify) task Verifying property uglify.dist/scripts/main\.js exists in config...OK Files: dist/scripts/main.js -> dist/scripts/main.js Options: banner="", footer="", compress={"warnings":false}, mangle={}, beautify=false, report=false Minifying with UglifyJS...Reading dist/scripts/main.js...OK OK Writing dist/scripts/main.js...OK File "dist/scripts/main.js" created.
concatタスクで生成したファイルに対し、Minifyを実行し、同一ファイルに出力しています。
copy
Running "copy:dist" (copy) task Verifying property copy.dist exists in config...OK Files: app/favicon.ico -> dist/favicon.ico Files: app/robots.txt -> dist/robots.txt Files: app/.htaccess -> dist/.htaccess Options: processContent=false, processContentExclude=[] Options: processContent=false, processContentExclude=[] Copying app/favicon.ico -> dist/favicon.ico Reading app/favicon.ico...OK Writing dist/favicon.ico...OK Copying app/robots.txt -> dist/robots.txt Reading app/robots.txt...OK Writing dist/robots.txt...OK Copying app/.htaccess -> dist/.htaccess Reading app/.htaccess...OK Writing dist/.htaccess...OK Copied 3 files
開発環境(app/)のファイルをデプロイ環境(dist/)にコピーしています。
単純なファイルコピーなので、開発環境とデプロイ環境で変更が無いファイルのみが対象です。
rev
Running "rev:dist" (rev) task Verifying property rev.dist exists in config...OK Files: dist/scripts/async-local-storage.js, dist/scripts/coffee.js, dist/scripts/fastclick.js, dist/scripts/fullscreensnippet.js, dist/scripts/main.js, dist/scripts/vendor/modernizr.js, dist/styles/main.css -> src Options: algorithm="md5", length=8 Hashing dist/scripts/main.js...Reading dist/scripts/main.js...OK OK >> fc8109b5fd49d06437f53a567e228a50 dist/scripts/main.js >> fc8109b5.main.js
ファイル名にmd5の暗号化文字列を8文字付加して、リネームしています。
js, css, imgなど、ファイルであれば何でもリネームできるようです。
リリース時にブラウザキャッシュを心配する必要がなくなるのはうれしいですね。
usemin
Running "usemin:html" (usemin) task Verifying property usemin.html exists in config...OK Files: dist/404.html, dist/index.html -> html Options: type="html", dirs=["dist"] Reading dist/404.html...OK Reading dist/index.html...OK Processing as HTML - dist/index.html Update the HTML to reference our concat/min/revved script files <script src="scripts/vendor/modernizr.js" changed to <script src="scripts/vendor/d7100892.modernizr.js" <script src="scripts/main.js" changed to <script src="scripts/fc8109b5.main.js" <script src="scripts/coffee.js" changed to <script src="scripts/3431b5a9.coffee.js" <script src="scripts/async-local-storage.js" changed to <script src="scripts/107b4b1c.async-local-storage.js" <script src="scripts/fullscreensnippet.js" changed to <script src="scripts/f4dff991.fullscreensnippet.js" <script src="scripts/fastclick.js" changed to <script src="scripts/4a20a196.fastclick.js" Update the HTML with the new css filenames <link rel="stylesheet" href="styles/main.css" changed to <link rel="stylesheet" href="styles/6bad6e7f.main.css" Update the HTML with the new img filenames Update the HTML with data-main tags Update the HTML with the data tags Update the HTML with background imgs, case there is some inline style Update the HTML with anchors images Update the HTML with reference in input Writing dist/index.html...OK
各処理の総仕上げです。
ファイル連結・圧縮などを経て、動的に生成された各ファイルの呼び出し箇所に対し、自動でファイル名の置換が行われます。
いかがでしたでしょうか?
Gruntfile.jsの設定と各モジュールの記法に従うだけで、デプロイに必要な様々なタスクを自動化できているのが理解できると思います。
自分でgrunt buildを実行して、デプロイ後の各ファイルを中身を再確認してみましょう。
衝撃と感動を受けると思いますよ!
「yeoman, grunt, bowerで静的サイト構築」としての連載は今回で終わります。
次回以降はgruntの各モジュールにフォーカスしていきたいと思います。