dackdive's blog

新米webエンジニアによる技術ブログ。JavaScript(React), Salesforce, Python など

認定スクラムマスター研修(CSM)で学んだこと

だいぶ前ですが、2/13-15 に認定スクラムマスター研修を受けて、無事認定スクラムマスターになりました。

f:id:dackdive:20190405022421p:plain:w100

こないだ社内でも報告会をやったんですが、ここにも学んだこととか思ったことをメモしておきます。
研修の内容についての詳細はあまり書かれてません。(別にバラされて困ることない、って講師の方はおっしゃってましたが)


認定スクラムマスター研修 (CSM) について

いくつか運営団体があるようですが、自分が受講したのは Scrum Alliance という非営利団体が管理しているやつです。
Odd-e Japan という会社から申し込みました。

講師はエバッキーこと江端さんで、この方は唯一の日本人の認定スクラムトレーナーです。


学び

スクラムマスターはチームの誰よりも論理的に物事を考えられなければならない

個人的に一番誤解していてショッキングだったのがこれ。
3日間の研修中、本当に論理的思考力を要求されました。

理由は後述。


スクラムとは「プロジェクトの現状把握をするためのフレームワーク
  • 一般にフレームワークとは「課題発見」の手助けとなるものと「課題解決」の手助けとなるもの(あるいはその両方)があるが、スクラムは前者
    • もっと言うと、発見されたものを課題とみなすかどうかまでチームに委ねられている
  • 課題を解決するのはチームのメンバー。スクラムが解決してくれるわけではない

...という話を聞いて、前もネットで似たようなこと聞いたなーと思ったら ryuzee さんのこのツイートでした。


世に出回っている「スクラム」に関する本は、ほぼ「チーム(開発メンバー)」目線で書かれたもの。スクラムマスターの目線で書かれた本はほとんどない
  • スクラムに登場する3つの役割として「プロダクトオーナー」「チーム(開発チーム)」「スクラムマスター」があるが、各役割から見たスクラムは全く別モノ
    • 責任範囲が違うので
    1. じゃあ、スクラムマスター目線でスクラムを学ぶには?
      1. スクラムアジャイル開発が生まれた背景にある学問を学ぶ。「組織論」と「集団心理学」

優れたスクラムマスターというのは、極論言うと「「チームの目的にスクラムがマッチしてなかったらスクラムを辞め、別の手法をとる」ことを提案できないといけない。
そのためにはスクラムがどういう背景で生まれたのかとか、その他の手法について熟知してないといけない。
「何がなんでもスクラムをやる」はスクラムマスターじゃなくてスクラムスレーブ(奴隷)。


スクラムチームの3つの役割と責任
  • プロダクトオーナー
    • 投資対効果(ROI)を最大化する
  • チーム(開発チーム)
  • スクラムマスター
    • プロダクトオーナーやチームが目的を達成する確率を最大化する

※ROI や生産性の定義(何を分母分子とするか)は目的によって異なる

すべて「最大化」なのがポイント。常に過去より良くする活動を続ける責任がある。


2つの責任:Accountability と Responsibility
  • 未来に対する責任が Responsibility(説明責任)、過去に対する責任が Accountability(実行責任)
  • 例:熱々のやかんに手を触れようとしている子供と、その親がいて
    • 親が子に向かって「やけどするから危ないよ!」と注意喚起するのが Responsibility
    • 子がそれでもやかんを触ってやけどしてしまったら、それは子の Accountability
  • スクラムマスターが背負うのは 基本的に Responsibility のみ
    • プロダクトオーナーやチームは Accountability も Responsibility も持つ
  • 実行責任を伴わない分、スクラムマスターがプロダクトオーナーやチームに対して行う提案には非常に重みがある
    • 誰よりも「なぜそうすべきなのか」を論理的に説明できないといけないし、その提案は関係者の次の行動に影響を与えるので大きな責任が伴う
    • かつ、スクラムマスターが行うのはあくまで「提案」であって「指示」ではない。提案を受け入れるかどうかはプロダクトオーナーやチームに委ねられている

なので、スクラムマスターには常に現状から一歩先の未来を見通す能力が必要。チームと同じ時間軸で物事を考えているだけでは不十分。
未来に向かって今取るべきアクションを論理的に考え、他人に説明し、納得してもらった上で対象者の行動を変えていかなければならない。
※何がなんでも自分の意見を採用してもらう、というわけではない。提案を納得してもらった上で、チームが別の選択を取るということも受け入れなければならない。その場合はそこでの選択を受けて事前に描いていた未来を描き直し、次の提案に向けてすぐに動き出さなければならない。


