【前編】企業所属のRubyコミッター対談! 〜企業に所属するOSS開発者って何?〜

こんにちはCTO室の緑川です。今回はアンドバッドさんが主催しているPodcast「ANDPAD TECH TALK」第12回目のゲストに弊社の@mameが出演したので、対談内容を書き起こしました。Podcastとしてお聞きしたい方は下記のアンドパッドさんの記事からお聴きください。

tech.andpad.co.jp

トーク本編

櫻井:皆さま、こんにちは。アンドバッドの開発本部でエンジニアリングマネージャーをしている櫻井です。

櫻井:12回目のANDPAD TECH TALKです。ANDPAD TECH TALKはアンドパッドの中の人をゲストに招いてあれやこれやお話するカジュアルなテック系Podcastなのですが、今回スペシャル対談会として、社外ゲストをお招きして、アンドパッドの中の人の対談をお届けしたいと思います。今回は企業に所属するRubyコミッターであるお二人をお招きしております。

櫻井:アンドパッドからはRubyコミッターでありフェローの柴田さん、対談相手はクックパッド株式会社所属のRubyコミッターであるmameさんこと遠藤侑介さんをお呼びしております。柴田さんと遠藤さんの対談は前編・後編の2回に分けて配信します。前編では「企業に所属するOSS開発者ってなに?」と題して話を掘り下げていきたいと思います。

自己紹介

櫻井:本日はよろしくお願いいたします。早速ですが、遠藤さんの自己紹介をお願いできますでしょうか?

遠藤:こんにちは遠藤といいます。僕は大学院を修了したあと、企業の研究員として働いている時に、趣味でRuby開発に携わり始めました。それをしばらく続けていくうちにクックパッドに転職をして、今は笹田耕一さんというRubyのVMまわりを主に開発しているRubyコミッターと一緒にフルタイムでRubyの開発をするチームに所属して、日々活動しています。

遠藤:自分のRuby開発の担当範囲はいろいろな範囲にわたっていて、一番みんなが使っているところで言うと、キーワード引数周りの設計や実装を担当したのが大きいかなと思います。他には、コードカバレッジの測定をするためのバックエンドとなるライブラリの開発はクックパッドに入る前からやっています。クックパッドに入社したあとはRuby 3に型システムを入れるという話があったので、型システムまわりの議論をまとめ、TypeProfという型システムの試作を中心にやってきています。趣味はQuine(クワイン)と呼ばれる自分自身を出力するプログラムを書くということで、この趣味が高じて本を書いています。

櫻井:ありがとうございます。ちなみに、遠藤さんはmameさんというお名前で活動されていると思いますが、本日は遠藤さん、とお呼びさせていただこうかと思っていますがよろしいでしょうか?

遠藤:はい

櫻井:ありがとうございます。ちなみにですね、mameさんというハンドルネームの由来をお伺いしてもよろしいですか?

遠藤:子どもの頃のあだ名ですね。遠藤豆とよく呼ばれていたので、そこから取ってきたハンドルネームですね。日本チームにしか伝わらない。

櫻井:ありがとうございます。すごいシンプルな由来ですね。

一同:笑

櫻井:遠藤豆さん、と言うところからですかね?

遠藤:そうですね、単純に。

櫻井:ありがとうございます。皆さん、シンプルな理由でした。では、柴田さん、自己紹介をお願いいたします。

柴田:はい、よろしくお願いします。柴田 博志といいます。アンドパッドには、2022年の11月1日にフェローという肩書きで入社しました。前職では、執行役員(VPoE)だとか技術部長を兼務していて、マネジメントを主に担当していたのですけれども、現在は開発本部の直下に所属している一エンジニアみたいな肩書きになっていて、毎日部門で見かけた課題だとかエンジニアやマネージャーなどの幅広い人の相談にのったりと、前職の経験を活かしながら開発組織を支援する業務を担当しています。あとですね、フルタイムでRubyの開発をするのがメインの業務としていまして、僕は主にRubyで書かれている(Cで書かれているものもあるんですけど)、Rubyのライブラリであるとか、ライブラリを使うための RubyGems bundlerというソフトや仕組みがあるんですけど、そっちの開発を行っています。あとはですね、そのRubyというソフトウェアを開発するために必要なインフラであるとか、あとはSaaSのようないろいろなサービスを利用しているんですけど、そのメンテナンスとか管理も担当しています。趣味としてはいろいろと幅広く、アウトドアの趣味としては最近は美術館巡りで、アート・芸術・社会学関係の本を適当に買って読むということをやったり、あとは家の中ではゲーム・アニメ・漫画など家の中でできる遊ぶ系のものは大体プレイしたりいろいろやっています。最近は先週くらいにThe Witcher 3というPlayStation 4で出てたものすごい名作であるゲームが、PlayStation 5バージョンで出たのでずっとそれをやっています。 

櫻井:ありがとうございます。The Witcher 3の5バージョンが出たんですね。

柴田:はい、出たんですよ。

櫻井:今、アウトドアとインドアと幅広い趣味を紹介いただいて、どこを深く聞こうかな、と思ったのですが、思わずThe Witcher 3に食い付いてしまいました。

一同:笑

柴田:そうなんですよ。PlayStation 4の時は、ちょっと買って1時間くらいプレイして、まぁいいやって置いといたんですよね。PlayStation 5バージョンが出たのでやってみるか、と思って1時間ではなく4時間くらいプレイしたらめちゃくちゃ面白いじゃんとなって、今20時間くらいプレイしているんですけど、全然終わる気配がないので、もっともっと時間を投入してプレイしようかと思います。

