ゆるふわ技術日誌

エンジニア見習いの悪戦苦闘日記

モノレポ on husky戦略

2020年は毎月2本技術的なアウトプットするぞ、と言いつつ1月から打ち破ってしまったので罪滅ぼしに最近業務でやったことについて備忘録的に書いておこうと思います。

モノレポを採用しているプロダクトにhuskyを導入したという話です。

※前置きが長いので、いらない人は本題のところまで読み飛ばしてくださいませ。


モノレポ

モノリシックレポジトリの略。

詳細な定義は知らないので、実際には違うかもしれないが(ていうか多分違う。)この記事におけるモノレポは「一つのGitリポジトリを用いて、一つのプロダクトのフロントエンド/バックエンド等のコードを管理するGit戦略」ということにして進めたいと思います。

husky

github.com

こいつのこと。これは一言で言うと、JS開発者間でGitフックの設定を揃えるための便利ツールとでも言えば良いのだろうか。

package.jsonに依存関係として定義しておくと、npm installnpm ciを使って依存ライブラリのダウンロードをした際に、Gitフックを設定してくれるという感じの挙動をします。あとはpackage.jsonや設定ファイルにgit commit時やgit push時にやらせたいことを列挙しておけば、自動的に設定に宣言したことを実行してくれます。

まぁJSを使って何かしらの開発をしていれば、npm installは間違いなくやるだろうし、そのタイミングを使ってGitフックが設定されるので実質的にGitフックの設定を強制することができるという素敵OSSってわけです。

これを使ってcommit前にPrettierやなんちゃらLintとかをかけておけば、誤ってコードフォーマットを忘れたコードがGitリポジトリ上に上がって、コードレビューで「フォーマッタかけてください」みたいな不毛なやりとりを産むこともないので素晴らしいのです。

ちなみに

ちなみに、huskyはGitフックを設定してくれるだけなので、lint-stagedというツールと組み合わせることで、ステージに上がっているファイルを対象に必要となるフォーマッタやLintをかけるということができます。どのファイルに対してどのフォーマッタを適用するかみたいなのを指定できるので超良い。超おすすめです。

んで本題。

基本的にここまでで書いたことをやりたかったら、一番早いのはlint-stagedのREAMDEに書いてある

$ mrm lint-staged

というのをプロジェクト直下で叩いてやるとインストールされているフォーマッタ等をみて良い感じにしてくれるので誰でもできると思います。

ところが、僕がメンバーとして関わっているプロダクトのリポジトリはモノレポ構成を取っており、1つのGitレポジトリの下にWebフロントエンド(ElmとTypeSript)やらスマートフォンアプリ(React Native製なのでTypeScript)、ほかにもサーバーサイドのコード等も入っているというような状況です。

このような状況において、huskyを導入するにはちょっと工夫をする必要があります。というのもGitフックはGitレポジトリ単位でしか設定できないので、たとえばWebフロントエンドのディレクトリ配下でhuskyを設定してしまうとスマートフォンアプリのディレクトリではhuskyを使うことができません。(できません、というか上書きで設定されるので最後にインストールしたものだけが生き残ってしまう)

huskyのREADMEにはlernaを使うように書いています。lernaはモノレポでの開発を支援するツールで、複数のnpm packageをスマートに管理してくれるものらしいです。(雑な理解)

ユースケースを見た所、npm packageの開発をモノレポを使って行う際に便利な機能を提供しているツールのようで、今回のようなケースには向かないと判断し別の方法を使ってなんとかhuskyを使う方法を模索しました。

そこで今回はGitリポジトリ直下にhusky用のディレクトリを作成し、そこで一括管理するという方法をとりました。

husky-example/
├── _husky
├── server
├── sp-client
└── web-client

こんな感じ。

_huskyディレクトリのしたのpackage.jsonのdevDependenciesにhuskyを追加し、設定を書きます。

今回Linterやformatterのツール自体はそれぞれのコードのあるディレクトリのpackage.jsonに書きたかったため、こんな感じで相対パスで指定するようにしました。

{
  "name": "husky",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "husky": "^4.2.1",
    "lint-staged": "^10.0.6"
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "../sp-client/app/**/*.{ts,tsx}": "../sp-client/node_modules/.bin/tslint -p ../sp-client --fix"
  }
}