自律的なチームに必要な要素
  • 目的が明確
    • できていたかどうかの判断が人によってぶれない
  • 境界線が明確
    • やっていいことと悪いこと、判断基準がはっきりしている
  • 目的を実現するために何をすべきか瞬時に判断し、行動し続けている


(質問)チームが自律的になったらスクラムマスターは不要ですか?スクラムマスターがいないチームというのは健全でしょうか?

これは研修の最中に自分が講師の方にした質問。
今の自分のチームにはスクラムマスターがいないので、それってアリなの?というのが気になっていた。

回答としては「基本的にスクラムマスターが不要になる瞬間というのはないと思って良い」とのこと。

ただ、続けておっしゃっていたのが

スクラムマスターがいなくなることはない。なぜなら、スクラムマスターが関わる対象は
開発チーム→プロダクトオーナーまで含めたスクラムチーム→複数のスクラムチーム→ステークホルダーも含めた「組織」
まで広げていかないといけないから。
逆に言うと、開発チームというミクロな視点で見てスクラムマスターがいないというのは問題だとは思わない

ということだったので、モヤモヤが晴れたとともにスクラムマスターが背負っていうミッションの大きさを再認識させられました。


感想

研修中は課題に対してとにかく論理的に解を出すことが求められ、ちょっとでも理論に穴があると突っ込まれ、停滞する、ということを繰り返した3日間で、本当にきつかったです。
日頃いかになんとなく行動を決めているかを痛感します。

スクラムマスターというとチームが自律的になるための支援をする人、ぐらいの認識だったので、どちらかというと人間力のようなものが求められるのかと思っていましたが
そこが間違いだったことに気づけたのは個人的には一番の学びでした。

また、重要なのは今後自分がどう行動していくか、また自分の行動によって周囲の行動をどう変えていくかだと思いますが
今のところチームでスクラムマスターになりたいと立候補するつもりはなくて、
スクラムマスターとしての考え方を身につけた上で、引き続きチームの1メンバーとしてカイゼンを続けていこうと思っています。

VSCodeVimでxやsでコピー(ヤンク)しないようにする

メモ。

素の Vim ではこちらの記事を参考に xs で1文字削除したときにクリップボードにコピーされないようにしていて、

VSCodeVim でも同様の設定をしたい。


方法

settings.json (コマンドパレットの Preferences: Open Settings (JSON)) を開き、以下を追記する。

"vim.normalModeKeyBindings": [
  {
    "before": ["x"],
    "after": ["\"", "_", "x"]
  },
  {
    "before": ["s"],
    "after": ["\"", "_", "s"]
  }
]

ESLintとPrettierを併用するときの設定(eslint-plugin-prettier, eslint-config-prettier)

今さらだけどメモ。
ESLint を使っているプロジェクトに Prettier を導入するときの設定方法。

結論としては、公式のこのページに全部まとまってた。

なお、 prettier-eslint というのもあるようだが調べていない。


先にまとめ

  1. eslint-plugin-prettier: ESLint と一緒に Prettier のチェックをしたい場合に導入する
  2. eslint-config-prettier: Prettier とバッティングする、ESLint のフォーマット関係のルールを無効化する
  3. 1, 2 両方やりたい場合、両方インストールして ESLint の設定に "extends": ["plugin:prettier/recommended"] と書けば OK

eslint-plugin-prettiereslint-config-prettier も公式のパッケージ。


1. eslint-plugin-prettier: ESLint と一緒に Prettier のチェックをしたい場合に導入する

eslintprettier コマンドを別々に実行するのではなく、ESLint で Prettier のチェックも同時にしたい場合に導入する。

$ yarn add --dev prettier eslint-plugin-prettier

ESLint の設定 ( .eslintrc.json ) には以下のように書く。

{
  "plugins": ["prettier"],
  "rules": {
    "prettier/prettier": "error"
  }
}

// main.js
const a = 1
var b = "foo";
let c = function() {};


console.log(b);

結果

