こまぶろ

技術のこととか仕事のこととか。

6/26 「カイゼン・ジャーニー・ライトニングトークス」で初LT登壇した

本日、「カイゼン・ジャーニー・ライトニングトークス」というイベントに参加してきました。勉強会には足繁く参加している僕ですが、今回が初めてのLTとなりました。

devlove.doorkeeper.jp

カイゼン・ジャーニー』

イベントの内容は、書籍『カイゼン・ジャーニー』にまつわる内容のLT大会です。この書籍は僕の背中を強く押してくれた本なので、「『カイゼン・ジャーニー』に背中を押されて行動したよ」という話であればそこまで悩むことなくできたと思います。ですが、せっかくの機会に書籍の礼賛をして終わっても勿体無いですし、その手の話をしても「良かったね」という感想しか持ち帰ってもらえないと考え、最近よく考えていることとカイゼン・ジャーニーを結びつけてお話しすることにしました。

発表資料

忘れられがちな気がする「文字言語」の重要性

今回のLTでは、「文字言語」の重要性についてお話ししました。これは、自分がここ数ヶ月、社内でアイデアの導入のために試行錯誤をしている中で、「明確に人に考えを伝えることに失敗しているな」と感じたところから出発しています。

長い文章を書くということは、エンジニアの世界ではあまり重要視されないというか、そもそも業務として少ないと感じています。文章らしい文章が書かれるとすれば、障害報告書くらいでしょうか(書いたことありません)。エンジニアにとって身近なのは、やはり顔を合わせての口頭での会話や、Slackなどでのライトなコミュニケーションなのだと思います。

もちろん、面と向かってのコミュニケーションでよく伝わることもあると思います。不安や感謝といった感情に関わるものは、かっちりとした文章よりもそのようなコミュニケーション方法によってこそ伝わるものでしょう。そして、それは行動によって裏付けられ、人を巻き込んでいくものです。

しかしながら、明晰な言語で論理的に綴られた文章は、自分の考えを伝えるためには、依然として極めて強力なツールなのではないか、と思っています。自分が認識している現状や、ある行動の根拠を精密に伝えようとすれば、それが複雑であればあるほど、言葉を尽くして説明する必要があります。それができるのはやはり、文字言語による文章である。それが発表の趣旨でした。

カイゼン・ジャーニー』と「アジャイルマニフェスト

僕はこの話をしようと思ったとき、当初は『カイゼン・ジャーニー』とは違う方向に行きそうだなと思いました。なぜなら、『カイゼン・ジャーニー』は行動を重んじる書籍だと思っていたからです。

カイゼン・ジャーニー』は、モヤモヤを持ちながらも燻っている人の背中を押してくれる書籍です。石神の「あなたは何をしている人なんですか」という問いは、多くの読者に強く響いたのではないでしょうか。「文句ばかり言っていないで行動を起こすことが重要だ!」というメッセージを受け取った僕は、考えたことを行動に移してきました。

しかし、僕はおそらく カイゼン・ジャーニー』を誤読していた のだと、今は思っています。なぜなら、あの書籍には文字言語による「見える化」を利用するプラクティスも多く含まれていたからです。長大な文章を書こうという話は出てきませんが、そもそもあの書籍自体が文章です。物語は明晰さとは縁がないように思われるかもしれませんが、江島の目の前に横たわっていた現実の描写や、プラクティスの解説の存在によって、あの書籍は単に情緒に訴えるだけのものに留まっていないと思います。

確かに『カイゼン・ジャーニー』は、情動に訴えかけて行動を促す要素のある、行動を重んじる書籍だと思います。しかしそのことは、あの書籍が 言語を軽んじるものであることを意味しません。 それは、「アジャイルマニフェスト」がドキュメントや計画の価値を貶めているわけではないのと同じなのです。

文章を書いていくという所信表明

本来であれば、自分が実践していることを発表すべきところなのですが、正直に申し上げて、僕はまだ自分の考えを正しく伝えるような文章を書けていません。そしてそれは、文章になっていないだけではなく、まだ思考の上でも曖昧なままなのです。

もちろん職場に直結するような内容は、ブログに書けることではありません。ですが、それは文章を書かない理由にはなりません。僕が取り組もうとしている切実な課題がそこにあるのであれば、公開できるできないに関わらず僕は書くべきなのだと思います。

数ヶ月後、数年後、僕にとって記念すべき初めてのLTとなったこの発表をふりかえって、「あのときの自分は間違っていなかった」と思えるかどうか。それは予想できません。ただわかるのは、「書いてみなければ答えはいつまでも得られない」ということです。こればかりは、 書くということを実際に行動に移して初めてわかる ことです。

最後の最後で、行動と言語の二項対立が崩れてしまいました。明晰さの欠片もありませんね。このような文章を書かないよう、みなさんもこれから言語を鍛えていきましょう。

