いまさらながらBower入れてGruntでcss-modal
いまフロントエンドのみの案件にとりかかっているのですが、いわゆるモーダルウィンドウが必要なケースが出てきました。
なんとなーく「jQueryでいいよなー」と考えていたのですが、「そーいやCSSだけでできるのがなんかあったよなー」と思い出し、
を試してみることにしました。
bowerインストール
Bowerはnpmみたいなパッケージマネージャです。
そんでBowerはNode.jsのパッケージです。なのでNode.jsのパッケージマネージャであるnpmでインストールできます。
ややこしいですね。
Bowerの基本的なことはfrom scratch様の記事
らへんを参考にさせていただきました。
まずNode.jsのアップデートから始めるのが基本ですが、ぼくの環境はWindowsなのでアップデートするにはインストーラ使うしかないです。
Windowsじゃない方は
$ node -v $ sudo npm cache clean -f $ sudo npm install -g n $ sudo n stable $ node -v
でアップデート。
Windowsだとnコマンドが使えないです(n --help
だけ使えますw)。
この記事を書いている時点で、Windowsで利用できる最新版が0.10.28みたいです。
つぎにBowerのインストール。
(たぶんWindowsだと、Gitがインストールされていることが必須です)
>npm install -g bower >bower -v 1.3.3
bower init
使いたいパッケージと目的が決まってるので、いきなり現行の開発環境に行きたくなりますが、テストから始めるのが良いかと思います。
さっき現行の開発環境で試しながらやってたら、とあるディレクトリがきれいさっぱり消えてなくなりました。
gitがなかったら死んでました。
>mkdir bowertest >cd bowertest >git init .gitignoreファイル node_modules/ bower_components/ >git add . >git commit -m "init bowertest" >bower init
めっちゃいろいろ聞かれますが、
[?] main file: index.js [?] add commonly ignored files to ignore list?: Yes
このふたつの項目は「公開するライブラリ(Bowerにレジストする)なら」重要、とfrom scratch様の記事には書いてあった。
ここでは公開するライブラリの制作目的でなく、プロダクトの制作にのみ使うことを想定していますが、いちおう上記のように答えました。
あと、公開されないようにprivateのマークを付けるか、と聞かれるので
[?] would you like to mark this package as private which prevents it from being accidentally published to the registry? Yes
これもYesにしました。
最後に書きだされるbower.jsonファイルが良さそうかどうか聞かれるのでこれもYesで答えます。
とりまcss-modalをインストール
>bower install css-modal --save-dev
bower.jsonのdevDependenciesにcss-modalが記述されます。
インストールしてみると、./bower_components/css-modal/以下にいろいろとファイルが置かれていますが、このうち必要なのはmodal.scssとmodal.jsだけです。
そんでもってscssファイルは/dev/scssディレクトリに、jsファイルは/dist/jsディレクトリに配置したいとします。
手作業でやるのでは自動化している意味がないので、Gruntでディレクトリ・レイアウトを指定することにします。
grunt-bower-task
bowerでパッケージをインストールすると、ディレクトリ構造ごと持ってくるので、レイアウト的に使いづらい。
レイアウトを使いやすいようにするgrunt-bower-taskをインストールします。
まだgrunt-cliがインストールされていなければ:
>npm install -g grunt-cli
まだカレントディレクトリがGruntで運用されていなければ:
>npm init >npm install grunt --save-dev
package.jsonのdevDependenciesにgruntが記述されます。
>npm install grunt-bower-task --save-dev
終わったら、Gruntが使うpackage.jsonファイルのdevDependenciesにgrunt-bower-taskが記述されています。
Gruntfile.coffeeにbowerの挙動を記述します
module.exports = (grunt) -> pkg = grunt.file.readJSON 'package.json' #config grunt.initConfig bower: install: options: #ターゲットディレクトリを指定します targetDir: './lib' #byTypeでファイルの種類ごとにディレクトリを分けます layout: 'byType' #bower installタスクを実行したいか否か install: true #詳細ログを出すか verbose: true #インストール前にターゲットディレクトリを削除するか cleanTargetDir: true #必要なファイルをターゲットディレクトリにコピーした後にbower_components/を削除するか cleanBowerDir: false #plugin for taskName of pkg.devDependencies grunt.loadNpmTasks taskName if taskName.substring(0, 6) is "grunt-" return
とりあえずこの設定でインストールを実行してみます。
>grunt bower:install
/lib/css-modal/にmodal.jsとmodal.scssがインストールされました!
cleanBowerDirをfalseにしたので、bower_components/も残っています。
bower_components/css-modal/bower.jsonをみると、"main"にmodal.scssとmodal.jsが書いてあるので、必要なファイルのみ/lib/以下にコピーされたわけです。
exportsOverride
layoutをbyTypeにしたのに、ファイルタイプごとに分けられず、/css-modal/以下に2ファイルとも配置されてしまいました。
これはタイプが定義されていないためです。
bower.jsonファイルで定義します:
"devDependencies": { "css-modal": "~1.0.4" }, "exportsOverride": { "css-modal": { "js": "**/*.js", "scss": "**/*.scss" } } }
このように定義してgrunt bower:install
を実行すると、
のようにタイプ分けしてくれます。
今回のケースではcss-modalしかインストールしていないので、よけいにゴチャゴチャしたように見えますが、いろんなパッケージをbowerでインストールしたときは、こっちのほうが便利なケースがあるかもしれません。
ファイルタイプでのレイアウトよりコンポーネントでのレイアウトのほうがいい、という場合は、layoutオプションを'byComponent'にします。
grunt-contrib-copy
もしかしたらgrunt-bower-taskでうまいことやれば、最終目的配置までやれるのかもしれませんが(layoutオプションに関数を定義できます)、めんどくさいので、grunt-contrib-copyを使って、決め打ちでコピーしてしまいます。
どうせファイル名がわかっているので。
>npm install grunt-contrib-copy --save-dev
package.jsonに追記されました。
Gruntfile.coffeeでコピーのタスクを記述します:
module.exports = (grunt) -> pkg = grunt.file.readJSON 'package.json' #config grunt.initConfig bower: install: options: targetDir: './lib' layout: 'byType' install: true verbose: true cleanTargetDir: true cleanBowerDir: true copy: cssModalScss: expand: true cwd: "lib/scss/css-modal/" src: "modal.scss" dest: "dev/scss/" flatten: true filter: 'isFile' cssModalJs: expand: true cwd: "lib/js/css-modal/" src: "modal.js" dest: "dist/js/" flatten: true filter: 'isFile' #plugin for taskName of pkg.devDependencies grunt.loadNpmTasks taskName if taskName.substring(0, 6) is "grunt-" #tasks grunt.registerTask "bowerinstall", [ "bower:install" "copy:cssModalScss" "copy:cssModalJs" ] return
こんどはcleanBowerDirをtrueにしてみました。
(copyの書き方も、もっとうまいことできるかと思いますがめんどくさいので1ファイルごと書いています)
これでgrunt bowerinstall
を実行すると、/bower_components/ディレクトリが消え、/lib/以下に配置された各ファイルが、目的の場所にコピーされました。
css-modal
そういえば、この記事は、CSS-Modalを使うために書き始めたのでした。
完全に忘れていた。
CSS-Modalは、cssのみを使ってモーダルウィンドウを表現するライブラリです。
ただしIE8との互換性やESCキーでモーダルを消す、などの機能のためにmodal.jsも使うことになります(jsがなくても、IE8で機能することは機能するらしいです)。
使い方は簡単で
@import 'modal';
でscssファイルにインポートして、モーダルウィンドウになるパーツに対して
.my-modal-section{ @extend %modal; }
のように適用するだけです。
注意点は、
- modal.scssは_modal.scssにリネームして使ったほうがいいかなー
- _modal.scssの1行目に@charset "UTF-8";を書かないとたぶんエラーが出る
- csslintはオフる
HTMLのマークアップはこんな感じ
<div class="work"> <figure class="workimg"> <a href="#modal-work01"><img src="img/dummy300.png"></a> </figure> <dl> <dt class="worktitle">モーダル作品1</dt> <dd class="workdesc">モーダル作品についての説明です。モーダル作品についての説明です。モーダル作品についての説明です。</dd> </dl> <section class="modal-work" id="modal-work01" tabindex="-1" role="dialog" aria-hidden="true"> <div class="modal-inner"> <div class="modal-content"><img src="img/work_01_image.jpg" alt="作品01"></div> </div> <a href="#!" class="modal-close" title="Close this modal" data-close="Close" data-dismiss="modal">×</a> </section> </div><!-- /.work -->
imgにaのhrefで#modal-work01へのトリガー、モーダルウィンドウ側はhrefに#!でトップに移動しないようにする。
ちょっと気になるのは、CLOSEしたときにURLに#!がついてしまうことかなー。