少々冗長な感じは否めないですが、まぁ仕方なし。。。

そしてもう一点やっておくとよいかもしれないのが、Lint対象のディレクトリにあるpackage.jsonpostinstallに_huskyディレクトリ以下でnpm ciを走らせるスクリプトを書くことです。

具体的にはこんな感じ。

{
  "name": "sp-client",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "postinstall": "cd ../_husky && npm ci"
  },
以下省略

このようにしておくことで、sp-client以下でnpm inpm ciをやったとき、一緒に_huskyディレクトリ以下でnpm ciが実行され、Gitフックが設定されます。

ここまで設定しておけば、普段の開発では意識することなくcommit時のlintが走ります。

おわりに

ということを先日仕込んでみました。まだマージされてから日が浅いので何か問題が起こったら、考え直そうと思っていますが、今のところは順調に動いています。

ここまでドヤ顔で記事を書きましたが、husky用のディレクトリを切ったらいいのではとか、postinstallを書いたらいいのではとかは全て開発メンバーのアイデアです。。。

それではまた。

2020年の抱負

仕事初めなのでここらで2020年の抱負を公開しておく。

いつも目標立てては、数週間で頭の端っこに追いやられてしまうので今年はこの記事のリンクをSlackbotのリマインダーにセットするぞ。

f:id:uutarou:20200106091754p:plain
追記: やった。

お仕事編

月2回以上の技術アウトプット

Qiita記事とか、このブログへの記事とか、勉強会のLT登壇とかなんでもいいが月に2回以上やる。

月2回やったとしたら年間で24回になるので、まぁまぁなボリュームかなと思う。上を見たらきりがないが、ほぼゼロからのスタートなので結構頑張らないといけない。

後述する登壇に繋げたいという意図。

昇級する

詳しいことはここでは省くが、会社の等級制度で今の等級より1つ上を目指す。

昇級するタイミングが、3月と9月なので9月の昇級を目指して課題を一つずつ潰していく。

アプリ以外の技術領域をやる

今はRNでアプリ開発をしていて、開発アイテムをそこそこ無難にこなす能力はあると思っている。

+αで技術的負債の返済とかは昨年に引き続きやっていくが、今年は少しだけできることの幅を広げていきたい。

具体的にはサーバーサイドとか。とはいえ器用貧乏になっても仕方ないので、上半期は今任されている領域においてプロになることに専念する心算。

100名以上くるイベントへCfPを出す

TSConfとかJSConfとかそういうイベントへCfPを出す。

CfP出すだけならぶっちゃけすぐにでもできるっちゃできるんだが、そうではなく、採用されるだろうという勝算が持てるレベルの内容を出したい。

これも下半期になりそう。いつでも出せるように技術アウトプットを通してネタを貯めておきたい。

プライベート編

冬キャンプをしたいので貯金する

しまりんになりたい

10万から15万くらい貯めてパーっと使いたい。

生活の質を一定に保つ

仕事が忙しかったりすると、ついつい生活の質を落としがちだった。(掃除がおろそかになったり、畳んでいない洗濯物貯めたり、食事が雑になったり)

忙しい時、忙しくない時があるのは仕方ないので、その中で無理なくできる生活リズムみたいなのをちゃんと作っていきたい。

目指すところは、いつ人がきても大丈夫な家。

他人に優しくする

自分に余裕がなくなると、他人に冷たくしたり強く当たってしまったりすることがまあまああった気がする。

他人には常に優しく、一歩大人になりたい。

2019-2020 年末年始をまとめる

さて、冬休みも終わるので、2019年末〜2020年始なにやってたかをまとめようとおもいます。

2019年末① 4回目の納会幹事をやった

物好きというか、なんというか笑

毎回なんだかんだ達成感もあり、次回への課題もあり、たくさんの人から感謝されるのが楽しくて気がついたら入社して4回目の納会幹事をしました。納会は四半期に一度なのでこれで1年やったことになりますねw

2019年末② Flutterをやってるよ

年末だけじゃなく、年始もやってるけど個人的な興味からFlutterを触ってみたりしてました。上記ツイートはFlutterのDevToolsの作り込まれ具合に感動している様子。この辺はちゃんと勉強したらまとめたいと思ってます。

作りたいものがあるというワケではないので、業務で作っているアプリの一部をFlutterで再現してみて、違いを体感したりしたい。