櫻井:The Witcher 3、こう聞くと、私もやってみてみたくなるので意識しておきます。

Rubyコミッターってそもそも何?

櫻井:Rubyコミッターってそもそも何? どういうことをする人なの? という方も視聴者の中にはいらっしゃると思いますので、本日はそういったところもお二方に聞いていけたらなと思っております。遠藤さんと柴田さんは古くからお互いをよく知る間柄だとお聞きしましたが、どういったきっかけで知り合うことになったのでしょうか?

遠藤:はい、柴田さんと知り合ったのはRubyの開発がまさにきっかけですね。僕が2012年ごろにRuby2.0というバージョンのリリースマネージャーをやっていて、Rubyをリリースするためにいろいろな活動をしていたのですけど、その時に柴田さんが新しいRubyでRailsアプリケーションを走らせてみたり、結構テストしていてくれていて動かないところを報告するという活動を継続していてくれていたのを見ていて、その時にRubyの開発者であるまつもとゆきひろさんに「柴田さんへコミット権限を差し上げたらどうでしょう?」という話をして「いいね、いいね」という話になって、それがきっかけで柴田さんがRubyのコミッターになったという話があります。

櫻井:なるほど、その頃から柴田さんも遠藤さんのことはご存じだったのですか?

柴田:ちょっと覚えていなくてですね、たしかこの時ってRubyの20周年イベント前後ぐらいでしたよね? 2012年の2月前後だったと思うんですけど、当時はSlackもなかったし、Twitterはあったけどどういう感じで使っていたかわからなかったので、おそらくメールとかRedmineという課題管理ソフトを使っているんですけど、その上で頻繁に見かける方だったなとか、Ruby2.0をリリースするためにいろいろチケットにコメントしたり、クローズしたり、オープンしたりしている方だなくらいの理解でしたね。

櫻井:なるほど。遠藤さんがRubyコミッターになったきっかけや馴れ初めはどうですか?

遠藤:大学時代からRubyに簡単なパッチを書いて送るといった貢献を少しずつしていたのですけども、会社に研究員として働き始めた後くらいからRuby 1.9.0のバージョンのリリースがあって、その頃から本格的に貢献を始めてコミッターになりました。1.9.0のRubyというのは野心的な新機能がたくさんあってバグが結構あったんですよね。なのでバグ出しやパッチ作成などの貢献の余地が非常に多くあったのと、Ruby 1.9.0のリリースをするのにいろんな人たちが寄ってたかってパッチを書いているのが学園祭というかお祭りみたいだったんですよね。それがすごく楽しかったと思ったので深く関わり出したきっかけです。

櫻井:なるほど。楽しそうな印象が伝わってきました。お二人が今の関係性になるまでどんな接点があったんでしょうか?

柴田:そうですね。いつの間にかRubyコミッター同士で知り合いというか仲がいいというか、大体みんなのことを知っているよね、と今はなっているのですけど、馴れ初めを思い出すとなかなか難しいな。僕の記憶だとRubyKaigiのいつだったかの開催の時に、mameさんがクックパッドに転職します、みたいな紹介の回があって、その時くらいから遠藤さんと話す機会が増えてきたと記憶しているんですよね。それまでは遠藤さんは別の会社で働かれていて、昼間であるとか、Rubyに関する活動以外の時間は何しているかは謎みたいな状況だったのですけど、そのクックパッドに転職されて以降はRubyもRuby以外の生活も最近の話だとかそういった部分でもいろいろと会話することがどんどん増えてきていて、実際にRubyの何かをする時だとか、例えばサーバーを何か引っ越したりだとかしますとか、開発に便利なものを何か作ります、というときも遠藤さんに結構手伝っていただいているので、二人でいろいろあーして、こーしてみたいなところを二人三脚でやるといった機会が増えてきて、今に至っているのかな、と思います。あと確か、間違っていたらひどい話なんですけど、同い年なんですよね?

遠藤:そうですね。

柴田:というのもあって、同年代エンジニアとして頑張るぞ、という感じで僕は捉えています。

櫻井:なるほど、それで今回、対談のお相手にぜひ遠藤さんと話したい、というお話が柴田さんからあったということですね。

柴田:はい、そうです。

遠藤:柴田さんとは、説明にあった通り、Rubyの開発をするインフラ管理なんかでだいぶお世話になっていますし、RubyKaigiとかRubyConfとかのRubyに関するイベント参加の時に一緒にうろうろするとか一緒にご飯食べるとかさせていただいています。なので、今回このアンドパッドにフルタイムのコミッターとして転職されて、どんな話をするのか非常に面白そうだと思って今回呼ばれました。

櫻井:今日のテーマが「企業に所属するOSS開発者ってなに?」なんですが、そもそもRubyコミッターってなに?という方も視聴者の中にはいらっしゃると思っています。なので、お二人から少し解説をいただけると嬉しいな、と思っていて、遠藤さんお願いいたします。

遠藤:はい、コミッターというのは、昔のバージョン管理システムの用語なんですけども、ソースコードの更新をする権限を持っている人のことです。gitだとコミットというのは履歴に変更を積むというだけの作業なんですけど、昔、gitよりも前のバージョン管理システムCVSだとかSVNだとかサーバー側に置いてあるソースコードを更新する行為のことを呼んでました。なのでgitの時代というとmergeだとかpushに相当するのですけど、その当時にコミットできる権限を持つ人をコミッターと、特に日本のRuby界隈ではソースコードを変更する権限を持っている人のことをコミッターというふうに呼ぶことが多いと思います。

