2020/06/14

最近のWindowsで開発するときこんな感じでやってます

仕事で「新卒研修のブログを書く」というタスクをタスク山の片隅に積んで早1ヶ月が経ちます。ということでそろそろ会社のブログを書きたいところではあるのですが、最近そもそもまともにブログというものを書いてないのでリハビリがてら自分のブログを書くか~~~ みたいな感じでこれを書き始めました。

さて、以前は普通に仕事用のマシンとしてBYODなMacBook Proを使っていたのですが、数年前から普通に会社支給で強いMacBook Proが支給されるようになったということで2年前からは仕事は会社支給Macにして自分用のPCは普通にWindowsノートを使うようになっています。なんでMacじゃなくてWindows買ったかというと、単純にMacBook Proは物理的に重い、MacBook Airだと当時はRetinaになってなかった、MacBookはTDP 5WくらいのYプロセッサ系だったので非力、ということで全部選択肢から消しました。

そうなるとWindowsのノートPCから選ぶことになるので、普通に重さとスペックとバッテリのバランスを比較検討してこれかなぁみたいな感じで選んだという感じです。条件としては、1kg切るくらいで! メモリ16GB以上乗っけられて! 英語キーボードで! 12時間以上バッテリ持つ! みたいな無い物ねだりのやつなのですが、なんとか条件合うものを見つけて買いました(本当はディスプレイは16:9ではなく16:10か3:2で! というのもあったんだけどそこまでは叶わなかった)。英語キーボードがネックなので、Amazon.comからの直輸入でしたけどね……。

開発環境

Windowsで開発するといっても、基本的には作るものがWeb系のバックエンド(GoとかPerlとか)だったりフロントエンド(VueとかReactとか)だったりするので、Linuxが必要ということでLinuxなVM上で開発しています。今やブラウザもエディタもSlackもTwitterも大体WebKit系のランタイムで動いてしまうので、もはやOSのこだわりみたいなのが消えつつあるといったほうが正しいのかなあ。WindowsやMacはただのWindow Systemとしてしかみていないんですよね。そうじゃない世界があるのももちろん知っているので、そういう意味では恵まれているともいえます。

LinuxのVMは、ここ数年ずっといろんなところを試してみたりしていて、自宅鯖のESXiにおいてみたり(ESXiの面倒みるのダルすぎて昨年自宅鯖のESXiは廃止しました、いまから自宅に鯖立てるならHyper-V Serverだろうなぁ)、開発マシンのノートPCにHyper-VなりVirtualBoxなりを入れてみたり、AWSのEC2 Spot InstanceやGCPのPreemptible InstanceをHibernateしながら運用してみたり、いろいろやりました。

結局の所可用性とコストのバランスをどこで取るかという話で、可用性は IaaS > 自宅鯖 > ノートPCなんだけど、コストはIasSが一番高いかなぁ(これ厳密に計算すると自宅鯖のほうが高い気もするけど、あれは浪漫なのでよしとする)と悩みつつ、ノートPCの上においとくとクラッシュとかでVMが消えたときが辛すぎるので、結局今はAWSのLightsailにおいとく、で落ち着いています。

この辺の試行錯誤と葛藤の歴史はそれを書くだけで記事が一本できてしまうのでまぁおいておきましょう……。EC2やGCEをHibernationしながらコストケチったりとかは確かにコスト的に良かったのですが、使いたい時に起動するのが不便でした(終了はsshセッションが0になったら自動でhibernateするスクリプトを仕込んだ)。

最終的に「結局SpotとかPreemptibleとかでコンピューティングコストをケチっていくとEBS/Persistent Diskの料金が支配的になってくるので使う時に起動しないといけない不便さよりも24時間ずっと起動してる方がいいな」となったのでスペック固定してオールインワンなVPSとしてLightsail使うのがよいなとなった次第。

エディタ

もともと、VimかEmacs選べと言われたらEmacsを選ぶ側の人間で昨年春くらいまではLinux VMにSSHしてEmacsでゴリゴリコード書いてたのですが、昨年春くらいにでたVSCodeのRemote Extensionが便利すぎで、もうリモートのEmacsじゃなくてVSCodeでいいやんとなりました。

今はさすがに電車乗らないですが、ちょいちょい所用で電車の長距離移動が必要でグリーン車とか新幹線でコード書いたりしていた時期がありまして、LTEテザリングだとちょいちょい不満がありました。横須賀線の保土ヶ谷のトンネルでLTEが切れたりとか、そもそもSSH上のターミナルはレイテンシがががとかそういうのもあって結構イラッとする感じです(ただ、保土ヶ谷のトンネルはグリーン車の2F席だとSSHがギリギリ切れないとか、テザリングのレイテンシーはWifi/BTじゃなくてLightningのUSB接続にすれば大丈夫だったりするとか回避法はあります)。

まぁmosh使えばいいじゃんという話ではあるのですが、1セッションで1ポートなのがどうにもIaaSのSecurity Groupとの相性悪いのであまり使う気にならなかったんですよね~。あと単純に仕事でもmosh使ってないというのもあり。

そんなところに現れたのがVSCode Remote Extensionで、VSCode上からSSHでLinuxにつないで直接ファイルを編集できるみたいな魔法のなにかで、編集するエディタバッファはWindows側にあるのでLTEでレイテンシーが厳しいときも編集自体には特に影響が無いのでとてもストレスフリーな感じで編集できます。いやーマジで便利ですね。