# eslint-config-standard を extends してるとする
$ ./node_modules/.bin/eslint main.js
/Users/yamazaki/workspace/eslint-prettier-playground/main.js
  1:7   error  'a' is assigned a value but never used        no-unused-vars
  1:12  error  Insert `;`                                    prettier/prettier
  2:9   error  Strings must use singlequote                  quotes
  2:14  error  Extra semicolon                               semi
  3:5   error  'c' is assigned a value but never used        no-unused-vars
  3:5   error  'c' is never reassigned. Use 'const' instead  prefer-const
  3:17  error  Missing space before function parentheses     space-before-function-paren
  3:22  error  Extra semicolon                               semi
  3:23  error  Delete `⏎`                                    prettier/prettier
  4:1   error  More than 1 blank line not allowed            no-multiple-empty-lines
  6:15  error  Extra semicolon                               semi

Prettier でフォーマットされる箇所が ESLint の1ルールとして検出されている。
また

https://github.com/prettier/eslint-plugin-prettier

The rule is autofixable -- if you run eslint with the --fix flag, your code will be formatted according to prettier style.

なので、--fix オプションつきで実行することによりフォーマットしてファイルを上書きすることも可能。


2. eslint-config-prettier: Prettier とバッティングする、ESLint のフォーマット関係のルールを無効化する

先の例で、セミコロンの有り無しは eslint-config-standard の設定と Prettier のデフォルト設定がコンフリクトしている。
このように ESLint のフォーマット系ルールは Prettier とコンフリクトする可能性があるので、それらのルールを無効化するために導入するのが eslint-config-prettier

$ yarn add --dev eslint-config-prettier

ESLint の設定 ( .eslintrc.json ) には以下のように書く。

{
  "extends": ["prettier"]
}

なお、

https://github.com/prettier/eslint-config-prettier#installation

Then, add eslint-config-prettier to the "extends" array in your .eslintrc.* file. Make sure to put it last, so it gets the chance to override other configs.

とあるので、extends に複数の config を指定する場合は一番最後に設定する。

// .eslintrc.json
{
  "extends": ["standard", "prettier"]
}

先ほどの main.js に対して

$ ./node_modules/.bin/eslint main.js
/Users/yamazaki/workspace/eslint-prettier-playground/main.js
  1:7  error  'a' is assigned a value but never used  no-unused-vars
  3:5  error  'c' is assigned a value but never used  no-unused-vars

フォーマット系のエラーは出なくなった。
ただし、全部無効化しているだけで Prettier のチェックもしていないので、 --fix オプションをつけただけでは何も起きない。
(別途 prettier --write をすればフォーマットされる)


注意 (2019/03/16追記)

https://github.com/prettier/eslint-config-prettier#special-rules によると、いくつか理由があって無効にしているルールがあるらしく、必要なオプション含めて各自判断しながら有効化しないといけないものがあるらしい。


注意2 (2019/03/17追記)

https://github.com/prettier/eslint-config-prettier#installation
をちゃんと読むと、

If you extend a config which uses a plugin, it is recommended to add "prettier/that-plugin" (if available). For example, eslint-config-airbnb enables eslint-plugin-react rules, so "prettier/react" is needed:

とあるので、 eslint-plugin-xxx を入れている場合は (あれば) 対応する prettier/xxxextends に追加すると
そのプラグインに含まれるフォーマット系のルールを無効化してくれる。

{
  "extends": [
    "airbnb",
    "prettier",
    "prettier/react"
  ]
}


3. 1, 2 両方やりたい場合

Use Both セクションに書かれている通りだが、1, 2どちらも有効にしたい場合は
それぞれの設定を書く必要はなく、 "extends": ["plugin:prettier/recommended"] と書けば OK。

// .eslintrc.json
{
  "extends": ["plugin:prettier/recommended"]
}

eslint-plugin-prettier , eslint-config-prettier どちらも npm install / yarn add しておく必要があることに注意。


注意 (2019/03/17追記)

eslint-config-prettier のところで書いた、eslint-plugin-xxx に対応する prettier/xxx については

// .eslintrc.json
{
  "extends": [
    "plugin:prettier/recommended",
    "prettier/react"
  ]
}

というように書くとうまく効いてるように見えた。
(動作確認したが公式ドキュメントからは見つからず)


その他

これらの設定をしても、 rules: { ... } のところに個別にフォーマット系ルールを設定していた場合はそっちが勝つので注意。当たり前だけど。

「よくわかるWeb Components」を読んだ

Web Components を学ぶべく、昨年の 技術書典5 で販売されていた 1000ch さんの本を買って読んでみました。