2020年始① 初日の出を見にオフィスへ

カメラが趣味というのもあり、初日の出を見たいと思ったものの、思い立ったのは大晦日

有名スポットに向かったら人混みに飲まれてしまうのがわかりきっていたのでなんとかならないか…と考えた結果。。。。

普段めっちゃ景色いいところにおるやんけ、と気づいたので実家からバイクで職場に向かってみました。

f:id:uutarou:20190514224623j:plain
参考: 普段の景色

あんまりちゃんと見えませんでした。。。

(天気のせいにしているが、これもうあと10分くらい待ってたらちゃんと見えたのかも。。。日の出の時間過ぎて見えなかったから諦めてビル降りてしまった…)

帰りにODOが1111kmになった。

2020年始② ツーリング初め

また後輩に誘ってもらったので大洗〜栃木ツーリングに行ってきました。

f:id:uutarou:20200105002427j:plain
大洗の景色、天気良かった。

で、大洗から栃木のツインリンクもてぎへ。

下調べ全然できてなかったのですが、ツインリンクもてぎってサーキットだけじゃなくて様々なアクティビティができるんですね。

Hondaのミュージアムがあったり。

f:id:uutarou:20200105104953j:plain
モトコンポの実物をみられる日がくるとはw

ずっとやってみたかったカートをやりました。(写真撮り忘れた)

www.twinring.jp

初心者向けの体験カートだったので、最大速度は45km/hなのですが、低いのと狭いのもありスピード感があって楽しかったです。これはハマりそう。

そういえば、栃木にはセイコーマートがあるんですね。道も広いし、実質北海道ツーリング。。。

f:id:uutarou:20200105105342j:plain

おわり

そんなわけで結構充実した年末年始をすごせたかなとおもいます。

ここには書かなかったものの年末年始はたくさん買い物をしました。

カードの請求が怖いですね。。。

近況報告的な記事(趣味要素つよめ)

社会人になって半年経った。という記事から一切更新しておらず、このままだと社会の荒波にもまれて闇落ちしたのかと思われてもしょうがない(?)のでここらで近況報告をしておこうと思います。

久しぶりの記事で申し訳ないですが、技術要素はほぼないです。ゆるふわ技術日誌とは一体。。。。

仕事

相変わらずReact Nativeでアプリを書いています。

入社以来、開発しているアプリにおける技術の面を支えていたスペシャリストの方が別の役職の仕事を優先するためチームから離れることとなり、その後任として技術面の意思決定をする役割をもらったりと、自分としては少しチャレンジな日々を過ごしていると思っています。

任せてくれた上司の期待を裏切らずやっていきたい。そう思いながら必死に悩んだり、コード書いたりいろいろしてます。

言い訳でしかないものの、日々忙しくせっかくやっている技術に関してアウトプットできていないのは痛いところ。

qiita.com

先日会社のアドベントカレンダーに書いたこれくらいかもしれないな。これは2020年の課題。


本来の仕事とは外れるものの、職場のちょっとした課題を技術で解決するのが最近の趣味だったりします。

Slack bot作ったり、GASで作ったAPIとReactで適当に作ったフロントエンドで困りごとを解決したり。やっぱ本質的に自分は人に感謝されることが好きなんだなあと感じておる今日この頃です。

技術

なんだかんだ仕事で使ってる技術以外に手を出して遊んでみたり、とかできてないなあという反省。

最近唯一ハマってちょいちょいやっているのはGCPのいろんなサービスをつまみ食いすること。特にCloud Functionsにはハマっています。あれ、Chromeが使えるのでPuppeteerが使えるんですよね。めちゃ楽しい。

qiita.com

つい最近書いたやつ。

趣味

何を思ったか8月末のある日、二輪免許が欲しくなり教習所を検索すると、なんと家から通える範囲に教習所が…!

これは行くしかないと思い立ち入校。目黒と恵比寿の間という土地柄もあってか、相場よりだいぶ高く普通免許所持の普通二輪免許取得のはずが14万位払いました。

後から聞いた話、通っていた教習所は芸能人御用達らしい。

仕事をしながらなので土日しか通えませんでしたが、無事ぴったり2ヶ月後の10月末日に教習所を卒業。10月31日に二輪免許を取得しました。

