開発環境の構築に時間をかけない

katashin氏:よろしくお願いします。みなさん開発環境自体のお話をしていましたが、僕はどちらかと言うとそれを構築するまでの時間を短くする、本質的じゃないことに時間をかけずに、効率よくモノを作っていきましょう、というお話をしたいと思います。

僕はkatashinといいます。黄色いネコのアイコンで活動しています。

僕は個人的に小さいライブラリをけっこう作っています。ちょっとピックアップしてみたんですが、先々月は10個くらい新しいライブラリ作りました。

これくらいライブラリ作っていると、やっぱり開発環境をすぐ用意できないとイヤになります。そういったことにすごくこだわっています。

すぐに開発環境ができることで何がうれしいのかというと、パッと思いついたアイデアをすぐに実装して、小さいライブラリにするというのがすぐにできます。そういうことができると、ただの思いつきでもそれがちゃんとしたプロダクトになって、それが後々の開発に役に立ちます。

これだけたくさんライブラリを作っていると、開発環境の構築に時間をかけたくないです。じゃあどうやってそれを短くしていくのか、というお話をします。

ボイラープレートを作る

時間を短くするためにいろいろやってることはあるんですけど、最終的にはこの3つに集約されます。

まず1つ目が「ボイラープレートを作りましょう」ということです。これは、みなさんもやっているとは思うんですが、テンプレート、ボイラープレートを作りましょう、という感じですね。

ボイラープレートを作っているとちょっとツラくなるので、じゃあプリセットを作りましょう。最終的には、すこしハードルが高いですが、ゼロコンフィグのビルドツールとか。ビルドツール自体は作らなくていいんですが、あるビルドツールをラップしてゼロコンフィグにする、みたいな。そういうふうになっていくのかな、と思っています。

具体的にどういう感じでボイラープレートを作ってるのかということをお話しますと……僕はあんまりボイラープレートを作ったり、展開する……という言い方が正しいのかわかりませんが、それに特別なツールは使っていません。ただ単純に、共通のテンプレート、ボイラープレートを、最小限のものをGitHubのリポジトリにします。リポジトリにしておいて、それをクローンして使うという、ただそれだけですね。

コマンドにすると、これはたぶんみなさんもわかると思いますが、git cloneして、cdに入って、このテンプレート自体のGitの履歴はいらないので、それ消すみたいなことをしてます。

ただ、これもちょっと面倒くさいので、これは僕が作ったものではないんですが、degitという「クローンをして、Gitの履歴を消す」ということをやってくれるものがあります。ほかにも機能はあるんですが、本当にそれだけのミニマムなツールがあって、それを使うとこれだけの記述になって、とても良いです。僕自身はこのdegitというツールは使っていないんですが、似たようなものを自作して使ってます。

ボイラープレートを作るにあたって重要なのが、「簡単に作って単純に使う」ということかなと思っています。だいたいのケースで、git cloneするだけで十分なんです。

いろいろと作っていると、「このケースに対応したい」とか「あのケースに対応したい」ということが出てくるんですが、そういったことは全部、個別のテンプレートにしています。

あと、先ほどdegitというのを挙げたんですが、ツールを使うにしても「あまり賢すぎないものを使いましょう」。ツールが賢すぎると、テンプレート、ボイラープレートを作るのも大変になってしまいます。ですので、ボイラープレートを作るのが大変すぎないくらい単純なツールだけを使うのがいいかなと思います。

プリセットを作る

ただ、ボイラープレートをたくさん作っていると、例えばESLintの設定とか、そういうものはどんどん重複してメンテナンスがツラいことになるので、そういったものはプリセットにしていきましょう。

そういったものをプリセットにしていきます。

ちょっと触れたんですが、eslint-config-xxxとかbabel-preset-xxxとか。あと、これやっている人はあんまり見かけないんですが、webpack-config-xxxのように設定ファイル自体を個別のパッケージにしてあげるのがプリセット化です。

具体例なんですが、ESLintのコンフィグ。

これはno-consoleですね。consoleを書いたらエラーを出す、みたいな設定を書いて、こういう簡単なpackage.jsonで、名前とバージョンをあげると。

個人的な設定ファイルなので、例えば「eslint-config-ktsn」。僕はkatashinなので、「ktsn」と後ろに付けて。ふつうに個人名をつけて、パッケージの名前にしちゃいます。それをnpm login、npm publishってしてあげて、npmに公開します。そのあとに使う側は、それをnpmからインストールして、設定ファイルでextendしてあげると。