末筆ながら、主催者のお二人、参加者のみなさま、ありがとうございました。

カイゼン・ジャーニー たった1人からはじめて、「越境」するチームをつくるまで

カイゼン・ジャーニー たった1人からはじめて、「越境」するチームをつくるまで

van-thks.com

環境構築弱者でも簡単に始められるテスト駆動開発〜mocha + power-assert でJavaScriptのテストを書く〜

環境構築弱者でもテスト駆動開発がしたい!

JavaScriptテスト駆動開発を始めてみる

みなさん、テスト書いてますか?僕は書いてません。

f:id:ky_yk_d:20180623082423p:plain

はい、すみません。

というわけで今回は、JavaScriptテスト駆動開発を始めてみたという記事になります。具体的には、

テストを実行するための、環境構築とテストの書き方をまとめました。

power-assert.jsは、和田卓人(@t_wada)さんが作成したライブラリです。その特質は下記のスライドをご覧ください。

www.slideshare.net

mocha.jsのGitHub

github.com

power-assert.jsのGitHub

github.com

【補足】「環境構築むずかしいのでは?」とブレーキをかける認知を補正する

最初、普通に環境構築してテスト書いて〜〜という記事を書いていたのですが、この記事を書くモチベーションについて思うところがあったので少し文章を。

テスト駆動開発に限らないのですが、何か新しいことを始めるときに、環境構築で転ける経験をしている方は多いのではないでしょうか。僕もそうで、いくつか転けてきた経験により何を始めるにも「よくわからないけど環境構築むずかしそう・・・」と二の足を踏んでしまうことがよくあります。

しかし、すでに始めている人からすると実は簡単なんだよというものは多いんじゃないかとも思っていますし、僕自身、何らかのきっかけで踏み出してみて、「なんだ、意外と簡単じゃん」と感じることもあります。

今回に関しても、「やってみたら意外と簡単だった」というのが結果としての感想なのですが、そういう記事が増えてくれるとどんどん新しいことを試していけるなぁと思いまして、とりあえず過去の自分に対しては「簡単なんだよ」と言えるように今回の記事を書きました。

そういうわけで、テスト駆動開発の中身(レッド・グリーン・リファクタリング)については特に記載していません。t_wadaさんの下記スライドをご覧ください。

環境構築

こちらの記事を参考にさせてもらいました。

コマンドラインからの環境構築

npmは入っている前提です。ちなみにMacです(たぶん関係ないと思う)。

cd [プロジェクトのディレクトリ]
npm init
mkdir test
npm install --save-dev mocha # たぶん
npm install --save-dev intelli-espower-loader # この辺は 
npm install --save-dev power-assert # 一気にやっていい

以上でコマンドラインからの環境構築は終了です。少し前まではnpm installと出てくると頭が痛かったのですが、VueやらWebpackやらと戯れているうちに大分慣れてきたように感じます。

npm run mochaで実行できるようにする

上記の設定だけを行い、テストを実行するコマンドmocha --require intelli-espower-loaderを叩いたところ、「mochaなんてコマンド知らねーよ」と怒られてしまいました。--save-devオプションをつけたmochaにはパスが通っていないので、mochaコマンドでは呼べません。

この事象に対処する一つの手段は、npm install -g mochaを実行することです。グローバルインストールすることで、パスが通ってmochaコマンドが使えるようになります。しかし、何でもかんでもグローバルインストールするのがダメだということは何となくわかります。

というわけで、下記の記事を参考にpackage.jsonを修正し、ローカルのものを使用するように変更しました。

package.json

{
  .
  .
  .
  "scripts": {
    "mocha": "mocha --require intelli-espower-loader"
  },
  .
  .
  .
}

以上の設定をすることで、npm run mochaでテストを実行することができました。いちいちオプションを指定しなくてもいいのも便利ですね。これで環境構築はできました。意外と簡単ですね。

※グローバルインストールしたmochaをnpm uninstall -g mochaでアンインストールしてみたところ、mochaコマンドは使えなくなりましたが、npm run mochaは問題なく使えたので意図した通り、ローカルのmochaを使えるようになったようです。

テストを書いて実行してみる

どう書くのか/どんな表示が出るのか

いよいよテストを書いて実行していきます。JavaScriptも初心者なのでツッコミどころがあったらGitHubなりTwitterなり(匿名がいい方は)質問箱なりに投げていただければ幸いです。

全て3の配列の2番目の要素(=3)と、1~5までの配列の2番目の要素(=2)を比較するテスト(落ちるはず)を書きました。下記の2つのコード(実装/テスト)を作成し、npm run mocha ./test/sample-test.jsコマンドを叩きます。さぁ、どんな結果が出るでしょうか。

./src/sample.js