櫻井:なるほど。そういう経緯からコミッターと呼ばれているんですね。僕も知らなかったですし、詳細までありがとうございます。

どうしてオープンソースで開発をしているのか?

櫻井:最近だと、オープンソースのソフトウェアを利用して、企業がサービスやプロダクトを開発するということが当たり前のようになってきているかな? と思うんですが、若い方はOSSとはそもそもなんなのか? あとどうしてオープンソースで開発をしているのか? といったようなところも知らないエンジニアもいらっしゃるのかな? と思っています。例えば、Googleなどの企業が母体となっているオープンソースプロジェクトなども増えてきている印象なんですが、その辺り柴田さんにお伺いしてみてもよろしいでしょうか?

柴田:はい、非常に難しい質問というか、解説になりそうな気がするのですけど、できる範囲でやろうかと思います。僕の理解としては、オープンソースは狭義のオープンソースと広義のオープンソースがあるかなと思っていて、狭義の意味としては「オープンソースデフィニション」という「これを満たしたソフトウェアはオープンソースであるよ」というものがあるんですね。それを満たしてたらなんでもオープンソースである、と言えます。それを開発している人はもちろんオープンソースの開発者になれる。なので、別にRubyみたいにプログラミング言語だけでなく、なんか自分で作った自分のカレンダーを管理するだけのソフトウェアであったとしてもそれがちゃんとオープンソースの定義に合致していればもちろんオープンソースですし、それを開発している方はみんなオープンソースの開発者であると、一旦狭い意味でのオープンソースです。で、もうちょっと定義ではないオープンソースソフトウェアというのは、経済とか社会とかとりまく環境の方で捉えてみるとオープンソースのソフトウェアは経済や社会みたいな部分だと今までにはない、不思議な存在となっていて、で、それが何かというとですね、会ったこともない人がなぜか自社の利益や売上を生むようなビジネスの中心にあるソフトウェアをメンテナンスしていて、なぜか何もお願いしていないのに不具合があったら直してもらえるし、欲しいなと思っている機能があったら開発をしてくれる、でそれを使ってそれぞれの所属している会社であるとか組織とかの利益や目標のためにそれを使うことができる。しかも無償で。というのがオープンソースソフトウェアの不思議な存在になっています。で、他の業界を見るとですね、たとえば、アンドパッドがメインとしているような建設業界だとか他の機械だとかいろいろな業界がありますけど、そういった業界ですと、こういうオープンソースのソフトウェアと似ているものはほとんどないな、と思っていて、ほとんどが特許、設計図だとかそういった規格は特許に守られていて、使うためには利用料金を払わなければなりません、とか、なんならもう使えない、みたいなものもいっぱいあるんですよね。ソフトウェア業界だと、オープンソースソフトウェアというものがあって、なぜか他の会社が開発したり、一個人が開発したものを無償で使って、それをビジネスの原動力に使える、というものになっています。でそれが今まで、現在進行形ですけど、オープンソースソフトウェアのざっくりとした説明になっていて、そのオープンソースソフトウェアのメンテナンスはいろんな人が何もお願いしなくてもずっと無限にやり続けてくれるのかというとそういうわけでもなくて、そのオープンソースソフトウェアというものがですね、ビジネスの中心になればなるほど、ビッグテックと呼ばれるようなGoogleだとかAppleだとかといった企業が主導してオープンソースのソフトウェアをメンテナンスしたり、会社によってはですね、社会全体の利益よりも自社が使いたい機能なので、といった形でそれを開発しているとか、いろいろ難しい問題も起きているというのが現状です。で、そのような中でですね、Rubyというプログラミング言語がありまして、私柴田であるとか、遠藤さんはそれぞれべつの企業に所属しながらも、それぞれの企業の事業の中心として使われているRubyのメンテナンスを業務として毎日行っているというのが現在になっています。

櫻井:Rubyの場合は母体となる企業があるわけではなくて、コミュニティが主体となって、活動してきているということですね。そういったコミュニティがメンテナンスや開発を進めていかないと、いけないというところで、本日のリスナーの皆さんが気になっている企業所属のOSS開発者とは何か? というところで、なぜ企業は自社のサービス開発ではなくてOSSの開発を主体とするエンジニアを迎え入れるのか、という話につながってくるのかな? と思います。と、いったところで、お二人が企業所属のRubyコミッターになった経緯をお伺いしたいと思います。まずは遠藤さんから、よろしいでしょうか?

遠藤:はい、前職の企業で研究者をやっていた時から趣味としてRubyの開発には参加していたのですが、自分も周囲も特に業務でRubyを使用しているわけではなかったので、いまいちRubyに実際にどうのような機能が求められているのか、といった現場感があまりなかったのがあります。そんな中でRuby2.0のリリースマネージャーを務めて、結構盛大なリリースパーティー、20周年かつ2.0のリリースパーティーといったものが行われたんです。実際のリリースはその翌日にですね、自分が自宅から、確か冬だったのでコタツで細々とリリース作業をするという自分ではあまり使用していないRubyをリリースするということをやっていて、一抹の寂しさのようなものを感じたというのがあります。そんな経緯もあって、そこからしばらくRubyの開発から1、2年ほど離れるんですけど、世間はその間にですね、ちょうどRuby on Railsが非常に盛り上がり始める時期だったので、Rubyの需要がさらに盛り上がっていき、遠目に見ていて楽しそうだな、と思っているところがありました。で、その時にクックパッドに転職をしたばかりの笹田さんからクックパッドでRubyの開発をしませんか? というお誘いをもらったので、転職をするきっかけになりました。その後はクックパッドの中で実際にRubyを開発に使っているという人たちからフィードバックをもらったり、会話したりしながらRubyの開発ができているので、とても毎日が楽しいです。

