【脱・gulp】npm-scriptsでシンプルなフロントエンド開発環境を作る

この記事は、Tech KAYAC Advent Calendar 2016 の22日目の記事です。


こんにちは!カヤックのクライアントワークチーム・フロントエンドエンジニアの@takumifukasawa です。

昨年のアドベントカレンダーではWebGLも怖くない!canvasライブラリを効率良く学ぶオススメの順番という記事を書かせていただきました。

もくじ

  1. はじめに
  2. 手順
  3. npm scriptsとは
  4. gulpと比較したメリット・デメリット
  5. サンプルの開発環境
  6. 明日は

はじめに


今年の夏頃、いつも通りgulpを使っていた僕は、ある日gulpのバージョンアップか何かをしたら自作のgulp開発環境が上手く使えなくなって、すごくハマりました。それはそれは深刻な事態に…。

その時にふと、「あれ、なんでgulp使ってるんだっけ…」と立ち返り、gulpをなくしてみたらどうなるんだろうとあれこれ手を動かしてみました。すると、開発環境が驚くほどすっきりして、しかも、環境を一からあれこれ試行錯誤で作ってみるのが楽しくなりました。


というわけで、gulpやgruntなどのタスクランナーを使わず、npm-scriptsを主軸とした今っぽいフロントエンドの開発環境を作ってみたいと思います。脱タスクランナーです。

npm-scriptsを活用した開発環境自体は1,2年くらい前から一つの流れになっていますが、せっかくなので、今っぽいモジュールを使った環境もご紹介できればと思います。

早速ですが、そんな開発環境の雛形を作ってみました。最後に解説をします。

web-starter-kit

手順


注)node.jsはインストール済の環境です

この順番が基本となります。最近facebook製の新しいパッケージマネージャーの yarn が登場しましたが、コマンド以外はyarnでもnpmでも特に変わりません。

1. $ yarn init ($ npm init)
2. $ yarn add module名 ($ npm install module名)
3. package.jsonのscriptsを編集
4. 2,3を繰り返す

こうしてみると、作業順番はとてもシンプルです。initやインストール部分も馴染み深いと思います。 それではいよいよ、npm-scriptsを使っていきます。

npm scirptsとは


npmはpackage.json内の「scripts」というフィールドにシェルスクリプトやエイリアスコマンドを登録することができます。

書いてみる

まず、package.jsonにscriptsのフィールドを作ります。あとは、"script名": "実行コマンド"をペアとしてどんどん追加していくだけです。まず、3つscriptsを書いてみました。

↓↓ 以降、こちらのsciprtsを元に解説していきたいと思います。

...
"author": "takumifukasawa",
"license": "MIT",
"scripts":  {
 "start": "npm run watchify & npm run serve",
 "serve": "browser-sync start --server ./public/",
 "watchify": "watchify ./src/js/app.js -o ./public/js/bundle.js -v wait;"
},
...
実行してみる

npm-sciprtsは $ npm run scripts名 でscirptを実行できます。 登録した watchifyであれば、$ npm run watchify でscriptが実行されます。

予約語

ここで注意したいのは、npm-scriptsには予約語が4つあることです。それらはrunをつけずに実行できます。

$ npm start
$ npm restart
$ npm stop
$ npm test

そのため、先ほど登録した3つのnpm-scriptsはこのコマンドでそれぞれ実行できます。

$ npm start
$ npm run serve
$ npm run watchify
実行順序

scriptsは&&&を用いて実行順序を指定することができます。先ほどのscriptsのstartでは&を使ってscriptを繋げています。

  • &を1つで繋げるとそれぞれのscriptを並列に実行
  • &&で繋げると直列に実行。scriptに実行順が必要な場合は&&が便利です。

例中のstartnpm run watchify & npm run serveと記入したので、watchifyとserveを同時に実行する指令となります。


※ npm-scripts自体の詳細な使い方は、参考文献とさせていただいたこちらの記事がとてもわかりやすいです。環境変数を設定することもできます。興味のある方は是非ご一読いただければと思います。 How to Use npm as a Build Tool

