Gruntでjadeコンパイルするときのあれこれ
こんにちは iijmyaです。
Gruntのプラグイン'grunt-contrib-jade'でjadeファイルをコンパイルする際に、
jadeファイルで使いたい値をGruntfileから渡したり、あるディレクトリ以外のjadeファイルをコンパイルしたかったりしたので、自分なりにGruntfile.coffeeに書いてみました。
1.jadeファイルで使いたいオブジェクトをGruntfileから渡す
外部から変数を定義するときは dataオプションを使用します。
data: function(dest, src) return { from: src, to: dest }
この関数は宛先(dest)と送信元(src)を引数として持ち、データオブジェクトを返します。
例えばjadeファイル内で、ページによって異なるクラス名を付けたいシチュエーションがありました。
変数bodyに、コンパイルするjadeファイルの直近のディレクトリ名を渡したい…
body(class="#{body}")
今回コンパイルするのは以下のファイルで、publicディレクトリの下に配置されます。
- src/jade/exam/index.jade -> public/exam/index.html
今回の実現したい事に対して、dataオプションは以下のように書いてみました。
data: (filepath)-> dir = filepath.replace('public/', '').replace(/[^\/]+\.[^\/]+/, ""); dir = dir.split("/").join(""); return {body: dir}
宛先のパスを引数として受け取り、余分な文字をreplaceメソッドで削って、最終的にキーがbodyで値がディレクトリ名のオブジェクトデータを返しています。
実際にGruntでwatchをしつつ、src/jade/exam/index.jadeを更新して生成したhtmlを見てみると。。
<body class="exam">
ちゃんと値が入っていました!
dataオプションには、このように関数を定義してデータオブジェクトを渡す他にも、直接データオブジェクトを渡したり、JSONファイルを読み込む事も出来るようなので、詳しくは以下のサイトを見てみてください。
gruntjs/grunt-contrib-jade · GitHub
2.あるディレクトリ以外のjadeファイルをコンパイルする
このディレクトリに入ってるjadeファイル以外をコンパイルしたい…
だからといってコンパイルしたくないファイル以外をいっこずつ指定するのは面倒ですよね。
そんなときはglobパターンを用います。
* : 0字以上の任意の文字列にマッチする
? : 1字の任意の文字列にマッチする
** : パスの一部を含む0字以上の任意の文字列にマッチする
! : 指定したパターンでない文字列にマッチする
{,} : カンマ区切りのor条件として、いずれかの文字列を含むかどうかをチェック出来る
例えば以下のようなファイルがあるとします。
- src/jade/index.jade
- src/jade/exam/index.jade
- src/jade/study/index.jade
- src/jade/parts/layout.jade
- src/jade/parts/header.jade
- src/jade/parts/footer.jade
この場合、partsディレクトリ内のjadeファイルを指定するには以下のようになります。
src: 'src/jade/parts/*.jade' または cwd: 'src/jade/parts/' src: '*.jade'
今回実現したかった、「あるディレクトリ以外のファイルをコンパイルしたい」ですが、
partsディレクトリ内のjadeファイルはhtml単体では意味をなさないため、
partsディレクトリ以外のjadeファイルをコンパイル対象に指定します。
src: [ 'src/jade/**/*.jade' 'src/jade/!parts/*.jade' ] cwd: 'src/jade/' src: [ '**/*.jade' '!parts/*.jade' ]
この設定でコンパイルを行ったところ、
$ grunt Running "watch" task Waiting...OK >> File "src/jade/parts/layout.jade" changed. Running "jade:compile" (jade) task File "public/exam/index.html" created. File "public/index.html" created. File "public/study/index.html" created. Done, without errors.
partsディレクトリ内のファイルを更新してみても、
ちゃんとpartsディレクトリ以外のファイルがコンパイルされました!
Gruntfileの大まかな書き方さえわかってしまえば、
Gruntはプラグインも豊富なのでいろいろと便利になりそうですね。
今回のjadeタスクの全体像は以下になります。
# Gruntfile.coffee jade: compile: options: pretty: true # インデント有効化 data: (filepath)-> dir = filepath.replace('public/', '').replace(/[^\/]+\.[^\/]+/, ""); dir = dir.split("/").join(""); return {body: dir} files: [ expand: true cwd: 'src/jade/' src: [ '**/*.jade' '!parts/*.jade' ] dest: 'public/' ext: '.html' ]
【SVG実践】SVG画像を使ってみる
こんにちは iijmyaです。
今回は先日お話ししましたSVGの実践編として、
SVGで画像を作成して実際にHTMLページに載せてみたいと思います。
=============================== 目 次 ===============================
1.SVGファイルの作成
2.HTMLのページにSVGファイルを載せる
3.SVGライフを充実させるために
====================================================================
前回お話ししたように、SVGファイルはAdobeのIllustratorやオープンソースソフトのInkscapeなどの
画像編集ソフトを利用することによって作成することが出来ます。
今回はIllustratorを使ってSVGファイルを作成し、HTMLのページに載せてみます。
1.SVGファイルの作成
2.HTMLのページにSVGファイルを載せる
今回は、前回紹介した方法の一つである、objectタグを用いてSVG画像を読み込みたいと思います。
比較用にPNG画像のアイコンも載せておきます。
■ HTMLの記述
<body> <header> <!-- 省略 --> </header> <div class="main"> <div class="left_pane top"> <object type="image/svg+xml" data="icon.svgz"></object> </div> <div class="right_pane top"> <!-- 省略 --> </div> <div class="left_pane bottom"> <!-- 省略 --> </div> <div class="right_pane bottom"> <img src="icon.svgz"> </div> </div> <footer> <!-- 省略 --> </footer> </body>
3.SVGライフを充実させるために
SVG画像は何も考え無しに作ってしまったり、複雑な構成や多色の図を作ろうとすると、
PNG画像やJPG画像などのラスタ画像と比べてファイル容量が大きくなってしまう場合があります。
例えば、今回作成したアイコンだとSVGファイルの方が半分も軽いですが、
以下の画像を見てみると、SVGファイルの方が倍以上容量が大きくなっています。
そのため、SVG画像の軽量化が必要になる場合が出て来ると思いますが、以下のような方法があります。
1) SVGZ形式で保存する
SVGZは、先ほどIllustratorでアイコンを作成し、保存するときに出てきましたね。
SVGZはSVGを圧縮したファイル形式になるため、軽量化が期待出来ます。
例えば、先ほど例に出したSVG画像をSVGZ形式で保存してみると、かなり軽量化することが出来ました。
2) 軽量化ツールの使用
軽量化ツールのひとつに「SVGO」があります。
SVGOはターミナル上で以下のコマンドを打つだけでインストール可能です。
sudo npm install -g svgo
使い方は簡単で、軽量化したい対象SVGファイルのあるディレクトリまで移動し、以下のようなコマンドを打つだけです。
svgo ファイル名
例えば今回作成したtest.svgに対して軽量化を行ったところ、以下のようになりました。
$svgo test.svg Done in 171 ms! 169.186 KiB - 16.5% = 141.276 KiB
SVGファイルをSVGZファイルに変換することも出来るようなので試してみたところ、
$svgo test.svg -o - | gzip -cfq9 > test2.svgz $du -a -h 12K ./test2.svgz
先ほど1) でIllustratorで保存したSVGZファイルより、5KB軽い結果になりました。
他にも指定ディレクトリ内にある全てのSVGファイルの軽量化や、
SVGZファイルからSVGファイルへの変換など、色々なことが出来るようなので、
詳しくは以下のリンク先で確認してみてください。
今後どんどんSVGに対応するブラウザやサイトが増えていくと良いですね。
【SVG入門】SVGでベクターグラフィックス【その2】
こんにちは iijmyaです。
今回も引き続きSVGについてです。
前回、SVGが扱うベクターグラフィックスやビットマップグラフィックスについてお話ししましたが、
(【SVG入門】SVGでベクターグラフィックス【その1】 - シアトルコンサルティング サービス開発ブログ)
今回は実際にSVGを使ってみます。
=============================== 目 次 ===============================
1.ベクターグラフィックスとビットマップグラフィックス(前回)
2.SVGの使用シーン(前回)
3.SVGを使ってみる
====================================================================
3.SVGを使ってみる
SVGは、既にFirefox,Safari,Chromeなどのブラウザがサポートしており、
IEに関してもフィルタやアニメーション,フォント以外ではあるものの、IE9以上がサポートをしています。
SVGをブラウザで表示する場合、外部SVGファイルを読み込む方法と、直接SVGをHTMLに埋め込む方法があります。
(1) 外部SVGファイルを読み込む方法
SVGファイルはAdobeのIllustratorやMicrosoftのOffice Visio、オープンソースソフトのInkscapeなどの画像編集ソフトを利用することによって出力することが出来ます。
ブラウザ上でペイントのように描画してSVGを出力できる「SVG-edit」というのもありました。
■ objectタグを使用する
HTML内にobjectタグを挿入し、type属性に"image/svg+xml"を、data属性に表示したいSVGファイルのURLを指定します。
この方法はSVGをサポートしているブラウザとの互換性も良く、JavaScriptによる制御も可能です。
<object type="image/svg+xml" data="sample.svg"></object>
■ imgタグを使用する
通常の画像と同じくimgタグのsrc属性でSVGファイルを指定することで表示することが出来ます。
ただし、この方法だと最新ブラウザのみでしか動作せず、かつ、JavaScriptによる制御が出来ないデメリットもあります。
<img src="sample.svg">
(2) 直接SVGをHTMLに埋め込む方法
■ svgタグを使用する
HTML5をサポートした最新ブラウザであれば、直接HTMLにSVGを埋め込むことが出来ます。
<svg> <!-- 円 --> <circle cx="100" cy="100" r="50" fill="#f65" /> <!-- 四角 --> <rect x="120" y="120" width="100" height="100" fill="#56f" /> </svg>
上記コードのように、svgタグの中にcircleタグやrectタグを指定することで、図形を描画することが出来ます。
(3) 応用: JavaScriptを使用してSVGを制御する
これは応用になりますが、SVGに対してJavaScriptを用いて制御を行うことも出来ます。
以下は、図をクリックすると色が変わるサンプルです。
<svg> <circle id="circle" cx="100" cy="100" r="50" fill="#f65" /> </svg> <!-- jQuery使用 --> <script type="text/javascript"> !function() { $("#circle").on("click", function() { $(this).attr("fill", "#56f"); }); }(); </script>
いかがでしたでしょうか。
今回は実際にブラウザでSVGを表示する方法について紹介しました。
devtools-snippetsでブラウザ上での作業をハッピーに
satkakuです。
Webサイト見てて、ちょっとしたデータの集計とかをブラウザ上のコンソールからさくっと取りたい、でもjQueryとか入っていないサイトだとめんどい、みたいな際にちゃちゃっとjQueryを差し込みたい、そんな状況が1年に12回くらい訪れます。
Chromeだと、*.users.js作ってUserScript差し込むのもそこまでめんどくは無いのですが(拡張機能画面につっこむだけ)、それすらもめんどかったので、Snippetを使うことにしました。
調べてみるとこんなのが!
今回欲しかったやつなんかもあります。
jquerify.js
使い方としては
(1) 「Sources」タブから「Snippets」を開く
(2) 右クリックで「New」
(3) ソース貼付ける
(4) Snippets名を右クリックして「Run」、または「▶」ボタンを押す
Snippetsに登録しておけば、いつでも呼び出すことが出来ます。こいつは便利ですね。
他にもこんなのがあります。
console-save.js
consoleにsaveメソッドを追加してくれます。
console.save(data, [filename])で、dataをJSON形式にしてくれた上でダウンロードできます。
filenameはオプションで、デフォルトはconsole.json。
dataurl.js
html上のimgとcanvasを全部DataURIに変換してくれます。
log-globals.js
グローバル変数を全部出してくれます。グローバル変数犯人探し。
devtools-snippetsには他にも色々とSnippetsがあるので、もうちょい眺めてみようと思います。
【SVG入門】SVGでベクターグラフィックス【その1】
こんにちは iijmyaです。
明けましておめでとうございます。
2ヶ月ぶりの更新となってしまいましたが、
今回はベクターグラフィックスを扱う、SVGについて書きたいと思います。
=============================== 目 次 ===============================
1.ベクターグラフィックスとビットマップグラフィックス
2.SVGの使用シーン
3.SVGを使ってみる(次回)
====================================================================
1.ベクターグラフィックスとビットマップグラフィックス
SVG(Scalable Vector Graphics)とは、ベクターグラフィックスを扱うための技術です。
ベクターグラフィックス(ベクター画像)は、一つ一つの点の座標(アンカー)やそれを結ぶ線などの図形情報を記憶しておき、
その図形情報を元に計算を行って図を描画するため、拡大や縮小をしてもそれに合わせて図を再描画するため、図が荒くなるのを防ぐことが出来ます。
ベクターグラフィックスと対の関係にあたるビットマップグラフィックス(ラスタ画像)は、
色の付いたドット(ピクセル)の羅列で図を描画します。
ビットマップグラフィックスは拡大・縮小に弱く、画像が荒くなってしまいますが、
ベクターグラフィックスは位置情報を元に図を描画するため、拡大・縮小に強い図形になります。
2.SVGの使用シーン
上記のようなベクターグラフィックスを扱うSVGですが、
どのようなときにビットマップグラフィックスではなく
ベクターグラフィックスを使うと、ハッピーになれるのかいくつかシーンを考えてみます。
■ オリジナルのフォントをSVGで作りたい!
→ ハッピー
ビットマップグラフィックスの場合、フォントサイズ(文字の大きさ)毎にフォントデータを用意する必要がありますが、
ベクターグラフィックスは拡大・縮小に強いため、1つのフォントデータのみで対応することが出来ます。
■ この間撮った写真をSVGで表現したい!
→ アンハッピー
ベクターグラフィックスは、図形情報を元に描画するため、写真のような複雑な構成や色使いをする図には向いていません。
写真の細かい色の違いや複雑な構成を表現するためにも、点単位で微妙な調整が効くビットマップグラフィックスの方が描画に向いています。
■ サイト内に載せるこのアイコンを複数デバイスに対応させたい!
→ ハッピー
一つの画像を複数デバイスで対応させる場合、ビットマップグラフィックスだと
解像度が異なる問題で、その分のビットマップデータを用意しなければならなくなってしまいます。
だったら高解像度で大きいサイズのビットマップデータを一つ作ってしまえば、
ある程度縮小しても平気だし、複数デバイスで使いまわせるんじゃないの?と思うかもしれません。
しかしそれだと、そんなに大きいサイズでなくても良い解像度のデバイスでもわざわざその画像を読み込まなくてはならないので、
大きいサイズの画像だと、その分ファイルの容量も大きくなってしまい、不必要にネットワーク負荷がかかってしまいます。
そのため、アイコンのように単純な図であれば、解像度を気にしなくて良いベクターグラフィックスの方が向いています。
いかがでしょうか?
ベクターグラフィックスとビットマップグラフィックスを使い分けられれば、いろいろと便利になると思います。
長くなってしまったので、今回はここまでにしておきます。
次回は実際にSVGを使ってみます。
シアトルコンサルティング新卒採用サイトをリリース!
こんにちは iijmyaです。
今月11月1日に、弊社シアトルコンサルティングの新卒採用サイトをリリースしました!
4月に新卒エンジニアとしてシアトルに入社した私は、今回の新卒採用サイトが初めて任せていただいたプロジェクトでした。
サイトの企画やデザインから始まり、実装、テスト、リリースまで、一連のフェーズに入社1年目のうちに携わることが出来たのは、とても良い経験だったと思います。
なかでも、新卒で入社した私にとって、実装面では初めて使うような技術もあり、エンジニアとして得るものが多かったと思います。
そこで、今回は当サイトを実装するにあたって用いた技術を簡単にご紹介します。
1.主な使用技術
今回、開発に使用した主な技術は以下の3つです。
- HTMLを生成するための「Jade」
- CSSを生成するための「Stylus」
- JavaScriptを生成するための「CoffeeScript」
■ Jade
HTMLの生成にJadeを用いることで、閉じタグなどの余分なコードが削減したり、インデントによる可読性向上や、ページ共通部分のコンポーネント化が可能になるなどのメリットが挙げられます。
//- layout.jade div.body_inner include header block content include footer
■ Stylus
CSSの生成にはStylusを用いることで、値の参照が出来たり、ネスト記法により、要素に対するスタイルの影響範囲を限定しやすくなるメリットがあります。
//- style.styl $fixedWidth = 980px div.main width: 100% min-width: $fixedWidth … &.other div.copyright padding-left: 5px margin-bottom: 15px div.logo padding: 0 img width: 50px height: @width
■ CoffeeScript
JavaScriptの生成にはCoffeeScriptを用いることによって、文末のセミコロンやvarのつけ忘れによる予期せぬ動作の回避や、コード量の削減といったメリットがあります。
class Slide … constructor: (option)-> @lists = $('.slide') @listsLength =@lists.length @lists.eq(@index).css("z-index", 10) setInterval(@slide, INTERVAL)
2.その他の使用技術
■ Grunt.js
タスクの自動化ツールであるGrunt.jsを用いて、.coffeeなどのファイルの変更を感知し、リアルタイムでコンパイルすることが可能になるため、JadeからHTML、StylusからCSS、CoffeeScriptからJavaScriptへのコンパイルを意識せずにコードを書くことが出来ました。
また、JavaScriptの圧縮ライブラリであるUglifyJSを使用して、JavaScriptのminify処理も行っています。minify処理を行うことでファイルの容量を削減し、Webページの表示の高速化が期待できるようになります。
■ Media Queries
今回、モバイルでの閲覧比率が高くなることを予想して、CSSのMedia Queriesを用いてモバイル用のUIにも対応しました。
//- layout.jade meta(name="viewport", content="width=device-width") //- style.styl $fixedMobileWidth = 480px @media screen and (max-width: 700px) body div.body_inner width: $fixedMobileWidth background-color: #fff header.mobile_header display: block !important
■ nib
Stylusのライブラリであるnibを用いることで、ベンダープレフィックスが自動で付いたり、clearfixを簡略化することが出来ました。
//- style.styl @import 'nib' header.mobile_header … &.title a width: 150px height: 75px background: url("/fresh/image/exam.png") no-repeat background-size: cover //- style.css header.mobile_header div.title a { width: 150px; height: 75px; background: url("/fresh/image/exam.png") no-repeat; -webkit-background-size: cover; -moz-background-size: cover; background-size: cover; }
簡単ではありますが、今回のプロジェクトで使用した技術についてざっとご紹介いたしました!
今後も、自社開発プロジェクトについてご紹介していきたいと思います。
エンジニアインターン3daysで未経験者にプログラミングをやってもらった話
satkakuです。
弊社シアトルコンサルティング株式会社で、8月、9月と2回に渡って、2015年卒学生向けのエンジニアサマーインターンシップを行いました。それぞれ3日間ずつで、プログラミング未経験者大歓迎で行ったのですが、内容については完全に一任してもらえたので、どんなことを考えてインターンを組んだのか、とか、次へ向けての改善とかについてまとめてみようと思います。
■ コンセプト
「プログラミングって楽しいねっ!」
もうとにかくこれでした。
弊社は、Javaをメインとして業務系のシステムに携わることが多いので、Javaをやってもらうとかも考えたのですが、短い時間でやってもらおうとすると環境構築だったりなんだったりが面倒くさいというのと、仮にそれをこちらで用意しても、インターンが終わった後で自分でやってみるのにはハードルが高くなっちゃうだろうなー、とその辺からJavaは却下。その他大勢の環境つくるとこから系言語は全て却下。
環境をつくること自体は、今回の本質ではなく、あくまで「自分で書いたものが動く楽しさ」を重視した結果、まあJavaScriptでいいんじゃないかなーという結論に達しました。キーワードは「メモ帳とブラウザがあれば出来る」。なので、参加者の皆さんにも普段使っているPCをそのまま持ってきてもらい、そのPC上で作業してもらいました。メモ帳で書く、ドラッグアンドドロップでブラウザ突っ込む。終わり。簡単。
最初は書き方の練習的にプロフィールページとか作ってもらったんですが、フルスクラッチで書くものだけだと、3日間であまり面白そうなものも出来なそうだったので、後半はYouTube再生アプリを作ろうというお題目で、YouTube API使って検索かけたり、ループ再生できるようにしたりと、まずはプロジェクター上で自分の書くとおりに写経してもらった後、拡張ポイントで、それぞれのカスタマイズが出来るようにしてみました。やっぱり普段自分が使っているサービスなんかと絡めたほうが、可能性を感じてもらえて楽しいのかなー、と。
あとは数人チームとか、ペアとかでやってもらおうかとも思ったのですが、それだとあまりコードを書かなくなってしまう人が出るかも、という懸念があり、基本的に全て個人プレーでやってもらいました。
■ ざっくりスケジュール
【 Day 1 】
10:00~10:30 イントロダクション
10:30~12:00 HTML,CSS
12:00~13:00 昼食休憩
13:00~14:00 JavaScriptその1
14:00~14:10 休憩
14:10~15:00 JavaScriptその2
15:00~15:10 休憩
15:10~16:50 プロフィールページの作成その1
16:50~17:00 コンクルージョン
【 Day 2 】
10:00~11:30 プロフィールページの作成その2
11:30~12:00 レビュー
12:00~13:00 昼食休憩
13:00~14:00 youtubeアプリ説明
14:00~14:10 休憩
14:10~15:00 youtubeアプリ設計
15:00~15:10 休憩
15:10~16:50 youtubeアプリ作成その1
16:50~17:00 コンクルージョン
【 Day 3 】
10:00~12:00 youtubeアプリ作成その2
12:00~13:00 昼食休憩
13:00~14:00 youtubeアプリ作成その3
14:00~14:10 休憩
14:10~15:00 レビュー
15:00~15:10 休憩
15:10~16:00 ライブコーディング(これは自分がやりました)
16:00~17:00 コンクルージョン
■ 気にしていたこと
「こうやったらこうなるんだ!」みたいな本屋で売っている入門書的な感じだと、まあ、本屋さんで買えばいいんじゃないですか、という思いがあったので、なるべく歴史の話(ティム・バーナーズ=リーとかブレンダン・アイクとか)やら、「なんでそれが生まれたのか」みたいな話を盛り込むようにしました。あと、強調して言っていたのが「HTMLもCSSもJavaScriptも、全てただの文字列。それをタグだったり、語順だったり、ルールで意味付けしているだけ」という話。
ちょうど当時「白と黒のとびら」を僕が読んでいた最中でもあり、やたら「プログラミングは魔法」ノリを出していたのも、ひとえに僕の中二病が成せるわざでしょう。
■ やってみた結果
具体的にどういったものを作るかとか、技術的な難易度とかに関しては特に制限を設けず、「こういうことやりたいから教えて」となったら都度説明していくスタイルでやったので、割とインターン生任せだったのですが、みんなそれぞれ持てる知識の中で面白いものを作ってくれて、自分としても楽しかったです。逆に技術知識とかが少ないほうが、その限定、集中された中での面白いアイディアをひねり出してくれるので、興味深かったです。(僕はそれを、冷蔵庫の余り物クッキングと呼んでいます)
あと、JavaScriptの文法説明するときとかにいちいちエディタとブラウザを行き来してもらうのもたるかったので、説明用資料をHTMLで作って、textareaに書いたJavaScriptをevalで動かすようにしておいたのも成功でした。話が楽。
■ 反省点
・メモ帳でやってもらうと、複雑なマークアップで死ぬ(僕が)
やはり人類の叡智を捨て去り、メモ帳でやったのはしんどかったです。「ここ上手くいかないんです」と相談されても、タグの対応をおっかけるだけで精神がやられます。結局第2回目からは、初日のラストで「というように、確かにメモ帳とブラウザだけあれば十分なんですが、それだと辛いのでこんなに便利なものがあるんですよ」とSublime Text 2入れてもらいました。僕のためです。結果的にはインターン生の作業もだいぶ効率化されて、もっとコードに集中できるようになったので、万々歳です。
・人が多いと死ぬ(僕が)
第1回目は6人、第2回目は4人で行ったのですが、個人プレーということもあり、横についてのレビューということが多く、講師側が1人だと手が回らない場面がありました。1人で教える分には、相手は4人くらいがベストな気もします。ただ、その分、インターン生どうしで分からないところに関して隣の人に相談したりとコミュニケーションが生まれていたので、それはそれで良かったなあと。
■ まとめ
未経験 + 文系という人が大半だったんですが、最終的にはみんな自分の色を入れた動くものを作れたので、最低限の目標はクリアできました。
ただ、個人プレー推しの結果、インターン生どうしの交流の時間をそこまで作れなかったので、次回があればその辺をどうするかが考えどころです。今のところ考えているのは、みんなでコタツに入りながらインターンを行うことで心の距離を縮める作戦ですが、恐らく企画が通ることは無いでしょう。