櫻井:柴田さんは11月にアンドパッドにジョインしたばかりで、当時、入社エントリーブログを読んだ方もいらっしゃるかもしれませんが、改めてお話を聞かせてください。

柴田:そうですね、私の場合はですね、Rubyを開発するのに必要なCIであるとか、インフラであるとか、周辺ライブラリのメンテナンスをすることをメインの担当領域としているのですけども、今まではですね、ぜんぜん前職ではRubyの開発はメインの仕事ではないので、いろいろとやる領域が広まれば広まるほどなかなか時間を作れなくって、Rubyのことをやるということが難しくなってきて、やりたいこととかやらなくちゃいけないことはいっぱいあるんですけど、時間をなかなか捻出できない、夜はもう疲れたので無理、みたいな形が続いてきて、そういった中で、たまたま話を聞いてみたアンドパッドのVPoEの下司さんにですね、最初の方はエンジニアリングマネージャーを採用したいといった形で僕に話をしてきたところに、僕がオープンソースの開発者として雇ってくれませんか?と逆にアピールをして「できるかもしれません」と下司さんにいろいろと動いていただいて、今に至って、今はRubyの開発をメインとしてやっています。で、遠藤さんも仰られた通り、会社の中でRubyを大規模に使って、プロダクトを作っているので、Rubyでこういうことに困っているだとか、こういう部分をよくしたいと思っている、みたいな部分ももちろんあるんですけど、最近はRubyの開発者の中でもフルタイムでRubyの開発を行う方が海外の会社も含めて増えてきていて、そういった中でこういう開発はどうかとか、こういうコードはどうかみたいな、そういう話であるとか、後は技術的な課題も含めて課題を議論したりだとか、そういったもので非常に毎日が刺激的なもので前職よりも1日の仕事をして疲れたというのが、11月からの現在の僕の状態です。

Rubyコミッターになるためのステップとは?

櫻井:このPodcastを聞いているリスナーの方々の中にもですね、Rubyコミッターになりたいという方もいらっしゃるかな?と思いますので、コミッターになるにはどうすればいいのか、どんなステップがあるのかを教えていただけたらと思います。

遠藤:はい、基本的にはRubyの重要なバグを修正していただけるとか、すごく重要ではないけれどたくさんのバグを修正していただけてくれるとか、他には大きな改善を提案してくれるとか、そういった貢献をしてくれた人には、そういう活動を続けてくださいとか、その改善をぜひメンテナンスしてくださいという意味でコミット権をお渡しして、その後勝手にやっていただくというのがよくあるパターンだと思います。

櫻井:ありがとうございます。他のオープンソースプロジェクトと同じようにコアコミッターでなくとも、Rubyに貢献することは誰でもできるということですね。貢献度の高い人はコアコミッターになれるという認識で大丈夫そうですかね?

柴田:そうですね。

櫻井:ありがとうございます。どうやって貢献していけばいいのか? は、また後半のRuby開発の裏話と今後の取り組みの方で深堀っていきたいと思います。Rubyコミッターは普段どんなことをしているんだろう、と気になっている方も多いのかな? と思います。アンドパッドのアドベントカレンダーで柴田さんがメールサーバーの移設の話を書かれていたと思いますが、そういったこともやられているというのは正直なところ驚きでした。

柴田:そうなんですよね、会社でプロダクトやサービスを開発する場合には、最近ですとSREというポジションの方がいたりだとか、社内のIT部門であるとかそういう専任で横断的な活動をする方がいらしゃって、そういった方達がプロダクトやサービスを作る人たちを支えるみたいな活動であるとか動きをしているものだと思うんですけど、Rubyの場合はですね、Ruby開発会社みたいなものがあるわけではなくて、言語としてのRubyを開発したいという人たちが10人、20人いますといった状態なんですね、なのでGitHubの設定だったりとか、GitHubのCIを誰がメンテナンスするのかだとか、後はもちろんお金がかかるものに関しては誰が請求書を切って、お金を払うのか? みたいな部分とか、そういった部分が宙に浮いちゃうわけですね。なので、私柴田とNaClという会社にいらっしゃる前田さんという方の二人が主にメインの担当としてRubyの開発の社内IT担当みたいな形でいろいろ動いているような動きになっています。

櫻井:遠藤さんは普段、どんなことをやられているのでしょうか?

遠藤:はい、日常的にはですね、Rubyに送られてきたバグ報告とか機能提案だとか脆弱性の報告なんかも来るんですけど、そういうのを読んで、トリアージしたり、簡単であれば修正したり、というのが日々やっていることになります。あと、RubyのCIっていろんな環境でテストが走っているんですけど、それが変更によって落ちたりし始めるんですよね。そういったことが起きたら直す、ということもやっています。と、日常的な話としては、Rubyは月に一回開発者会議というのを行って、送られてきているバグ報告や機能提案について議論するということをやっているんですけど、その時のアジェンダを作成したり、最終的に書かれた議事録を公開したりだとか運営作業も行っています。より長期的な仕事としては最近はRubyに大きな改善を計画してくれる人たちと協力したり提案してくれる人を支援したりすることも結構増えてきています。Ruby3に入ったRubyの基盤となる型記述言語RBSというのがあり、Steepという型チェッカーを作っていたんですけど、それに対してはいろいろ口を出させていただいてRubyの本体に連動させるようにいろいろとアレンジさせていただいていましたし、去年はWebAssemblyに対応させるという結構大きな話があって、それをほぼ一人でやってくれたkateinoigakukunといろいろ話したり、支援させていただくこともやっていました。最近だとですね、ちょうど9月くらいからクックパッドにインターンに来てくれていたMakeNowJustっていう人がRubyのReDoS脆弱性と呼ばれる一種の脆弱性のリスクを大きく下げる改善というのをしてもらってそれも無事Rubyにmergeされたので、その成果でRubyのコミッターになってもらうということもあったりしました。今後は個人的に注目しているのはShopifyという会社の人たちがRubyのパーサーを大きく改善するという計画を立てているというレポートを注入してくれているので、それもいい感じにアレンジさせてもらったり、期待しているところになります。