まぁなんか低速回線で詰まることがあるとしたら、Goとかを編集してて保存したときにフォーマッタがかかったりするときとかくらいでしょうか。LSPの反応が遅いとかもありますが、まぁ局所的なコードを書いてる分にはそこまで補完頼みのコーディングしないのでそこまで影響はないかな~という感じです。

SSHのターミナル

WindowsからLinux VMにSSHするのはD2D/DW PuTTYというPuTTYのカスタマイズ版ビルドでDirectWriteで描画するやつを永らく愛用しておりました。理由としては、エディタに使ってるフォントがSource Han Code JP(源ノ角ゴシック Code JP)でして、こいつ日本語と英語の文字幅比率が1/2じゃなくて2/3なんですよ。つまりプロポーショナルフォントというわけです。

MacのiTerm2はSource Han Code JPでも普通にそれっぽく使えるので不便してなかったのですが、いざWindowsに帰ってきてみるとそもそも等幅じゃないフォントでまともに動くターミナルというのがほとんどなくて(そりゃそうだ)、たどり着いたのがD2DDW PuTTYだったわけです。後述するフォントレンダリングの話の関係で本当はGDI描画がよかったのですが、GDI PuTTYでプロポーショナルフォントをつかうとレンダリングがすごく遅い(もしかすると後述のMacType併用も関係あるのかも)ということで、D2DDW PuTTYを使っています。

……というのもつい先週くらいまでの話で、Windows TerminalがついにGAリリースになりまして、使ってみたらこれでいいじゃんとなったのでつい最近Windows Terminalに乗り換えてみました。Windows Terminalは一番最初にプレビュー版が出たときは日本語関連が全然満足する水準になくて使うのを見送ったのですが、さすがGA版はちゃんと日本語周りもまともになっていたのでいい感じです。

ということで今Windows Terminalが実用になるか試用中という感じです。なんかよく分からんけどちょいちょい切れることがあって、一応 ServerAliveInterval 設定してるんだけどな……となっています。もうちょっと調べてみるか……。

ちなみに、私はLinuxのVMから手元のマシンにいろんなポートをLocal Forwardして手元のブラウザで動作チェックとかをやるのですが、たまにiOSとかでも確認しなきゃならないのでsshのconfigに GatewayPorts yes しておりまして、これがWindowns Terminal(とWindows標準のOpenSSH)に乗り換えたときにうまく動かなかったのですが、Windows Firewallでssh.exeのファイヤーウォール許可をしたらちゃんと別の端末からもアクセス出来るようになりました。ただし、さすがにパブリックネットワークだと危ないのでその辺はちゃんと設定しましょう……。

Windowsのフォントレンダリングがアレな話

さて、こんな感じでWindowsでもLinux VMにVSCodeで繋いで動作確認系はポートフォワードしてWindows上のブラウザで見てるので問題無い(というかMacでも同じスタイルで開発できるのでこれに慣れるとOSをあまり気にしなくなる)……と言いたいところなのですが、WindowsのフォントレンダリングがMacに比べてどうにもよろしくないという問題があります。

とはいえ、Windows 10になってから何度かHiDPI時のレンダリングは改善されたりして3~4年前よりはよっぽど良くなったのですが、それでもMacとはレンダリング特性が異なるし、そもそもレンダラもソフトウェアによってGDIだったりDirectWriteだったりして気にしないといけないことが多いので、その辺をどうにかするためにMacTypeを入れています(githubもアリ)。

こいつは主に2種の効能があって、

  • GDIで描画するソフトウェアのレンダリングをフックしてFreeTypeでレンダリングしたフォント描画にしてくれる
  • DirectWriteで描画するソフトウェアのレンダリングオプションをオーバーライドできる(レンダラはFreeTypeにはならない)

という感じになっています。旧来から存在するソフトウェアはGDIで描画しますが、最近のソフトウェアはDirectWriteで描画しています。とくにStoreアプリからダウンロードできるUWPは基本的にDirectWriteになっていますし、WebKitベースのブラウザやその他のソフトウェアは大体DirectWriteです。

で、ひとつ問題がありまして、MacTypeが効かない奴がいます。Chromeブラウザです。Chromeで効く効かないは色々歴史があって今だと --disable-features=RendererCodeIntegrity をつけて起動すると一応MacTypeが効くみたいな話のようですが、なんかいたちごっこ感があってアレなのと、FreeTypeベースのレンダラのほうがやっぱ好きだなということで私はChromiumベースでGDIレンダラが利用できるCent Browserを使うみたいな感じで回避しています。まぁでも久々にWindowsでChrome起動してRendererCodeIntegrityをオフにしたらちょっと細めだけど以前のように全然ダメというわけではない感じだったので、MacTypeとChromeの組み合わせでもいいかもしれないですね。

とまぁそんな感じで今回は自分が最近のWindowsでWeb系の開発するときの事情の話でした。自分はWSLは使ってないのですが、Lightsailはネットワーク代も入ってるから固定料金で気兼ねなく使えるので、VSCodeとの組み合わせで快適に手元にWSLあるのとさほど変わらないかなぁという感じで使えてます。

うされもん @acidlemonについて

|'-')/ acidlemonです。鎌倉市在住で、鎌倉で働く普通のITエンジニアです。

30年弱住んだ北海道を離れ、鎌倉でまったりぽわぽわしています。

外部サイト情報

  • twitter
  • github
  • facebook
  • instagram
  • work on kayac