gulpと比較したメリット・デメリット

メリット

  1. タスクランナーを介さないので、豊富なnode_modulesを直接叩ける
  2. gulpやgruntなどのタスクランナー自体を学習するコストがいらない
  3. 必要最低限のnode_modulesだけ使えば良いので、プロジェクトの容量を押さえられる

タスクランナーを使う場合、そのタスクランナー用のnode_modulesの開発が止まったり、タスクランナーのバージョンが上がるなどの影響で動かなくなることがあり、詰まった経験をした方は多いんじゃないかと思います。

なので、npm-scriptsから直接実行することの大きなメリットは1番だと思います。npmのドキュメントを直接見れば大抵の場合こと足ります。例えば先ほどのwatchifyであれば、こちらのドキュメントを読めばOKです。

www.npmjs.com

デメリット

  1. package.jsonが肥大化する
  2. 使える変数が限られているなど、柔軟性・拡張性が低い
  3. 可読性はタスクランナーに劣る

package.jsonにタスクが集約してしまう分、複雑なことはあまり向きません。 同時に実行するタスクの数が多かったり、実行したいタスクの順番を厳密に決めたい時は、gulpなどタスクランナーを使った方が管理しやすいです。

サンプルの開発環境


最後に、最初ご紹介した自作のnpm-scriptsで書いた開発環境について解説して終わりたいと思います。開発環境を作る際や、この記事のご参考になればと思います。

モジュールは今っぽいものを組み合わせています。シングルページを想定したかなりミニマムな構成なので、複数html,js,cssを作りたいときは、適宜修正しています。

web-starter-kit

構成

html: pug(旧jade)

インデント形式でhtmlを記述できます。閉じタグを書かなくて良いので楽です。

css: postcss

autoprefixerやpostcss-assetsなど、使いたい分だけ適宜モジュールをインストールして使うpostcss。環境によってモジュールの組み合わせを変えることができるので、開発のスケールを自由に変えられます。

javascript: watchify

browserifyの差分ビルドを実現してくれます。browserifyをそのまま使うと更新のたびに1からコンパイルしてしまうのですが、差分ビルドにすることで、コンパイル速度が劇的に上がります。

serve: browser-sync

開発サーバーです。ファイルが更新された時に自動でリロードしてくれるautoreload機能が便利です。

明日は


今年新卒で入社してくれて超大活躍している @beinto くんのすごい記事です!

[参考文献]

How to Use npm as a Build Tool

npm で依存もタスクも一元化する

Grunt/Gulpで憔悴したおっさんの話

GitでUnityプロジェクトを管理する

はじめに

カヤックのソーシャルゲーム事業部で働いているUnityエンジニアのmadaです。
カヤックでは、Unityのプロジェクトのバージョン管理にGit、ホスティングサービスにGithubを利用しています。 今日はGitでUnityプロジェクトを管理する方法について紹介します。

この記事はカヤックUnityアドベントカレンダー2016の22日目の記事です。

UnityプロジェクトのGit管理について

プロジェクトをGitで管理する際、AssetsProjectSettingsディレクトリを含める必要があります。LibraryTempディレクトリは含めなくても動作に影響はありません。 Gitの管理対象から外したいディレクトリやファイルは.gitignoreに記述します。 .gitignoreの例を紹介します。

Library
Temp
*.bat
*.csproj
*.csproj.user
*.booproj
*.pidb
*.sln
*.sln.meta
*.suo
*.unityproj
*.userprefs
*.userprefs.meta
*~
.DS_Store
*[! -~]*
*.pidb.meta

metaファイルについて

UnityではAssets以下のコンテンツを内部のゲームにすぐに使えるデータに変換して、 プロジェクトのLibrary以下に保存しています。 Assets以下にはインポートしたファイルがそのまま残ります。 例えばテクスチャのインポート設定でTextureFormatを上書きすると、 Assets以下のテクスチャは上書かれずにLibrary以下のファイルが上書きされています。