2時間程度で読み切れるので、Web Components 全く知らない状態から概要を理解するのにはとても良い本だと思います。
自分は Web Components がどういうものかぐらいは知っている状態で読んだけど、第1章で Web Components を採用するメリットや構成技術について再確認できたし、続く第2章以降で実際のコードを見ながら学べたのはよかったです。

そして、この本を読んだ後に昨年の HTML5 Conference 2018 のこのスライドを見返すとより一層理解が深まりました。
(Conference 当日にセッションを聴いていたが、そのときはほとんど理解できてなかった)

コードを写経したものは↓にあげておきます。


本書で学べること

  • Web Components およびそれらを構成する Cutome Elements、Shadow DOM、ES Modules とはどういう技術か
  • 実際に生のJavaScriptで Web Components を書くとどんな感じか
  • 名前しか知らなかった lit-html がどんな役割を果たしているのか


次に勉強するなら

最近リリースされた Ionic 4 が、Angular 以外の UI ライブラリもサポートするために Web Components で実装したみたいな話を聞いて、そしてそれには Stencil.js という TS + JSX で Web Components 作れるライブラリを使用してるらしいので気になっています。

参考:Introducing Ionic 4: Ionic for Everyone | The Ionic Blog

あとは https://www.webcomponents.org/コンポーネントのサンプルを眺めてみるとか。


以下、学習メモ


第1章

  • Web Components とは
    • 部品の本質的な再利用を、web標準技術で可能にする概念
  • メリット
    • ブラウザネイティブで動作する
    • ツールやライブラリに依存しない
    • 既存プロジェクトの技術と競合しにくい(ReactなどのUIライブラリと共存できる)
    • Shadow DOMによる本質的なスコープ
  • 構成技術
    • Custom Elements
    • Shadow DOM
    • ES Modules


第3章

  • 3.2 attachShadow() できるDOM要素は限定されている
  • 3.4 <slot> 要素を使うと、ホスト要素の子要素をShadow DOM内に挿入できる
<div>
  #shadow-root
    <slot><!-- ここには2つの<p>が入る --></slot>
    <slot name="foo"><!-- ここには<button>が入る --></slot>

  <p>Inserted into default slot</p>
  <p>Also inserted into default slot</p>
  <button slot="foo">Inserted into slot[name=foo]</button>
</div>


第4章

  • 4.4 <script nomodule src=...> とすると、ES Modulesに対応していない環境でのみスクリプトが読み込まれる
    • <script type="module"> と併用できる


第5章

  • 5.3 lit-html
    • Polymer チームが開発
    • 仮想DOMのような仕組みを使って効率よくDOMを更新できる
    • html`<div>...` でテンプレートを記述し
    • render(this.template, this.shadowRoot) で render する

「モブプログラミング体験会 with Chris Lucian」に行ってきた

今日はこちらのイベントに参加してきました。

きっかけはこちらのツイートが TL に流れてきたのがたまたま目に留まって。

行きたかった Regional Scrum Gathering Tokyo 2019 の基調講演に登壇された方からモブプロを学べるってすごいイベントなのでは?と思ったのと、
ちょうど職場環境が変わって業務でモブをがっつりやることになったので、何か持ち帰れるものがあればと思い参加しました。

Twitterハッシュタグ#MobExperiment


私のモブプログラミング経験

先月サイボウズという会社に転職して、そこで初めてモブプロというのを経験しました。
私が所属する kintone チームでは現在、基本的に業務はすべてモブで進めるというスタイルをとっています。
kintone という1つのプロダクトに対してのプロダクトバックログが1つあり、そのバックログを共有する 3~4 名のモブチームが複数存在するという形です。

(ちょうどそんな話を弊社の @ama_ch さんが RSGT2019 で話してました: チームワークの会社で最高のプロダクトを目指すチームができるまで / RSGT2019 - Speaker Deck )

1ヶ月ほど経ってようやくモブで進めることに慣れてきました。
雑多な感想として、私のような新規メンバーのオンボーディングとしてモブは非常に強力だと思います。
既存コードの読み進め方や不慣れな技術スタックがある中で、一人で試行錯誤するのに比べて圧倒的に効率よく知識のキャッチアップができていると感じます。