さっきの例だと1個のルールしかないんですが、そこに自分のプロジェクトで使う共通のルールやプラグインなどを諸々入れておくと、1回extendするだけでいいので楽です。

先ほど話したようにボイラープレートがたくさんあっても、最終的にはプリセット作っておくと、そのプリセット読み込むだけでいいですし。もしESLintの設定が変わったとか、「追加でこういうルールを追加したい」ということがあったときは、その設定自体を更新してパッケージのバージョンを上げればいいだけなので、すごく楽になります。

webpack-config-xxxっていうのをやってる人はあんまり見かけないんですが、webpackの設定ファイルって結局はただのjsファイルなので。webpackの設定の、jsのオブジェクトをエクスポートするパッケージを作ってあげて、それをふつうにrequireして、プロジェクトのwebpack-configでエクスポートしてあげる。それだけでプリセットっぽいことができるので、これはぜひやるといいんじゃないかと思います。

なので、よく使うwebpackの設定とかを書いておいて、個別のパッケージにして、それをrequireする、というふうにやると、webpack疲れもないんじゃないかなと思います。

ゼロコンフィグのツールを作る

最後にゼロコンフィグのツールです。これはあまり自分で作ることはないかもしれないんですが、同じ悩みを持ってる人はけっこういて。BiliとかPoiとかVue CLIっていうのがあったりして。こういうのは全部、基本的にゼロコンフィグのビルドツールとか、その他の機能もあったりします。BiliPoiっていうのはそのままググっても出てこないので、後ろに「js」って付けてください。

ここで重要なのが、ただのゼロコンフィグじゃダメで、デフォルトはゼロコンフィグで使えるんだけどその設定は全部上書きすることができる、というのが重要です。これはどういうことなのかというと、ゼロコンフィグって最初はすごい楽しいんですよ。設定ファイルは書かなくていいので。すごく楽しくてうまくいくように見えるんですが、だいたい開発を進めているとその設定を変えたりとか、あとはそのプロジェクト独自のビルドの流れとか、そういうのが出てくるので。そこをうまいこと上書きできる設定を追加できるのは必要です。

なので、ゼロコンフィグのツールを作るときとか採用するときは、絶対にこの「デフォルトは設定書かなくていいけど、結局全部上書きできる」みたいなのを選んだほうがいいです。

Vue CLIはそれができて。これはVue CLIの設定例なんですが、chainWebpackというオプションがありまして。ここに関数を渡すと、第1引数にwebpackの設定を抽象化したなんらかのオブジェクトが来るんですね。それに対してゴニョゴニョしてあげると、例えばこれはsvgに対するwebpackのルールを取得して、デフォルトのルールを全部クリアします。そのあとに自分が使いたい、自分自身のsvgのローダーを差し込んであげる。こういうこと簡単にできるので良いです。

この文法は生のwebpackの設定じゃなくて、webpack-chainというのを使っています。最初は「うげっ」てなるんですけど、これがあるとけっこう……あるルールを引っ張ってくるとか。これもそうなんですが、そういうのが簡単にできたりとか。あと、プラグインのオプションを変えたりっていうのは、すごく簡単な記法でできるので慣れておくとすごく便利です。

もちろんこのwebpack-chainの記法だけじゃなくて、ふつうのwebpackの記法でも書けるので、そこは大丈夫です。

という感じで、この3つ。最終的にはこの3つをやると、すごく効率が上がるというか、時間をあまりかけずに開発環境の構築ができて、すごく良いです。

僕の話は以上なんですが、最後にちょっと宣伝をさせてください。『Vue.js入門 基礎から実践アプリケーション開発まで』という本が9月22日に発売します。

Vue.js入門 基礎から実践アプリケーション開発まで

これは「入門」って書いてあるんですが、基礎の基礎から大規模開発まで全部カバーしていて、すごく実践的な本なのでオススメです。

分量けっこう多くて400ページ超えで、一部界隈からは「技術評論社から出る鈍器」とか言われてるんですけど。

(会場笑)

けっこうボリュームあるので、本当にオススメです。ぜひみなさん、買ってください。……というわけで、以上です。ありがとうございました。

(会場拍手)