櫻井:ありがとうございます。ちなみに、Rubyコミッターの方は何人くらいいるんでしょうか?

遠藤:前数えた時はおおよそ100人ちょっとだったと思います。ただ昔コミッターになったけれども、今はほとんど活動していないという人も多いので、この一年くらいでアクティブに活動している人というと15人くらいから20人ちょっとくらいかな?と思います。

櫻井:なるほど。そのアクティブな方々の担当みたいなものってあったりするんですか?

遠藤:漠然とあったりなかったりする感じですね。macOSに関するバグだったら、この人に一旦話を振るだとか、Rubyのこの機能に、たとえばカバレッジだったら、僕に振るだとか比較的はっきりしているところもあったりしますけど、誰もあまり興味がないところはみんなが見たりしたりしています。

櫻井:漠然とというところですね、OSS開発はチーム開発と比べて、どう違うんでしょう?

柴田:そうですね、まずRubyに関する話をするので、そのオープンソースソフトウェアが全部こうだという話ではないというのは事前にお伝えしておきますけども、Rubyの場合はですね、開発計画みたいなものはないんですよね。プロダクトやサービスの場合だと、いつ頃までにこういうものを作って、どういうユーザー向けにこういうものを出します、というまず開発計画があって、それに対して、じゃあ、いついつまでに作るにはこうしないといけないよね、という解像度を上げ下げして、ソフトウェアの開発を進めていくというのが、まずチーム開発というか会社でのソフトウェア開発だと思うんですけど、Rubyの場合はですね、毎年1バージョンはリリースするということだけが決まっていて、あとはRubyの開発者であるまつもとゆきひろさんが今後はこういうことをやっていきたいなー、といういわゆるプロダクトマネージャーみたいなすごい大方針的なものがすごくものすごく、フワッとしたものだけあるので、じゃあ、誰がいつまでに何をどう作るのか?みたいなものは誰も決めていないし、決めようとしてもいないという感じですね。とはいえ、そのそれぞれ15人から20人くらいの人が何か自分の好きなものだけをがーと開発していると、じゃあRubyどうなっとるんだ?ってなって、結果として誰にも使われなくなるということは、みんな知っているので、それぞれ自分がやりたいことは持ちつつも、お互いに話したり、作ったパッチだったり、これはこうではないか?みたいなことをディスカッションしたりしながらプログラミング言語Rubyとして違和感がないものをみんなで頑張って作っていこうという形になっていますね。で最近はmameさんも仰られたけど、毎月開発者会議という形で話す時間を設けたり、日本語で行っているんですけど、オフィスアワーという形で毎週ゆるく話す時間を用意したりしていて、この機能のことだよね、いやいやそういうことではない、みたいな部分を擦り合わせたり、その認識のギャップみたいなものを洗い出すということをやっています。でコミッターと呼ばれる人たちはですね、それぞれが一人でわりかしなんでもできる人が多くて、そのインフラ作って、コード書いて、サービスをリリースします、なんならマネージャも別にやります、みたいな人とかばっかりでそれぞれがですね、チーム開発ではないんですけど、チームプレイをしながら、Rubyの開発をしていると。マネージャーはいなくて誰かが時間の管理だとか次に何をするかといった管理はしていないんだけど、コミッター同士でうまく話を合わせ、こういうことかな?っていうニーズを掘り出して、実際に作って、リリースするというような形で開発を進めているのがRubyというオープンソースソフトウェアの開発体制となっています。

櫻井:ありがとうございます。だいぶ具体的なお話も出てきてですね、とても面白い話になってきて、続きが気になる方も多いと思いますが、今回のANDPAD TECH TALKは以上とさせて頂きまして、この続きは次回柴田さんと遠藤さんのスペシャル対談の後編として企業所属のRubyコミッター対談、Ruby開発の裏側と今後の取り組みでお届けしたいと思います。

柴田:そうですね。後半ではもうちょっと技術的、もしくはRubyの課題のような部分に踏み込んだ話ができればな、と思います。

櫻井:どんな踏み込んだお話が聞けるのかワクワクしております。次回はお二人の具体的な活動や裏話を盛り沢山でお届けする予定です。ぜひお聴きいただければと思います。それでは次回、またよろしくお願いいたします。ありがとうございました。

さいごに

前半はここまでです。後半は1月27日(金)ごろにアップをする予定です。 クックパッドではサーバーサイドやOSSに関わりたい仲間を募集しています。ご興味のある方はぜひご連絡ください。

cookpad.careers

エンジニアリングマニフェストを刷新しました: クックパッドの開発者文化をあらわす3つの言葉