免許センターを出たその足で、YSP(ヤマハのディーラー)へ行きお目当てだったSR400というバイクを見に行きました。

ぶっちゃけこれを買うことを目標に免許を取ったところがあるのですが、なんと納車待ちが2ヶ月。。。。しかも思ったより見積もりも高く(車検のある車両の乗り出し価格は結構すごい)ひとまず諦めて、ふわっと頭の片隅にあったもう一台のバイクを見に行くためホンダドリームへ。

こんなバイク。

f:id:uutarou:20191216233904p:plain

思った以上にかっこいいし、思った以上に安く(これは直前にSR400の見積もりを見ていたせい。このバイクは250ccなので税金等がSR400より安い)しかも在庫あり。1週間ちょっとで納車可能とのこと。

うっかり契約と相成りました。

納車はこんな感じで。

f:id:uutarou:20191216234413j:plain
店の一番目立つところに置かれていたマイバイク

f:id:uutarou:20191216234501j:plain
マジの新車

f:id:uutarou:20191216235231j:plain
その後同期に連れられて東京駅に。カメラの充電切れててスマホ撮影になってしまったのが悲しい。

というのが約1ヶ月前の話。

それから1ヶ月の間は、冬でクソ寒い中毎週土日にちょこちょこバイクに乗る生活をしていました。大好きな海ほたるへ行って初高速を体験したり、これまた大好きなアイドルであるでんぱ組.incの幕張で開催されたライブにバイクで行ったり、東雲のバイク用品店に行ったり、ずっと行ってみたかったコメダ珈琲店に行ったり。

住んでるところがバリバリの都会なので全然バイクなんてなくても生きていけるし、電車なら寒くないし、コケて怪我したりする可能性もないけどそれでもエンジンの振動や音を感じながらいろんなところへ自力で行けると言うのはなんとも言えない楽しさがあります。

f:id:uutarou:20191216235856j:plain
これはそのライブで行ったライブのひとまく。初めてスマホによる撮影が解禁されたライブとなりました。しばらくアイドル熱は冷め気味だったのですが、やっぱりライブはいい。というか「でんぱ組の」ライブはいい。(オタク特有の早口)

で納車から1ヶ月が経ち、昨日は初めてツーリングをしました。行先は千葉。

バイク乗りの後輩に誘われて行ってきました。買ったけどサイズが合わなかったらしい冬用グローブを納車祝いにいただいてしまいました。本人は安物と言っていたけどアレがなかったら今頃手が凍傷にでもなっていたと思う。本当に救われた。

ちょっとした(いやけっこう?)ハプニングはありつつも、楽しく千葉をまわることができました。天気も👍

f:id:uutarou:20191217000424j:plain

f:id:uutarou:20191217000438j:plain

1ヶ月経って走った距離はこのツーリングを含めておよそ950kmくらい。だいぶ慣れてきましたが、これからも安全に楽しく乗っていきたいなと思います。


てなわけでほとんどバイクの話しかしてないけど近況報告でした。

学生のころはしょっちゅう病んでたけど、今は平日精一杯仕事して、休日はバイクに乗ってあっちこっちへ。というとてもメリハリのある生活をしているおかげか心もわりかし健康です。

ついついいろんなことに首を突っ込んでしまって、めっちゃ忙しいので体を壊さない程度にがんばっていきます。

社会人になって半年経った。

表題の通りです。

ちょっとだけ振り返っておく。

4月/5月

この辺の話は過去にブログに書いてた。

yurufuwa-tech.hatenablog.com

初めての一人暮らしで浮かれているのがよくわかる記事。

あの頃は、目覚ましかけなくても朝目が覚めてしまって、それで凝った朝食を作っていたなあというのを思い出した。

多分一人暮らしに体が慣れずに目が覚めてしまっていたというのと、業務もそれほど忙しくなかったのがあるのかなあ。

結局朝食は、目玉焼き+トースト+(ときどき)ヨーグルト+コーヒーというので安定しました。ウインナーとか毎朝焼くのはちょっとコストパフォーマンスが悪いのでやめました。

6月

なんだか必死に目の前のタスクだけをこなしていたような。

試しにそのあたりのSlack遡って見てみたら、オリジナルなライブラリ作ってプロダクションコードにマージされて喜んだり、React Nativeのアニメーションが扱えるようになってニヤついたりしてた。