exports.getActual = () => {
  let actual = [];
  [...Array(5)].map((_,i) => {
    actual.push(i + 1);
  });
  return actual;
};

./test/sample-test.js

const assert = require('power-assert');
const myModule = require('../src/sample');

describe('サンプルテスト', () => {
  it('落ちるテスト', () => {
    let expected = Array(5).fill(3);
    assert(myModule.getActual()[1]=== expected[1]);
  });
});

実行結果

f:id:ky_yk_d:20180623121041p:plain

想定通り落ちました。そして、「何が起きたのか」がコンソールに表示されています。t_wadaさんが「すごい表示、素晴らしい表示、実にわかりやすい表示」自画自賛する表示です。

単純に想定と実際が出てくるだけでなく、assert()の引数に渡した式の途中の評価結果も表示されています。これなら、どの時点でおかしくなっているのかもよくわかります。便利に使えそうですね。

-w オプションで変更を検知してテストを自動実行する

ちなみに、npm run mocha -w ./test/sample-test.jspackage.jsonscripts "mocha": "mocha --require intelli-espower-loader -w"-wオプションをつけると、ファイルの変更を検知してテストを自動実行するモードになります。このモードを終了するにはctrl + cです。下記の記事を参照しました。

毎回コマンド叩く必要がなくなるのでサイコーです。

2018.06.24 修正