CTO の成田(@mirakui)です。 クックパッドはいま、2017年からの10年間を投資フェーズとして位置づけていて、ミッションである「毎日の料理を楽しみにする」を実現するため、長期的に成長していけるための事業づくり、組織づくりに投資をしています。

クックパッドは価値のあるプロダクトをユーザに届け続けることが事業の中心にあり、そのためにはエンジニアの活躍が不可欠です。クックパッドにおけるエンジニアというのは、単なる「実装担当」ではなく、自発的に課題を発見し、一人ひとりの専門性や創意工夫をもって開発をしていくことが求められます。強い個人が集まって、それぞれの能力のうちの高い部分をお互いに引き立て合って、一人ひとりでは解決できないような大きな課題に取り組めるようになる。私は CTO として、クックパッドのエンジニア組織をそのように強化していきたいと考えてきました。

エンジニアリングにおいては、エンジニアの人数を増やしていくことが組織の生産性をあげるかというと、私はそうではありません。エンジニア10人の組織と100人の組織とでは、プロダクトの品質という意味では差が出てくるかとは思いますが、突破できる事業課題の大きさにはあまり人数は関係ないのではないかと考えています。それよりも一人ひとりが重要な課題に取り組めているかどうかが重要です。平均的な100人よりは精鋭の10人の組織でありたいですし、少数精鋭の10人が集まった100人の組織でありたいと考えています。そういったエンジニア組織を目指すため、チームワークによる生産性を目指すよりも先に、個々人の能力、リーダーシップを高めることを重要視しています。

私は今年、一人ひとりが自律的で卓越したエンジニアの集団を目指すために、クックパッドのエンジニアとしてのあるべき考え方・文化を言語化した「エンジニアリングマニフェスト」を制定しました。実はマニフェスト自体は以前から存在していたのですが、これからの成長を見据えて、新しい言葉で置き換えることにしました。それぞれ日本語と英語の表記を用意し、これを日本だけでなく海外のエンジニア組織も含めて統一しています。

クックパッドのエンジニアリングマニフェストは、次の3項目からなります。

  1. 境界を越える (Beyond boundaries): 私たちは一人ひとりが高いリーダーシップを持った個人になるために、自分の能力の限界や、責任範囲に対する思い込みを乗り越えて成長していくエンジニアを目指します。
  2. 技術を楽しむことに責任を持つ (Responsible for enjoying technology): 私たちは一人ひとりが技術を楽しむ集団であることを目指します。困難な状況であっても、常に技術的な挑戦の機会を諦めません。一人ひとりに技術を楽しんでいる自分を目指す責任があります。
  3. 作ったもので語る (Speak with what you make): 私たちは動くものをすばやく生み出せる存在として価値を発揮します。また、作ったものを実際に触れることで得られる気づきを尊重します。

以下、それぞれについて解説します。

1. 境界を越える (Beyond boundaries)

「境界を越える」は最もクックパッドのエンジニアらしさを表す言葉だと考えています。これは、知らず知らずのうちに自ら作り出している「境界」を見つけ出し、それを乗り越えていこう、ということを意味しています。境界は、例えば自分の能力の限界や、所属している部署の役割、自分の役職に与えられている裁量だったりします。

たとえばエンジニアが一人しかいないスタートアップであれば、その人はコーディングだけでなくさまざまな領域をカバーしなければなりません。しかし組織が大きくなると役割は細分化され、自分の限られた領域の仕事をしていれば済むようになります。その場合たとえ組織の人数が増えても、ただ役割を細分化していくのでは、本当の意味で課題に立ち向かう人数は増えていないということになりかねません。 自分の役割にとらわれずに、スタートアップの一人エンジニアのような責任感や柔軟さ、視座をもって立ち回れることは、クックパッドのエンジニアとしての大きな強みになると考えています。

2. 技術を楽しむことに責任を持つ (Responsible for enjoying technology)

二つ目として、私のエンジニアとしてのスタンスを最も表した言葉を選びました。

私たちの会社のミッションは「毎日の料理を楽しみにする」であり、「楽しみ」というものが生み出すエネルギーの大きさを信じています。世の中の技術は常に新しくなっていきます。新しい技術が登場してはコモディティ化し、エンジニアに求められる知識も日々変化しています。エンジニアの仕事というのは、そのような時代の流れのなかで常に技術の引き出しを新しくしながら磨いていく必要があります。どんなことでも、頼まれた仕事だから仕方なくやってる人は、楽しくて仕方が無いからやっている人には勝てません。

技術の学習についても同じで、これはどうやって動いてるんだろう、とか、この仕組みをもっと知りたい、とか。こんなことを出来る技術はあるのかな、とか。クックパッドのエンジニアには、こういった好奇心、技術的興味といったものを膨らませて、技術を楽しんで欲しい。

私はさらにこれを「楽しむことに責任を持つ」という強い言葉で結びました。これは、楽しんでいないのだとしたら、楽しんでる自分に持っていくことをそれぞれの責任でやってほしいという願いが込められています。誰かにそうしてもらうのではなく。

私はクックパッドで十年以上勤めてきたなかで、多くの卓越したエンジニアの方々と働く機会に恵まれました。卓越したエンジニアは、特にこの「技術を楽しむ」ということに長けています。忙しい業務のなかでも技術的なチャレンジをうまく入れ込んできます。日々の開発や技術の研鑽を「仕事だからやっている」から「楽しいからやっている」になれたとき、エンジニアとして次のレベルに成長できると考えています。

3. 作ったもので語る (Speak with what you make)