一方で、以下のようなモヤモヤというか、「こういうときどう対処するのがいいんだろう?」みたいな疑問も生じ始めているところでした。

  • 終日モブで一人で考える/調べる/学ぶ時間が無い
    • 9:45 のデイリーから始まって 18:00 頃まで基本モブ(MTG などの予定がない限り)
    • モブの中で生じた、もう少し知識を深めておきたい/周辺のコードも理解しておきたい みたいなことはモブ終了後になりがち
    • 自分はそういう自己研鑽が業務外になることを良しとしてしまってる人間なので問題だと思ってないが、次に入ってきたメンバーに同じような考えを強制したくはないなあみたいな気持ち
    • ※ それでも 18:00 にはだいたい終わりにしてるから、30 分ぐらいは毎日確保できてる計算になる
  • モブに決まったタイムボックスがない
    • 午前はなんとなく 12:00 の昼休憩までで1つの区切りになるが、午後はドライバーの交代や休憩のタイミングがまちまち
    • 個人でタスクを進めてたときにポモドーロを取り入れてたこともあって、個人的には1コマ○分とかあった方がリズムができていい
    • タイムボックスとかないのが一般的?
  • 次スプリント以降のバックログに対する技術調査を誰が・いつするのか
    • バックログリファインメントで Ready とは言ったものの、「○○する方法については技術調査必要だよね」とか「実際どこ直せばいいのかは事前に軽く調べといた方がいいよね」みたいな状況に何度か遭遇した
    • そういった時間をどこで確保すればいいのか
    • モブの途中に内職することもできそうだが、それだとモブに参加してる意味がないし一人だけ隠れて悪いことをしてるようで誠実ではない
  • 自分がドライバー以外のときにモブに貢献できてないことがある
    • みんなが議論している以前のところでつまずいてることがあり、沈黙状態になる
    • ※これは完全に自分が悪いと思っている。メンバーとしての質問責任を果たしていない


勉強会の内容

午前パートは Chris さんからのプレゼン形式。
前半モブプロとは何かという基本的な話、 Chris さんの所属する Hunbter Industriesでのモブプロやそれ以外のふりかえり・テストなどについてのプラクティスなどを教えていただきました。

ツイートされてたので後で観ましたが、 Chris さんの会社の雰囲気はこの動画がとても参考になります。

ランチをはさんで午後は実際にモブプロを経験。
参加者を2チームに分けて即席チームを作り、お題に取り組みました。


午前パートのメモ

Chris さんの所属している会社でのプラクティスをかなり具体的に説明してくださったんですが、いかんせん自分の英語力が低く理解できなかった部分も多かった...
(これは今回の反省点で、話さえぎってでも都度都度自分の理解が合ってるか確認すべきでした)

その中でも印象に残っていることを。


モブプログラミング RPG

モブするときの役割を RPG っぽく定義したもので、GitHub で公開されてます。
https://github.com/willemlarsen/mobprogrammingrpg

ドライバー以外はみんなナビゲーターかと思ってましたが、こんなにあります。

f:id:dackdive:20190113025313p:plain