あとは業務でHTML/CSS書いたり。(CSSなんて趣味のレベルでしか書いたことなかったのに、急に書くことになって雑に書いたら「コーディング規約あるよ…」って言われて死んだ)

この頃はとにかく、毎日会社にいけば新しいチャレンジができて、自分のスキルが上がっていくのが身を以て体感できて仕事が楽しいと思っていたような気がする。

yurufuwa-tech.hatenablog.com

yurufuwa-tech.hatenablog.com

TSの言語機能勉強したりとかもしていた。

記事にしていないことを含め、継続的に勉強していたのだが、いつの日かやめてしまった。

というのも、プロダクトのコードを触る程度であれば、基本的な型やinterface/enum/typeあたりがわかっていれば差し支えなく、やっても実戦に活きないと感じたから。

実戦の役に立たなければそれは無駄な知識なのか、と言われれば絶対にNOだと思うしなんでやめてしまったんだろうと、ちょっとこの記事を書きながら後悔している自分がいる。

こういうところから差は広がっていくんだろうな。

7月

驚くほどに何をやっていたか思い出せない。それくらい虚無。

それなりに毎日仕事をして、帰ってご飯食べて寝て翌朝仕事に行くという生活をしていたんだと思う。

Slack遡って調べてみたら、Reactのパフォーマンス計測/チューニング的なことをやっていた。

結局、shouldComponentUpdateを適切に書いたり、PureComponentを使って再レンダリングを抑制するのがもっとも効果がある、という結論が出て、じゃあやるか、と思ってコードに手をつけたら、構造上手をつけられないコンポーネントが大多数で、結局ちょっとだけ手を入れて終了した記憶。。。。

8月

業務は引き続きなにをやってたんだか全く覚えてないくらい無難に黙々とタスクをこなしていた気がする。

プライベートでは勉強会に2本登壇した。なぜか2週連続で。

nihonbashi-js.connpass.com

meguroes.connpass.com

喋りが苦手とかそういうのは練習不足だったのもあるし、致し方ないと思えたが、やっぱりエンジニアとして自分はイマイチなんだなと思った。

こういう場にいくと上には上がいることを思い知って辛くなってしまう。こういうタイミングで、悔しさをバネにして成長できる人は大成するんだろうと思うが、残念ながら僕はそう言うタイプではない。

こんな発言をしていた。発言当初はできると思って発言しているんだと思うが、今は全く自信がない。

9月

流石にまだ記憶にある。

ここまでの振り返りでお気付きの通り、普段の開発アイテムは一通り無難にこなせるようになって、完全に仕事がつまらなくなっていた。

そんなタイミングで降ってきた巨大開発アイテム。ある画面の挙動を変更するために、アプリケーション全体のデータ構造を変更するというものだった。

普段の開発アイテムは、雑に見積もっても大抵それ通りに終わるし、と思っていつも通りろくに既存の実装も確認せず見積もりをしたら大誤算。数日残業しまくっても終わらず、決められたバージョンでのリリースができなかった。

ここにきて初めて挫折した。


というのが半年の振り返り。綺麗にまとめて、じゃあ次の半年もがんばるぞ!って言って終わるつもりが記事を書き始めたらこうなってしまった。

慣れって怖くて最近全然仕事に対して、やりがいとか楽しさを感じなくなってしまった。

おまけに、周りはすごい人だらけ自分は上半期トータルで見ると全然成長した実感がない。

今目の前にある仕事に本気で向き合ったら、その先には何があるんだろうか。

そもそも自分がどうなりたいというのがなさすぎて、何に向かって努力すればいいのかわからない。

あるのは、自分の書いたものが意図通りに動くことは嬉しいし楽しいという気持ちだけ。とはいえそんなの学生インターンでもできる。

じゃあどうすればいいのか、何を目指せばいいのか。全くわからん。

そして、こういう自分の意思がない人は会社も求めてないだろうと思うと、余計に苦しい。


追記

将来とか知らんけど目の前の仕事は全力でやることにした。

点と点はどっかでつながるかもしれないし

スティーブ・ジョブス 伝説の卒業式スピーチ(日本語字幕) - YouTube

この動画、中学生の時に初めて見て、それなりに感銘を受けたつもりだったが、先日思い返してまた観たらその時より染みた。