プロダクト開発では、初手から完成品を作るのではなく、まずは小さく価値を表現できる MVP を開発して検証する、というのはすでに世の中の当たり前になってきています。動くものを作り出せるというのは、エンジニアの強みどころか、存在理由でさえあると私は考えています。だからこそ、エンジニアがアイデアを表現する手段は、言葉よりもコードであってほしい。「こういうものがあったら良いよね」ではなく、「こういうものを作ってみたんだけどどうかな」という会話であるべきです。

私はクックパッドで働いてきて、サービス開発のプロセスは探索的であり、10個作って10個捨てることの繰り返しであると学びました。本当に優れたプロダクトを目指しているとき、比類無き一手を生み出せないくらいなら、一手も進めない方がマシだからです。打席に立つ回数や質を上げていくには、エンジニア一人ひとりが「作ったもので語る」ことが当たり前な文化があれば、より確度の高い一手に近づくことができるはずで、それによって未来を変えていけると私は信じています。

おわりに

クックパッドのエンジニア組織は、一人ひとりが卓越したエンジニアとなり、個人の能力の掛け合わせによって大きな事業課題を解決していくことを目指します。そのために重要と考える3つの要素を「エンジニアリングマニフェスト」として言語化し、これからのクックパッドのエンジニア文化としていきます。

Next.js アプリケーションの共通コンポーネント開発

こんにちは。レシピサービス開発部のkaorun343です。クックパッドではスマートフォン向けページにおける開発者体験向上のために、レシピサービスのフロントエンドを Next.js と GraphQL のシステムに置き換えている話にて紹介したとおり、Next.jsとGraphQLを用いたモダンな環境へと移行を進めています。例えばモバイル端末からのアクセスでURLがトップページの / であれば Rails、レシピ詳細ページの /recipe/:id であれば Next.js アプリにルーティングされるようになっています。現在ではレシピ詳細ページだけではなく検索結果ページやつくれぽ詳細ページ、MYフォルダページなどもNext.jsアプリケーションに置き換わっています。今回はその移行により生じた課題と取り組み方、それから併せて実施したモノレポ環境整備について紹介します。

共通コンポーネントの導入背景

cookpad.com では上述の通りページによってホストするアプリケーションが異なる一方で、ヘッダーやサイドメニュー、フッターといった全てのページに共通して表示されているコンポーネントがあります。このような、Next.js と Rails アプリの両方から利用される UI コンポーネントのことをこの記事では "共通コンポーネント" と呼ぶこととします。

クックパッドではハロウィンやクリスマスにあわせてヘッダーやフッターのデザインを変更する施策を定期的におこなっています。したがって共通コンポーネントに変更を加えたいとき、2つのアプリケーションのその両方の実装を編集しなければなりません。さらにこの2つのアプリケーションは使用している言語が異なるため、実装担当者にとってはさらなるコストになっています。 そこで実装を一度で終えられる仕組みを導入しました。

トップページとレシピ詳細ページのサイドメニュー(共通コンポーネントの例)

実装方法

結論としては、共通コンポーネントを以下の方針で実装することにしました。

  • Reactコンポーネントとして実装し、Next.jsでは通常のReactコンポーネントとして利用する。
  • 少ない労力でRails上で表示するために、上記のReactコンポーネントをウェブコンポーネントでラップする。

developer.mozilla.org

Reactによる共通コンポーネント作成

共通コンポーネントはReactで作ることにしました。この方針には2つ理由があります。

1つめは、Next.js上では今まで通り通常のReactコンポーネントとして使うためです。Vue.jsやSvelteなど他のパッケージを使わないため余計なコードが含まれなくなり、バンドルサイズが増加したり表示が遅くなったりする心配がありません。加えて、Next.js上で容易にSSRすることができます。

2つめは、Next.js アプリに実装済みのコンポーネントを共通コンポーネントとして再実装する際にその実装をほぼそのまま使えるためです。実際、Next.js用に実装したコードを少し修正するだけで済みました。

Storybookによる開発環境

共通コンポーネントの開発に際してはStorybookを導入しました。クックパッドではプルリクエストごとにステージング環境を作れる基盤があるので、このStorybookもプルリクエストで確認できるようにしました。これで変更内容をレビュアーが容易に確認できます。

また、表示の確認だけではなくテストにも使っています。Storybookの中で事前にpropsを渡したりcontextのproviderで包んだりしているので、テストの実装を綺麗にできます。

import { MyReactComponent } from './MyReactComponent'
import { MyProvider } from '~/contexts/MyContext'

export default {
  component: MyReactComponent,
  decorators: [
    (Story) => (
      <MyProvider>
        <Story />
      </MyProvider>
    )
  ],
}

export const Default = {}

export const Prop1 = {
  args: {
    prop1: 'prop-1',
  },
}
import { composeStory } from '@storybook/testing-react'
import { axe, toHaveNoViolations } from 'jest-axe'
import * as stories from './MyReactComponent.stories'

expect.extend(toHaveNoViolations)

const storyNames = ['Default', 'Prop1']

describe('MyReactComponent', () => {
  describe.each(storyNames)('%s', (storyName) => {
    const Story = composeStory(stories[storyName], stories.default)

    it('スナップショットテスト', () => {
      const { container } = render(<Story />)
      expect(container.firstChild).toMatchSnapshot()
    })

    it('アクセシビリティチェック', () => {
      const { container } = render(<Story />)
      expect(await axe(container)).toHaveNoViolations()
    })
  })

  describe('Prop1', () => {
    const Story = composeStory(stories.Prop1, stories.default)

    // 個別にテストしたいことを書く
  })
})