"mocha": "mocha --require intelli-espower-loader"の設定下で、変更監視モードで起動するには、 npm run mocha -- -w ./test/sample-test.jsなどと--`を付けてからオプションとファイル名を記載する必要がありました。下記の記事を参照しました。

まとめ

以上、環境構築方法とテストの書き方をご紹介しました。簡単に始められたので、ガシガシテスト書いていこうと思います。

  • mocha + power-assert のテスト環境は簡単に構築できる!
  • power-assert は便利に使えそう!
  • -w オプションを使えばさらにテストは高速に!

参考記事一覧

テスト駆動開発

テスト駆動開発

【おまけ】素因数分解プログラムのテストを書いてみる

整数値を渡すと素因数分解した結果を配列にして返すプログラムを書いてみました。JavaScriptよくわからん。

なお、開発の過程はブログ向きでないので、GitHubリポジトリをご覧ください。コミットの単位が荒くて恐縮ですが、試行錯誤の跡を見ていただけるかと思います(笑)

github.com

実装コード

let isDivisor = (dividend, divisor) => {
  return dividend % divisor === 0;
}

exports.findSmallestFactor = function(num){
    let possibleLargestFactor = Math.floor(Math.sqrt(num));
    for (let i = 2; i <= possibleLargestFactor; i++){
      if (isDivisor(num, i)){
        return i;
      }
    }
    return 0;
  };

 exports.factorize = function(num){
    let result = [];
    let temp = num;
    while (true){
      let smallestFactor = this.findSmallestFactor(temp);
      if (smallestFactor === 0 ){
        result.push(temp);
        break;
      } else {
        result.push(smallestFactor);
        temp = temp / smallestFactor;
      }
    }
    return result;
  };

テストコード

const assert = require('power-assert');
const PrimeFactors = require('../src/PrimeFactors');

describe('PrimeFactors', () => {

  describe('素因数分解が正しく行われる', () => {

    it ('2のときは2を返す', () => {
      assert(PrimeFactors.factorize(2).toString() === [2].toString());
    });
    
    it ('4のときは[2,2]を返す', () => {
      assert(PrimeFactors.factorize(4).toString() === [2,2].toString());
    });
    
    it ('6のときは[2,3]を返す', () => {
      assert(PrimeFactors.factorize(6).toString() === [2,3].toString());
    }); 

    it ('108のときは[2,2,3,3,3]を返す', () => {
      assert(PrimeFactors.factorize(108).toString() === [2,2,3,3,3].toString());
    });

  });

  describe('最小の約数を返す', () => {

    it ('12を渡すと2を返す', () => {
      assert(PrimeFactors.findSmallestFactor(12) === 2);
    });
    
    it ('17を渡すと0を返す', () => {
      assert(PrimeFactors.findSmallestFactor(17) === 0);
    });

  });
  
});

実行結果

f:id:ky_yk_d:20180623112659p:plain

まさに「何もなければ黙るのみ、落ちるときはやかましく」ですね。

F.O.X Meetup #3 ~スタートアップのチームビルド~ に参加した

F.O.X Meetup #3 ~スタートアップのチームビルド~

6/18に開催された「F.O.X Meetup #3 ~スタートアップのチームビルド~」(@ヒカラボ)に参加してきました。

career.levtech.jp

カカカカックさんのプレゼン姿を見たかった & チームビルドに関心があった

現在、このブログを中心としたアウトプットについてのメンタリングを、カカカカック(@kakakakakku)さんにしていただいています。日頃のTwitterでのやりとり以外に、ブログやプレゼン資料、ゲスト出演されたポッドキャストについては拝読・拝聴していましたが、直にお会いしたことはなく、プレゼンという形のアウトプットに自分の目と耳で接したことがなかったので、いい機会と思い参加しました。

内容面でも、チームビルドという非常に関心を持っている分野について、スタートアップで働かれているお三方からお話をうかがえるということで、非常に楽しみにしていました。

資料はお三方ともに後日公開、かつメディア取材が入っていてそちらの記事が各登壇者についてそれぞれ1本(!)公開される予定とのことでしたので、内容についてはあまり触れず、感想を。

登壇資料とlogmiの記事

門田さん

www.slideshare.net

logmi.jp

田中さん

www.slideshare.net

logmi.jp

吉田(カカカカック)さん

kakakakakku.hatenablog.com

logmi.jp

門田 矩明 さん「成功したチーム、失敗したチーム」

F.O.Xの門田さんです。F.O.X Meetupの主催者の方。

cyber-z.co.jp

これまでのキャリアで経験された3つのチームの事例をもとに、成功するチームと失敗するチームを分けるものは何かのか、というテーマでお話しされました。

結論としては、スタートアップで成功するのは、

  • チーム内でタスクや知識をシェアできる
  • 専門領域を超えた仕事ができる
  • つまり、いわゆる「チームワーク」のできている

チームだというお話でした。この結論自体は、ありふれたものでしたが、お話を拝聴していて感じたことがあったので書き留めておきます。

時期によるタスクの偏りという問題

2番目のチームとして、アドテク製品のフルスクラッチでの開発において、4つのサブシステムにそれぞれ専任者を付けて開発を進めた結果、「失敗したチーム」となってしまったチームのお話がありました。

発生した問題は、サブシステム間(すなわちメンバー間)でタスクの偏りが生じた際に、手すきの人員に手伝わせようとしても、専任制でノウハウが共有されていないためにキャッチアップできない、ということでした。

誰も専門的な知識を持っていない領域に対する調査〜開発のあり方

3番目のチームとして、2012年ごろに携わったスマホアプリの開発についてのお話がありました。当時、スマホアプリ開発は現在ほど広く普及したものではなく、そこについての情報が少ない、専門的な知識を持ったエンジニアがチームにいないという状況で、どのように調査・開発を進めたか?というお話でした。

要点としては、

  • 専門領域を問わず複数名で技術調査する
  • 調査メンバーで全領域を設計し、そのメンバーがコードレビューする
  • 調査〜開発までを複数名で実施する

という取り組み方をした結果、ドキュメントに書いていないことが起きるなどのトラブル発生時にも複数名で対応でき、プロジェクトは成功したということでした。

全員が未知の領域の場合、担当を割り振ってまずはその人にチーム内での第一人者になってもらうという行動に出たくなってしまいがちであるように思います。しかし、結果として後からキャッチアップするのに手間がかかる、レビューが正常に機能しなくなるなどの問題が発生するリスクはやはり大きいなと感じました。

田中 裕一 さん「タイムバンクでみるプロジェクトの立ち上げとMVP」

タイムバンクの田中さん。「見た目のせいか『デザインもやって!』と言われますが、デザインは全然できません」とのお言葉が印象的です。

timebank.jp

冒頭で予告された内容は以下のような点でした。

  • クラッチから立ち上げてどのような苦労があったか
  • チームワークをどのように作っていったのか
  • エンジニアの組織で起きがちな問題

拝聴していて印象に残ったことをいくつか。

各フェーズにおいて何を諦め、何を重要視するのか?

「有益な施策はたくさんあるが、それを一時期にすべて実施するのは無理」という厳然たる事実に基づいたお話でした。本を読んだりネットの記事を読んだりすれば、「こうすれば良くなる」という施策は技術の導入であったりプラクティスであったり様々なものを知ることができます。僕自身、日々そういうものを学び、「あれもやってみたい、これもやってみたい」と半ばワクワク、半ば焦燥に駆られています。

しかし、当然ながら「何ができて何ができず、何が有効で何が効果薄なのか」というのは、現場や時期によって異なることです。これは当たり前の事実で、様々なプラクティスを紹介している『カイゼン・ジャーニー』でも冒頭(第1部第1話の解説)にも似たような趣旨のことが書かれています。

私たちは、他者の実践の背景にどんな状況、制約があったのかを理解し、自分たちの状況、制約の下ではどのように実践するべきなのか捉え直さないといけない。(『カイゼン・ジャーニー』13頁)

今回の田中さんのお話は、ある現場において、立ち上げからフェーズを切りながら、それぞれのフェーズで可能かつ有効な施策を考え、実践していった記録として非常に面白く聴きました。

チームとしての取り組み

技術的背景も、価値観もバラバラなメンバーからなるチームにおいて、どのように行動をしていったかをお話しされていました。印象に残ったもののみ挙げておきます。発言ベースなので内容に重複があります。

  • お互いの「正義」が違うことを理解する
  • 「開発チームとして、何を優先し、何を諦めるのか?」を合意し、それを時期に応じて変えていく
  • 自分たちの現状と向かうべき先について共通理解を作る、そのためには時間を取る
  • 一度決めたことは当面はブレさせない
  • チケットには最低限、いつ、何が起きて、誰が対応したのか?だけはわかるように書く(初期の妥協点)

MVP & the Wizard of Oz

MVPのお話。書籍で読んで知ってはいましたが、実際に適用されている方のお話を伺うのは初めてでした。下記のような発言がありました。

  • KPIの跳ね方を見てピボットするなどの行動をとる
  • 仮説と検証を回す
    • 検証不可能なものは検証可能な仮説にするか、聞かなかったことにする
    • 心理的表現が含まれる仮説はボケたりするのでコストばかりかかることが多い
  • ユーザ体験を損ねる方向のMVPの使い方は危険

吉田 慶章 さん「さぁ!今すぐプロジェクトリーダーに立候補しよう」

大トリはカカカカックさん。下記のブログで公開している社内勉強会の内容をアップデートしたものをお話してくださいました。

kakakakakku.hatenablog.com

冒頭に、「資料を後日公開するのでメモはとらずに僕の話を聴いてください」と通告されました。スライドになかった発言だけメモしていましたが、ご本人が終了後に「めっちゃアドリブで喋っちゃう」と仰っていましたので、ちょうどよかったなと思いました。

長いプロジェクトは失敗する?

今回、章立てとしては、

  • 「タスクの流れ」に着目する
  • 「雑談」と「スウォーミング」を大切に

の2つに分けてお話をされたのですが、これらに入る前にされた「プロジェクトとは?」というお話の中で、下記のような趣旨の発言がありました。

4ヶ月以上のプロジェクトは切り分け方が悪い。絶対失敗する。3ヶ月くらいで何かしらリリースすべき。

僕はプロジェクトの経験があまりないので、このあたりの肌感覚はまだわからないのですが、おそらくタスクと同じで、長い間、目に見える成果を提出できないというのは辛いし、行き詰ってしまいがちなんですよね。リリースを文字通りに捉えるとスタートアップ限定の話に聴こえますが、一般(?)のプロジェクトも短く切れたほうがいいのかなと感じました。

「タスクの流れ」に着目する

人を抜き取られてしまわないために、うまく動いてることをスプリント計画を使って示す

スプリント計画は経営層やステークホルダーに対しても有効という視点は考えたことがありませんでした。人を抜き取られたり追加されたりするのはリスクなので、チームを守るためにはかなり大事ですね。

スキルマップの△は、次のプロジェクトでは◯になっていてほしい人

プロジェクト自体の成功とは別に、個人の望む成長も実現したいというのはプロジェクトに関わる人全員に共有されてほしいです。。

「雑談」と「スウォーミング」を大切に

後半は、話の内容よりもプレゼンの仕方の工夫が印象に残りました。

「3秒休んで一呼吸おき」、後半に突入

「3秒休みます」と声に出して仰っていました。切れ目に間を作るというのはよく言われますが、「休みますよ」と言われるとたとえそれが3秒でも「あ、いま気を抜くタイミングだ」と安心して気を抜けるので良かったです。

スライドを映して上から下まで読ませてから、口頭での説明・ストーリーを追加する

スライドを読むだけのプレゼン辛いというのはよく言いますし、このやり方は珍しいものではないと思いますが、視覚と聴覚の両方をうまく使ってプレゼンを「体験」することができるなーと感じました。

終わりに

カカカカックさん目当てで参加したイベントでしたが、とても満足感が高かったです。普通なら、余韻を楽しんで終わってしまうところなのですが、カカカカックさんから下記のツイートが飛んでくるのでブログ書きました。

というわけで、これにて勉強会終了です!

カイゼン・ジャーニー たった1人からはじめて、「越境」するチームをつくるまで

カイゼン・ジャーニー たった1人からはじめて、「越境」するチームをつくるまで

ザ・ゴール ― 企業の究極の目的とは何か

ザ・ゴール ― 企業の究極の目的とは何か

カンバン仕事術

カンバン仕事術

Vue.jsで作る初めてのSPA〜Udemyの"The Ultimate Vue JS 2 Developers Course"のProject 2を受講した

初めてのSPAをVue.jsで作る

前々回の記事の続きです。

ky-yk-d.hatenablog.com

UdemyのThe Ultimate Vue JS 2 Developers CourseのProject 2を終えました。今回は、そちらの感想記事です。

www.udemy.com

3つのサンプルアプリケーションを作りながらVue.jsを学ぶこちらのコースの2番目のプロジェクトで作るのは、"Vue.js Cinema"。映画のポスターと詳細情報と上映時刻をAPIで取得し、一覧・フィルター・詳細表示するSPAです。講師の方が公開しているデモサイトは下のリンクにあります。

vuejs-cinema.vuejsdevelopers.com

f:id:ky_yk_d:20180616213744p:plain

1番目のプロジェクトで作成した"Vue.js Poster Store"との大きな違いは、今回のアプリケーションがVue routerを利用したSPAであることです。これまでSPAを作った経験がないので、初めてのSPAをVue.jsで作るということになります。

内容について

CSS(scss)はあらかじめ用意されているものを適用するだけですが、JavaScriptやHTMLはほぼ全て自分で1から記述します(API接続やユーティリティ関数は一部用意されているものを使います)。Vue.jsを学習するコースなので、ビューに関わる箇所は省略せずに全てのコードを映像の中で講師の方と一緒に記述していきます。

今回のプロジェクトでは、下記のようなこと(抜粋)を学び/使います。

  • DOM操作
  • イベント処理
  • Webpack
  • Vue.js devtools
  • SFC
  • Vue router
  • Vueインスタンスによるイベントバス

詳細な内容については、コースの内容一覧のページに記載してあります。細かく映像が区切られており、それぞれにその映像で学ぶ/実施する内容がわかるタイトルがついているので、どんな技術を使っているのかは受講しなくてもわかります。また、作成するソースコードGitHubに初期状態から完成形までが公開されています。区切り区切りでブランチが切られているので、復習するのにも便利です。ソースコードは受講していなくても見られるので、ご興味ある方は見てみてください。

github.com

受講して良いと思った点

今回もとてもわかりやすかったです。コンポーネントにせよSFCにせよVue routerにせよ、文法・使い方はドキュメントを読んでわかっていても、実際にどのように使うのか、何が嬉しいのかはよくわからず、自分でこれらを使ってアプリを作ってみようという気になれていませんでした。それが、今回のプロジェクトで実際に一からコードを書いていくなかで、「なるほど、こうやって使うんだな」というのがわかってきた気がします。受講していて良かったと感じたポイントをいくつか書き留めておきます。

巨大VueインスタンスからSFCへのリファクタリングを実践できる

今回のプロジェクトではWebpackを利用しているのですが、最初はエントリポイントであるsrc/main.jsファイル内のVueインスタンス(ルートインスタンス)に全てのVueのコードを記載していきます。ある程度まではそのまま続けていくのですが、途中で「これだとファイルが巨大になっちゃうからからリファクタリングしていこう」と子コンポーネントSFCに切り出していきます。モジュール化するといいよねというのは頭ではわかるのですが、実際に巨大なインスタンスを切り分けていく体験をするとリファクタリングする動機も方法もより実感できます。

相変わらず間違えるAnthonyさんにツッコミを入れたくなる

上の点に関連して、ファイル作成→コピー/カット&ペーストを繰り返して書き換えていくなかで、モジュールの相対パスを書き換えたり、モジュールのインポートを追加したりする必要が出てきます。その過程でも、前回書いたようにAnthonyさんは間違えます。わかっている人からすれば「何回同じ間違いしてんだよ」となるのでしょうが、やはり教材としては長所になっているのではと感じます。

これが最初からすんなり適宜修正を加えてくれてしまうと、映像を見ながら写経している側の印象に残らないのですが、ご丁寧に何度も何度も間違えるので、次第に写経しているこちらが先回りしてエラーが出ないようなコードを書くようになります。「またAnthonyさん同じ間違いしてるじゃん(笑)」となったらこれは教育としては最高の結果ですよね。

Vue.js以外のフロントエンド技術も学べる

これも個人的にはありがたい点です。上述のように、このプロジェクトではJavaScriptはほぼ自分で書きます。したがって、アプリケーションを作成していく中で用いられるVue.js以外のJavaScriptのライブラリや関数についても一緒に勉強することができます。もちろん、Vue.jsのコースなので深い解説まではされないのですが、「こういうものを使うよ」という断りはちゃんとされますし、参考資料として外部のドキュメントのURLなどを提示してくれるので、わからないところは自分で調べられるようになっています。一例としては以下のようなものを学びました。

  • ES6
  • JavaScriptの組み込みオブジェクト(StringやArrayなど)
  • 基本的なライブラリ(Moment.jsなど)
  • Webpackで用いるローダー(Style loaderなど)

「隅から隅まで知っているサンプルコード」を獲得できる

新しい言語やツールを学ぶときは、ドキュメントやサンプルコードを参考にしてどうにかこうにか作らざるを得ません。しかし、一度学んだ/使ったことのあるものを思い出す時には、自分が書き、理解しているコードを見るのが最前だと思っています。どうやって使うんだっけ?と思ったときに、公式のドキュメントだけでは応用方法がわからず、かといって他人のコードではその設計をまず理解しないとどのように使っているかはわからない、という経験をされたことがある方は多いのではないでしょうか。そういうときに、自分の書いたコードがあると、「ああ、そうだったそうだった」と思い出せます。Anthonyさんと一緒にコードを書いていくことで、この最強のサンプルコードを手に入れることができる。これがこのコースの大きな長所なのではないかと感じました。

おわりに

全部で14時間、3プロジェクトのコースも2/3まできました。だいぶ、Vue.jsの世界にも馴染めてきたような気がしています。Project 3ではGoogle Calendarのクローンを作りながら、サーバーサイドレンダリングなどを学べるようなので、楽しみながら学んでいきます!

フロントエンド弱者が腹を括ってWebpackに触ってみた

前回UdemyのVue.jsのコースについての記事を書きましたが、続きがなかなか視聴できていないので、今週はそれとは違う内容になります。少々お待ちください・・・。

さて、ブログを始めたくらいの時期からこれまで、フロントエンドの勉強を細々と続けてきました。

  • GitHub Pagesで静的Webサイトを公開したり

ky-yk-d.hatenablog.com

  • twitter:cardやog:imageを設定してみたり

ky-yk-d.hatenablog.com

  • Dynamo DBに繋いでみたり

ky-yk-d.hatenablog.com

と、少しずつ知識は広がってきていますが、その中で、チラチラと目に入りながらも避けてきたものがあります。

それは、Webpackです。

公式のホームページかっこいいですね。

webpack.js.org

単にWebサイトの基本やVue.jsの文法を学ぶだけなら、Webpackなどのモジュールバンドラーを使う必要はないのですが、

  • Vue.jsの勉強をしていると途中からvue-cliが導入されたり
  • 使おうとしているライブラリのサンプルがWebpack前提だったり

と、ここから先に進むにはブラウザでそのまま動くファイルだけでは限界があるなと感じ、Webpackの勉強を始めることにしました。

例によって、山田祥寛さんの書籍を見ながらぽちぽちやりまして、ソースコードGitHubに上げていっています(サンプルコードそのままではありません)。

速習webpack 速習シリーズ

速習webpack 速習シリーズ

github.com

まだ、書籍も途中なのですが、基本的なファイルのローダーを扱うところまでできましたのでまとめてみます。まだ理解が不十分なので、間違ったことを書いているかもしれません。お気づきの方はコメントくださると幸いです。

Webpackを導入する

Webpackとは何か

「モジュールバンドラー」です。JavaScriptスタイルシート、画像ファイルなどをまとめるツールとのことです。モジュールバンドラーを利用するメリットとしては、以下のようなものが挙げられています。

  • 依存関係の解決
  • リクエスト数の抑制
  • ソースの可読性の向上・グローバル汚染、名前の競合の回避

個人的な経験としても、htmlファイルの中に<script>タグでJSファイルを埋め込んでいくときに、記述の順番を間違えて動作しない(先に読み込んだJSから後に読み込むJSを利用していた)という経験をしており、これが増えてくるとヤバそうだと感じていました。かといって、ひとつのファイルに全部書き込むのは嫌なので、モジュールシステム、モジュールバンドラーの出番というわけですね。

モジュールバンドラーのなかでも、Webpackは広く採用されているものです。『速習Webpack』では、Webpackの長所として下記のものを挙げています。

3つ目の理由に関連したものかもしれませんが、採用実績が豊富であるため、試したいライブラリのサンプルが見つけやすいのもメリットではないかと感じています。

Webpackをインストールする

それでは、Webpackをインストールしていきます。npmを利用します。

ターミナル

> cd プロジェクトのパス
> npm
> npm init -y # -y は規定の値で設定ファイルを作成
# package.jsonが生成される
> npm install --save-dev webpack webpack-cli
# --save-dev はpackage.jsonにインストールするパッケージの情報を記録するオプション
# webpack-cli はwebpackコマンドを実行するために必要

package,jsonはNode.jsの設定ファイルで、依存関係などを記載しておくと別の環境で必要なライブラリを用意したいときに便利(npm installだけで構築できる)らしいです。

qiita.com

Webpackがインストールできたら、下記のような構成を作ります。

.
├── node_modules   ←npmでインストールしたライブラリが置かれる
│
├── dist ← バンドルしたファイルが出力される
│   └── index.html ←生成したJSファイルを呼び出すhtml
│
├── src ← Webpackによってバンドルされる対象のファイル
│   └── index.js ←エントリーポイント
│
├── package.json
│
└── webpack.config.js

このような構成を作って、npx webpackを実行すると、dist配下にmain.jsが生成されます。これがバンドルしたファイルです。npx [パッケージ名]で、ローカルのnode_modules内のパッケージを実行するコマンドです。

qiita.com

ちなみに、エントリーポイントと出力場所はデフォルトでそれぞれ、/src/index.js、/dist/main.jsになっているようですが、下記のような設定ファイルを作成することで変更することが可能のようです。このwebpack.config.jsは、ローダー等を追加する際にも必要になってきます。

webpack.config.js

module.exports = {
    mode: 'development', // productionを指定すると実行効率の良いコードを生成する
    entry: './src/index.js',
    output: {
        path: `${__dirname}/dist`,
        filename: 'main.js'
    },
/* 後略 */

開発サーバーの導入

静的Webサイトを作るだけであれば、上記のnpx webpackコマンドを実行してから/dist/index.htmlを開けばよいのですが、いちいちビルドするのはだるいので、開発サーバーを導入します。ホットリロードってやつですね。

ターミナル

npm install --save-dev webpack-dev-server
# 開発サーバーがインストールされる

webpack.config.js

module.exports = {
  /* 中略 */
  devServer: {
    contentBase: './dist'
  },
};

[プロジェクトルート]/dist配下のファイルがコンテンツとして公開されるということですね。

次に、開発サーバーを起動するためのコマンドにショートカットを設定しておきます。package.jsonを編集します。ここではビルド用のショートカットも設定しています。

package.json

"scripts": {
    "start": "webpack-dev-server  --open",
    "build": "webpack --config webpack.config.js"
},

こうしておくと、npm startコマンドで開発サーバが起動します。package.jsonscriptsに記載した内容はnpm run hogehogeで呼び出せるようになりますが、startは特殊らしく、単にnpm startで起動できるようになります。

ローダー

モジュールバンドラーとしてのWebpackのコアな機能は、JavaScriptのモジュールをバンドルすることなのですが、ローダーを用いるとCSSや画像ファイルをモジュール化して、Webpackのバンドルの対象とすることができます。

山田さん曰く、

webpackを学ぶということは、ローダーを学ぶことである

とのことです。書籍では様々なファイルに対応したローダー(スタイルシート、画像、Webフォント、CSVJSON、HTMLなど)を紹介していますが、スタイルシートに関わるものだけご紹介します。

スタイルシートのバンドル

css-loaderによってスタイルシートを読み込み、style-loaderによって<style>要素として埋め込みます。いずれも、npm installでインストールします。インストールしたローダーは、webpack.config.jsに記載します。

webpack.config.js

module.exports = {
/* 中略 */
    module: {
        rules: [
            // スタイルシートを処理するローダー
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    'css-loader'
                ]
            }
        ]
    }
};

use要素で指定したローダーは、逆順に処理されるので、上記の設定によって

  • 拡張子が.cssのファイルに対して、
  • css-loaderでモジュール化して、
  • style-loaderでページに埋め込む

という処理が施されることになります。エントリーポイントである/src/index.jsから、import './hogehoge.css;という形でモジュールとして読み込むことができます。

外部ファイルとして出力する場合について

スタイルを<style>タグで埋め込むのではなく外部ファイルとして出力して利用したい場合には、style-loaderは使えません。『速習Webpack』では、この用途のために、extract-text-webpack-pluginを用いています。

github.com

しかし、これはまさにこの記事を執筆していて気づいたのですが、Webpack 4 以降ではこのプラグインは非推奨となっているようです。

docs(readme) WP4 deprecation for css. Link to MiniCSSExtractPlugin (#… · webpack-contrib/extract-text-webpack-plugin@0b69b72 · GitHub

現在では、mini-css-extract-pluginがWebpack 4 で利用されるべきプラグインとされています。こちらについては使ってみていないのですが、余裕があれば別途使用してみて記事にするかもしれません。

github.com

その他のファイルのバンドル

バンドル対象としたいファイル形式と、紹介されているローダーだけ記載しておきます。

  • 画像ファイルのバンドル
    url-loaderを用います
  • フォントファイルのバンドル
    file-loaderを用います
  • JSONファイルのバンドル
    気味の悪い拡張子のファイルですが、Webpackは標準対応しているのでローダー不要です
  • CSV/TSVファイルのバンドル
    csv-loaderを用います
  • HTMLファイルのバンドル
    html-loaderを用います
  • XMLファイルのバンドル
    xml-loaderを用います

おわりに

今回、WebpackをWebpackとして勉強してみて、使い方はなんとなくわかりました。ホットリロードが便利なので、これからは積極的にWebpackを用いて開発していこう!と思いました。

  • Node.js
  • モジュール
  • ES2015
  • Sass

などについても、Webpackを使いながら勉強していこうと思います。UdemyのコースでもWebpack使うみたいなので、楽しみですね。