TypeScriptのReadonly/Partial/Pick/Recordについてまとめる

引き続きTypeScript handbookの英語に苦しみつつ読み進めています。

ちょっとだけ日本語訳にも頼ったりしているけど許してね。


さて、今日はAdvanced TypesのMapped Typeというところに出てくるReadonly/Partial/Pick/Recordという型について。

つい先日やりたいと思っていたことが全部解決したので、自分用メモとしてまとめておきます。

www.typescriptlang.org

Readonly

これは、既存の型の各プロパティを読み取り専用にしたい時に使う型。定義は以下。

type Readonly<T> = {
    readonly [P in keyof T]: T[P];
}

使い方は、

interface SomeType {
    hoge: string;
}

type ReadonlySome = Readonly<SomeType>

これでReadonlySomeは、

{
  readonly hoge: string;
}

と等しくなります。

Partial

これは、既存の型の各プロパティをoptionalにしたい時に使う型。定義は以下。

type Partial<T> = {
    [P in keyof T]?: T[P];
}

使い方はReadonlyと変わらないので省略。ちなみに僕はこれがやりたくて、つい先日interfaceを2個書きました。。。

Pick

これは既存の型から、一部のプロパティを抜き出した型を作るのに使う型です。定義は以下。

type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
}

だいぶ型が複雑になってきますね…。使い方は以下。1つ目の型引数には元となる型を渡して、2つ目の型引数には、キーを渡してやります。

interface SomeType {
    hoge: string;
    fuga: string;
    piyo: string;
}

type PickedType = Pick<SomeType, 'fuga' | 'piyo'>

PickedTypeは、

type PickedType = {
  fuga: string;
  piyo: string;
}

となります。

Record

新しい型を定義するための型。(ちょっとうまく説明できない)

定義は以下。

type Record<K extends keyof any, T> = {
    [P in K]: T;
}

使い方は以下。

type SomeType = Record<'hoge' | 'fuga' | 'piyo', string>

↑のようにするとSomeTypeは、

type SomeType = {
  hoge: string,
  fuga: string,
  piyo: string
}

と等しくなります。

実際はkeyofとかと組み合わせて、動的に型を生成するのに使うのかなと思います。

const some = {
    hoge: 1,
    fuga: 2,
    piyo: 3
};

type SomeType = Record<keyof typeof some, string>

こんな感じ???

所感

Readonly/Partialあたりは割とすぐ使いどころが出てきそうな感じがした。

あと、副作用として、これくらいのレベルの型の定義を読み解けるようになっておくと、他でも役に立つ気がした。

今日も朝から学びになりましたね。

JavaScriptのインスタンスメソッドを変数に代入してはいけない

JSerにとっては当たり前の事なのかもしれないが、うっかりハマってしまったので備忘録として書いておく。


こんな感じのコードがあったして…

class User {
  constructor(name) {
    this.name = name;
  }

  getName() {
    return this.name;
  }
}

const user = new User('mirin');

UserクラスのインスタンスであるuserのgetNameメソッドを呼び出します。

user.getName() // -> mirin

これは間違いなく、インスタンスかする時にコンストラクタで指定した名前が返ってきます。

しかし、以下のような感じで呼び出すと…

const gn = user.getName
gn() // -> Uncaught TypeError: Cannot read property 'name' of undefined

となる。

なぜか。

(ちょっとこの辺は正確さに欠ける表現があるかもしれないので、ご承知おきください)

JavaScriptthisは、呼び出したオブジェクトが入ります。(アロー関数を使った場合の挙動は別になります。要注意)

user.getName()の場合は、userがthisになるため、名前を取り出す事ができますが、メソッド自体を変数に代入して呼び出してしまうと、thisはundefinedとなってしまうため↑に示したエラーが起こります。

ちなみに

実際に僕がやらかしたのは、条件によって呼び出すメソッドを変える必要があるという、割と複雑なロジックを書いていた場面でした。

結局、それくらい複雑なことをやるなら関数分けた方がいいよね、となってやめたのですが、もしインスタンスメソッドを変数に代入したい場合は、

const gn = user.getName.bind(user)
gn() // -> mirin

という感じで、bindを使ってthisを束縛してやればOKです。もしくはメソッドの定義をアロー関数を使う、でもOKです。