こちらの記事を参考にしました。 zenn.dev

リソース取得のためのAPIサーバー

Next.js版ではAPIサーバーとの通信に専用のGraphQLサーバーを使っています。共通コンポーネントの実装にあたっては、専用のGraphQLサーバーを用意するとサーバーの実装やCI/CD環境を構築する手間がかかることや、Next.jsのGraphQLサーバーと機能が重複していることから、Next.jsと同じGraphQLサーバーを利用することにしました。

ウェブコンポーネント作成

Rails アプリに直接 React コンポーネントをマウントしようとすると Rails アプリ側にたくさん JS のコードを書く必要があってつらいです。加えてRails側にReactコンポーネントを変換するための環境を構築しなければなりません。また、共通コンポーネントが内包するリセット用 CSS などをRailsアプリに影響させたくないといった課題がありました。 そこでRailsアプリケーションに導入する際は、Reactコンポーネントをウェブコンポーネントで包むことにしました。

ウェブコンポーネントは、再利用可能なカスタム要素を作成し、ウェブアプリの中で利用するための、一連のテクノロジーです。コードの他の部分から独立した、カプセル化された機能を使って実現します。 ウェブコンポーネント | MDN より

ウェブコンポーネントは複数の技術要素から成り立っています。カスタムエレメントが前者を、Shadow DOM が後者を解決してくれます。

カスタムエレメント

Reactコンポーネントをマウントする場合、自力でマウント対象の要素を探し、マウントしなければなりません。一方でカスタム要素にすることでそれを利用する側ではカスタム要素のタグを書くだけで済みます。

Shadow DOM

ReactコンポーネントをShadow DOMの子要素にマウントすることにしました。 共通コンポーネントはNext.jsアプリケーションと同じリセットCSSをベースにスタイリングしています。もしShadow DOMがなければRailsアプリケーションも同じリセットCSSを導入するか、共通コンポーネントのスタイリングそれぞれにリセットCSSを含めなければいけません。一方で Shadow DOMを使えばリセットCSSをShadow DOMの一番最初に追加するだけで済みます。

実装例

ウェブコンポーネント版の共通コンポーネントパッケージでは、Reactコンポーネントを表示するカスタムエレメントを提供します。

export class MyCustomElement extends HTMLElement {
  connectedCallback() {
    const mountPoint = document.createElement('div')
    // シャドウルートをカスタムエレメントに追加
    this.attatchShadow({ mode: 'closed' }).appendChild(mountPoint)
    // Reactコンポーネントのルートオブジェクトを作成
    const root = createRoot(mountPoint)
    const prop1 = this.getAttribute('prop1')

    // ウェブコンポーネント用のEmotionの設定
    const emotionCache = createCache({
      key: 'my-custom-element',
      container: mountPoint,
      prepend: true,
      speedy: true,
    })

    // Reactコンポーネントのレンダリング
    root.render(
      <CacheProvider value={emotionCache}>
        <GlobalStyles />
        <MyReactComponent prop1={prop1} />
      </CacheProvider>
    )
  }
}

共通コンポーネント(ウェブコンポーネント)を利用する側では、まずカスタムエレメントを定義します。そしてHTMLにそのカスタムエレメントのタグ名を記述します。

import { MyCustomElement } from '@cookpad/shared-components'

customElements.define('my-custom-element', MyCustomElement)
<my-custom-element prop1="prop-1"></my-custom-element>

モノレポ環境整備

モノレポ環境整備を整備する前の状況

共通コンポーネントはNext.jsとGraphQLサーバーのリポジトリに存在します。開発当初はモノレポ環境にしていなかったため、それぞれのパッケージが独立していました。ゆえに共通コンポーネントをNext.jsで使うためには一度npmパッケージとして公開するか、もしくは yarn link 機能を使わなければならず手間がかかっていました。加えてCIジョブもそれぞれのパッケージごとに作っていたので、今後新たにパッケージを増やすとそのたびにCIジョブも作らなければいけませんでした。そこで共通コンポーネントの実装と並行して、モノレポ環境を整備していきました。

Yarn Workspacesの導入

ワークスペース機能を使って共通コンポーネントを直接参照できるようにしました。Next.jsに共通コンポーネントパッケージをインストールするときはYarn workspacesを利用し、別リポジトリにあるRailsにインストールするときは社内のプライベートnpmレジストリに公開してから使っています。

yarnpkg.com

Turborepoの導入

Turborepoはモノレポ管理ツールと呼ばれるものです。設定を比較的簡単に書けるのが特徴です。また他のモノレポでは複数の実行環境に対応しているものもありますが、TurborepoはNode.js用の管理ツールです。対象のリポジトリはJavaScript(Node.js)だけからなるモノレポなので、Turborepoを採用することにしました。 Turborepoを導入することで、CIのジョブを1つにまとめることができました。また、変更があったパッケージとそれに依存するパッケージのみ必要なタスクを実行してくれるので、ジョブの実行時間が短くなりました。例えば共通コンポーネントパッケージに変更があった場合は、Next.jsのパッケージもテストなどを実行してくれる一方でGraphQLサーバーについてはタスクの実行をスキップしてくれます。

turbo.build

さいごに

今回はレシピサービスの共通コンポーネント導入とモノレポ環境整備について紹介しました。クックパッドではこれからもモダンな技術によるレシピサービスの刷新を引き続き進めていきます。この取り組みを一緒に進めてくれる仲間を募集していますので、興味のある方はぜひご連絡ください。

cookpad.careers