Library以下に格納するための設定はmetaファイルに保存されます。 metaファイルにはアセット固有のIDと、インスペクターに表示されるインポート設定が保存されています。

詳しくは公式のマニュアルを参照してください。
アセットの内部処理

Gitでmetaファイルを管理する

metaファイルに記述されたインポート設定もGitでバージョン管理するために以下の設定をします。 metaファイルはテキスト形式で管理したほうが、差分の設定がわかるので便利です。

Edit->Project Settings->Editorから Version Control: Visible Meta Files Asset Serialization: Force Text

Gitにおける大文字と小文字の区別

Gitでは、標準で大文字と小文字のファイル名が区別されません。 同じファイル名で、大文字と小文字を変更するだけでは差分が認識されません。 Gitで同じファイル名の大文字と小文字を変更するときは以下のコマンドが利用できます。

git mv -f Readme.md README.md
-f Force renaming or moving of a file even if the target exists

Gitにおける空ディレクトリの扱い

Gitでは空のディレクトリは管理されませんが、 Unityは空のディレクトリでもmetaファイルを作成します。 そのためmetaファイルだけコミットされ、対象のディレクトリは存在しないケースが生じます。 このようなケースを避けるために、ディレクトリを新規作成すると、 .gitkeepという空のファイルを自動配置するPostProcessを作成し利用しています。

文字コードと改行コード

それぞれの開発環境で文字コードや改行コードが異なると無駄な差分が発生するので、 プロジェクト内で統一したほうが良いです。 文字コードは日本語を利用するためBOM付きUTF-8、 改行コードはWindows形式のCRLFで統一しています。

Git-Flow

Gitを用いて効率的に開発を行うフローにGit-Flowというモデルがあります。 カヤックのプロジェクトでは、このフローに基づいて開発を行っています。 詳しくは以下のページを参照してください。
git-flow-cheat-sheet

コードレビュー

機能開発が完了したブランチをマージする時は必ず他人にコードレビューしてもらいます。 コードレビューによってバグを生むコードを発見したり、 他人のコードをよく読むことで勉強にもなります。

GitのホスティングサービスにGithubを利用しているため、 Pull Request上でレビューを行いコメントを残しています。

現在のプロジェクトで、レビュー時に注意している項目をまとめてみました。

わかりやすさ
メンテナンスしやすさ
コーディング規約が順守されているか
スペルミスがないか
共通できるコードを共通化しているか
コードのカップリング度が低いか
命名の一貫性があるか
データの処理はモデルに書いているか
メソッド名と実装がかみ合っているか
マジックナンバー使ってないか
無駄にコメントアウトされたコードが残っていないか
ファイル配置が正しいか
ロジックに問題がないか
Warningが出てないか
無限ループから抜け出せなくなってないか
null になりそうな項目が null チェックされているか
配列へのアクセス時に配列の長さとのチェックをしているか
SaveProject を実行して差分がでないことを確認(BuildSettingsなど)
Update()、LateUpdate() 中での参照が、キャッシュされているか
Update()、LateUpdate() 内で foreach を利用していないか
GameObject.Find を利用してオブジェクトを取得していないか
空の文言は "" ではなく string.Empty を使う
動的に変更を想定していない値には readonly が設定されているか
型変更時、型変更されることが確実ならキャスト、不確実ならば as を利用しているか
不要なファイルコミットしてないか

Pull Requestの活用紹介

Unityでスマートフォン用の実機ビルドを用意するのには10分以上の時間がかかることもあります。 開発者の環境で実機ビルドを作成するのは非効率的なので、 Jenkinsを用いてサーバーでビルドを作成しています。 Pull RequestにbuildとコメントするとJenkinsにビルドパラメータを渡し、 ビルド結果のURLを教えてくれるシステムが稼働しています。

f:id:kayac-mada:20161221221526p:plain

おわりに

この記事では、GitでUnityプロジェクトを管理する方法について紹介しました。 明日はAssetBundleについて清水が紹介します。