(https://github.com/willemlarsen/mobprogrammingrpg/blob/master/Mob%20Gallery.pdf)

そしてモブを RPG とみなして、自分が今何のロールを演じているかはっきりさせることで、自分がモブの中で果たすべき役目が明確になりますね。

ここにある全ロールはこれからじっくり見ていこうと思いますが、個人的になるほどと思ったのが Researcher というロール。

f:id:dackdive:20190113025628p:plain

(https://github.com/willemlarsen/mobprogrammingrpg/blob/master/Researcher.pdf)

今、あるいはこれから必要になる技術調査をモブと並行して進めるロールだという理解です。
冒頭のモヤモヤに対する1つの解になってる気がします。「今から Researcher のロールやります」と言えばモブの議論から抜けることに抵抗がなくなりそうです。


Mob Timer(と、ふりかえりのタイミング)

モブプログラミング時に使えるタイマーアプリで、これも GitHub にあります。
https://github.com/MobProgramming/MobTimer.Python

f:id:dackdive:20190113030410p:plain

モブのメンバーを追加(タイマー下の左側のブロック)してタイマーをセットすると、時間が来たらスクリーンがロックされ、次のドライバーに交代を促されるらしいです。
Chris さんの会社では 1 コマ 45 分でやってると言ってました。

また、面白いなと思ったのはここのメンバーに「Retro」というのを追加して、1 周したタイミングで 45 分のふりかえりを実施するというもの。
(すべてのモブチームで統一してるわけではないよ、と言ってた気がしますが)


Learning Sessions(学習セッション)

Chris さんの会社では毎日1時間 (金曜は2時間) を学習(実験)のための時間として確保しているそうです。

チームで勉強時間と聞くと準備が必要な勉強会形式を想像しますが、一人でもくもくと調べるような時間も含まれているとのこと。
何をやるか、一人でやるか複数でやるか、はそのときそのときで変わるそうです。
(勉強会開くとして、準備の時間もこの枠で確保されてるみたいなイメージかな)


No Estimate

これはアジャイルや Chris さんの会社のことを知ってる人からすれば有名な話のようでしたが、個人的には衝撃でした。
見積もりをしないらしいです。ストーリーポイント使ってない。

その理由のところがうまく聞き取れず残念でしたが、ランチの最中にその話題に触れて

「僕らは価値ある機能をユーザーに一刻も早くデリバリーすることに重点を置いている。だから、僕らがやってるタスク(スクラムで言うユーザーストーリーのことだと思う)は着手してからリリースされるまで長くても 2 時間ぐらい。15 分ぐらいのもある。仮に T シャツサイズ見積もりしたとして、僕らからすると全部 Small になっちゃうよ」

「作ったものを素早くユーザーに届けて、それが本当に価値があったのかを計測することが重要。だから、あるフィーチャーがリリースされてから実際何%ぐらいのユーザーに使われているのかを計測できるようにしておくのは大事だよね」

といった旨のことをおっしゃってたのが印象的でした。


午後パートのメモ

参加者とチーム組んで、お題「三目並べを実装する」に挑戦しました。

※ ネタばらしをすると、これは「Chris と一緒に記念写真撮ろう!楽しくモブしてるっぽい写真にしよう」と言って撮った写真なので Chris さんがっつり演技入ってます。楽しかったのは本当です。

前半パートの Chris さんの話を参考に、僕らもタイマーでドライバーの交代タイミングを決める&1周したらふりかえることにしたんですが、モノを作るよりもモブでの開発を体験するのが目的なので 1コマ5分という高速サイクルに。

以下感じたことを箇条書きに。

  • とにかく楽しい
    • この勉強会に参加するぐらいの人だから熱量が高かった
  • 物理的にPC共有すると 5 分交代でもスイッチングコストそんなかからない
  • 何かあったときにさっと集合できる&フリーハンドで書ける場があるの強い
    • 業務でリモートでやってると、ここらへんに課題を感じることがある
  • 即席チームでも全然なんとかなる


クロージング

最後は2チームがそれぞれやったこと、感じたことを共有した後、自由な質問タイムに。
冒頭のモヤモヤにあった、モブで沈黙状態になる問題についてはある参加者から

「うちも新人とかがモブに加わった際、わかってないんだけどわかってないと言えず置いてけぼりになるという問題が発生してた。でも「わからないことはわからないと言う」っていうのをチームのグランドルールに設定したところ、それだけでもだいぶ効果があった」

という話を聞いて、あーそっか曖昧にせずチームで合意する・明文化するってだけでも改善されるものだなという学びがありました。


おわりに

熱が冷めないうちに書いてしまおうと思って書いたらまとまりがない長文になってしまいましたが、非常に多くのことを学べた濃い勉強会でした。

スクラムのプラクティスもそうですが、チームの問題はチームによって違うので、よそでうまくいってるプラクティスをただ持ってくるだけではうまくいかないというのは今回もあてはまりそうですが、それでも世界最高レベルでモブプロをうまくやっているチームの話が聞けて自分の引き出しが1つ増えたのは非常に良いことだったと思います。

また今回のイベントの運営側のみなさま、勉強会の最中はそこまで積極的に介入せず参加者に自由にやらせてくれましたが、英語でみんなが困ったときに助け舟を出してくれたりモブの最中は定期的に果物やコーヒーを差し入れたりしてくれて、参加者が気持ちよく過ごせるようにという配慮がとても感じられました。
今回の勉強会を企画・開催してくださったことも含め、本当にありがとうございました!

TODO:あとで読む

Chris さんが所属する Hunter Industries について昨年のアドベントカレンダーに記事があったようなので読む。
モブプログラミングという働き方 #モブプログラミング - ナイスビア珍道記

読書記録アプリを作ってkintoneの基本的な使い方を学ぶ

kintoneの使い方を勉強するのにちょうどいい題材はないかと考えたところ
自分が読んだ/読みたい本を管理するアプリが欲しいなと思っていたので、それを作りながら基本操作を学ぶことにした。


アプリのイメージ

読みたいと思った本や web 上のちょっと長い記事をどんどん登録して、読み途中・完了というステータスを管理するだけのシンプルなアプリ。
ゆくゆくは登録の手間をできるだけ省力化したい(URL 登録したら勝手に書籍タイトルが入る、とか)。
また読みたい本の優先度がころころ変わりそうなので、Jira のバックログみたく気軽に並べ替えられるならそういう機能もほしい。


目的

標準機能として kintone アプリでできることを理解するのが目的で、JS カスタマイズやプラグイン機能は含まない。
またなるべく画面だけ見ながら開発してみて、どこまで直感的に迷わず操作できるか試してみる。
加えて、詰まったときの情報検索の仕方を学ぶ。


作る

アプリにアイコンを設定する
設定 > 一般設定 > アイコンと説明

本棚っぽいアイコンどっかから探してこよう、と思ったら標準でも十分なのがあった。
これにします。

f:id:dackdive:20190111004401p:plain

項目作成

思いつきだが、こんな入力項目を用意する。

項目名 説明 データ型
種別 書籍📕かweb上の記事🔗か ドロップダウン
タイトル 書籍/記事のタイトル 文字列
リンク 書籍/記事へのリンク リンク
ステータス 未読/進行中/完了 を区別したい (後述)
開始日 読み始めた日。
ステータスを未読→進行中に変えたら自動でその日がセットされるとか将来やりたい
日付
完了日 読み終わった日。
こちらもステータスを完了に変えたタイミングで自動的にセットしたい
日付
経過日数 読み始めてから何日経ったか。または読み終わるまでに何日かかったか。
あんまり日が経ってるようだと目立たせたりアラートとばしたりしたい
計算(後述)
カテゴリー 書籍のジャンル。技術系とかビジネス系とか (後述)
メモ 感想など自由記入欄 リッチエディター

特に迷うことなく追加できた。

f:id:dackdive:20190111004452p:plain

ステータスとカテゴリーは項目じゃなくて別の機能を使うことにした。後述する。


経過日数を計算する

計算式で「今日」を使う方法がわからなかったので、とりあえず読み始めから読み終わりまでに何日かかったかだけやった。
日数を出そうとしたが計算結果の値が全然合わなかったのでググった。

よくあるご質問 | 日数の計算はできますか。

なるほど、(60 * 60 * 24) で割るらしい。正しく表示された。


カテゴリーを追加する

項目とは別に、こういった設定があるらしい。

設定 > その他の設定 > カテゴリー

これを使うと、レコード一覧を開いたときに左側にカテゴリー一覧が表示されるようになり、簡単にレコードをフィルターすることができる。

f:id:dackdive:20190111004624p:plain

カテゴリーは階層構造で持てるらしい。また1レコードに複数カテゴリー設定できる。


未読→進行中→完了 というステータス遷移を実現する:プロセス管理

なんらかのアクション実行ボタンを押して現在のステータスを変更する、みたいなのはプロセス管理という機能で実現できそうだ。

設定 > 一般設定 > プロセス管理

設定すると、レコード詳細ページ上部にアクションボタンが表示されるようになる。

f:id:dackdive:20190111005228p:plain


レコード一覧に表示する列を設定する

最後に、レコード一覧ページでの列を設定する。一覧設定からできる。

f:id:dackdive:20190111005406p:plain


できた

というわけで30分ぐらいでできた。

f:id:dackdive:20190111005522p:plain


TODO

発展的なお題として、これをもうちょっと使いやすくするために試してみたいことがいくつか。

  • アクションボタン実行に合わせて開始日・完了日の入力を自動化する
  • 経過日数が一定を超えたレコードはハイライト表示したり通知する
  • URL をリンク項目に入力したら勝手にタイトル補完してくれるようにする
  • ドラッグ&ドロップで行並び替えたい
    • かなり難しそう

「Google API Expertが解説するClosure Libraryプログラミングガイド」を読んだ

業務で Closure Library を使うので読んだ。
正確には、最後まで写経しながら読み進めようと思ったけど第5章あたりで挫折して、第6章以降はさっと目を通す程度になってしまった。

出版されたのが 2010 年とかなり古いが、Closure Library を扱った書籍としてはあとこれぐらいしか見当たらず(こっちは英語)。


事前に学んでいたこと

公式ドキュメントをかいつまんで読んだ程度。


本書で学べること

目次ベースでざっくりまとめておく。
Closure Library の基本的なコンポーネント開発方法と、Closure Compiler と組み合わせてコンパイルするための環境構築あたりに興味があったので
第4章まで読んだ後一旦第9章「Closure Compiler による JavaScript の最適化」を先に読んでから第5章に戻った。


第2章「Closure Library を使ってみよう」

depswriter.py, closurebuilder.py という Closure Library に同梱されているツールの使い方が紹介されていた。
Closure Compiler を使わずに Closure Library をどうアプリに組み込めばいいか知りたかったので、最初に言及されていたのは良かった。


第3章「Closure Library の基礎」、第11章「その他の機能」

Closure Library の豊富な UI コンポーネントや関数・ツール群について紹介がされているが、なにしろ膨大なので熟読して覚えるというよりは必要なときに参照できるようリファレンスとして手元に置いとくと良いなと思った。


第4章「Tiny Word アプリケーション」以降

ここから先は複数の章を通じて Tiny Word というサンプルアプリケーションを開発しながら、Closure Library の使い方を学ぶという構成になっている。
ただし第7章、第8章はアプリとして完成させるために Closure Library とは直接関係ないサーバーサイドの開発 (Google App Engine w/ Python) の話になっている。
一部 Closure Library を使った非同期処理の書き方も含むが、アプリを作りきるのが目的でなければこのへんはスキップしてもいいかも。

サンプルアプリで使用している Closure Library のコンポーネントは、主にこのあたり:

  • データソース ( .goog.ds.JsDataSource ) およびデータマネージャ ( goog.ds.DataManager )
    • 多くの形式のデータを共通のインターフェースで扱える
  • ツールバー、メニュー ( goog.ui.Tab , goog.ui.Menu )
  • ツリーコントロール ( goog.ui.tree.TreeControl )
    • こういうやつ↓

f:id:dackdive:20190109003313p:plain


第9章「Closure Compiler による JavaScript の最適化」

JavaScript の型チェックと最適化を行う Closure Compiler の概要と、closurebuilder.py と組み合わせて使う方法について。

特に

あたり、かなりページを割いて解説されていたのは有難かった。


第10章「デバッグ・テスト」

デバッグツール ( goog.debug , goog.asserts) の使い方、およびテストフレームワーク ( JSUnit ) を使ったテストの書き方。
残念ながらあんまちゃんと読めていない。


本書で学べないこと

  • Closure Template ( .soy ファイル) を使ったコンポーネントの開発方法
    • Soy テンプレートはこの書籍の対象外
  • コンポーネントの使い方 (override しないといけないメソッドなど) をどうやって調べるか
  • Closure Compiler の型チェックでエラーが出たときの原因と対処方法の調べ方
    • 9.3.3 に代表的なエラーをリストアップしてくれているが、ここに書かれていないエラーが発生したときに何が原因で怒られているのかよくわからなかった


その他:2019年にこの本を読む上での注意点

depswriter.py, closurebuilder.py の使い方が学べてよかった、と上に書いたが、書籍が出版された時代から Closure Compiler もいくらか進歩しており
コンパイル方法などは当時とは状況が変わってそう。

というのも、closurebuilder.py でビルドをすると、以下のような警告が出る。

$ python closure-library/closure/bin/build/closurebuilder.py \
  --root=closure-library \
  --root=scripts \
  --namespace="tinyword.App" \
  --output_mode=compiled \
  --compiler_jar=compiler.jar \
  --output_file=script.js
closure-library/closure/bin/build/closurebuilder.py: Scanning paths...
closure-library/closure/bin/build/closurebuilder.py: 1620 sources scanned.
closure-library/closure/bin/build/closurebuilder.py: Building dependency tree..
closure-library/closure/bin/build/closurebuilder.py: Closure Compiler now natively understands and orders Closure dependencies and
is prefererred over using this script for performing JavaScript compilation.

Please migrate your codebase.

See:
https://github.com/google/closure-compiler/wiki/Managing-Dependencies

おそらくだが現在は Closure Compiler 単体で goog.provide() / goog.require() の依存解決はできるみたい。
また Closure Compiler も現在は npm パッケージで公開されているものもある

さらに、こんな記事もある。

今回、自分も写経していてこのへんの開発効率の悪さ(ローカルサーバー立ち上げる、ファイル編集するたび closurebuilder.py 実行して待たされる、etc.)は結構ストレスを感じたので
開発環境まわりはこの後もう少し調べてみたい。