<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[reona.dev]]></title><description><![CDATA[reona.dev は Next.js + Cloudflare Pages によって作成されています。Reona Shimada の技術的な学びや日々の出来事を発信する Web サイトです。]]></description><link>https://reona.dev</link><generator>Reona Shimada</generator><lastBuildDate>Mon, 18 Nov 2024 12:04:31 GMT</lastBuildDate><atom:link href="https://reona.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[ja]]></language><item><title><![CDATA[ラクスル株式会社に入社した]]></title><description><![CDATA[今年の9月にこれまで働いていたメドピア株式会社を退職しました。そして翌月の10月にラクスル株式会社に入社しました。]]></description><link>https://reona.dev/posts/20241117131610</link><guid isPermaLink="false">/posts/20241117131610</guid><category><![CDATA[career]]></category><pubDate>Sun, 17 Nov 2024 04:16:10 GMT</pubDate><content:encoded><![CDATA[<link rel="preload" as="image" href="/2024-11-17-14.05.56@2x.png"/><p>今年の9月にこれまで働いていたメドピア株式会社を退職しました。そして翌月の10月にラクスル株式会社に入社しました。</p>
<p>入社して既に1ヶ月半ほど経ちましたが、まだ記憶が新鮮なうちに今回の転職活動について記録しておきます。</p>
<h2 id="なぜ転職したのか"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#なぜ転職したのか"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>なぜ転職したのか</h2>
<p>私が所属していたチームでは、主にプロダクト横断でフロントエンド関連の課題の解決に取り組んでいました。
直近ではデザインシステムの導入や UI ライブラリの構築に携わっていましたが、それらに区切りがつくタイミングだったことがきっかけとしては大きかったです。</p>
<p>また、私は製薬会社の MR としてキャリアをスタートしており、前職でも医療に関するプロダクトを開発していましたが、それとは異なるドメインで社会課題に向き合ってみたい気持ちも強く、今回の転職活動に踏み切りました。</p>
<h2 id="転職活動について"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#転職活動について"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>転職活動について</h2>
<h3 id="期間"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#期間"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>期間</h3>
<p>転職活動の期間としては、約2ヶ月間取り組みました。
具体的なスケジュールは、キャリア棚卸しを本格的に始めたのが6月初旬で、転職活動を完全に終えたのが8月中旬でした。</p>
<h3 id="媒体"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#媒体"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>媒体</h3>
<p>キャリアエージェントは Findy、ビズリーチ、Forkwell の3つを利用しました。また、リファラル採用や直接コーポレートサイトから応募した企業もありました。</p>
<h4 id="forkwell"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#forkwell"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>Forkwell</h4>
<p>当初は Forkwell を利用する予定はなかったのですが、転職活動を始めて少しのタイミングで<a href="https://x.com/Akira_Akagawa" rel="nofollow" target="_blank">赤川さん</a>の登壇を拝見し、すぐに面談の予約を入れました。IT エンジニアのキャリアオタクと呼称されるのが納得できるくらい、公開されている記事も濃い内容のものばかりでとても面白いです。</p>
<ul>
<li><a href="https://pr.forkwell.com/career_navi/six_patterns_of_tech_leads/" rel="nofollow" target="_blank">テックリードはキャリアの分岐点。取材でわかった6系統の役割と市場価値のリアル</a></li>
<li><a href="https://pr.forkwell.com/data_insights/annual-income-distribution-of-it-developers/" rel="nofollow" target="_blank">あなたは上位何％？ITエンジニアの年収分布まとめ【データベース完全公開】</a></li>
<li><a href="https://pr.forkwell.com/blog/has-the-engineering-bubble-about-to-burst/" rel="nofollow" target="_blank">本当にエンジニアバブルは崩壊したのか？</a></li>
</ul>
<p>最終的に最も頼らせて頂いたのが Forkwell で、キャリアの壁打ちや職務経歴書の添削、選考の進捗管理などもご協力いただき、非常に心強かったです。
特に、転職活動は孤独で不安になることが多いのではないかと思いますが、Forkwell ではエンジニア経験のある方に親身になって自分のキャリアについて考えていただき、終始とても心強かったです。</p>
<p>以下は選考の進捗状況を管理していたスプレッドシートで、実際に Forkwell で用意してくださったフォーマットを活用しました。
カジュアル面談を受けて、実際に選考に進んだのは9社でした。</p>
<p><img src="/2024-11-17-14.05.56@2x.png" alt="選考の進捗状況を管理していたスプレッドシート"/></p>
<p>最終的に入社を決めたラクスルは Forkwell 経由での応募ではなかったのですが、それでも選考に際しては多分にご協力いただき助かりましたし、感謝しております🙏</p>
<h2 id="転職活動を振り返って"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#転職活動を振り返って"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>転職活動を振り返って</h2>
<p>転職活動を振り返ると、短期間ではあったものの非常に中身の詰まった活動期間だったと改めて思います。</p>
<h3 id="企業の中の人と話ができる"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#企業の中の人と話ができる"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>企業の中の人と話ができる</h3>
<p>普段仕事をしていて、直近ではなかなか社外の人と話す機会を得られていなかったこともあり、社外のエンジニアや役員の方と話す機会を頂けるのは貴重だと感じました。
特に子どもが生まれてからは勉強会への参加にも消極的になっていたので、色んな会社の技術的な話を多く伺うことができたのは、純粋に勉強になることが多く楽しかったです。</p>
<p>また、複数社の選考を通して自分を見つめ直すきっかけにもなりましたし、最終的な意思決定をする際には最後の最後まで本当に悩みました。</p>
<h3 id="キャリアを振り返るきっかけになる"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#キャリアを振り返るきっかけになる"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>キャリアを振り返るきっかけになる</h3>
<p>普段業務に忙殺されていると、なかなかキャリアを振り返る機会をつくれないです。
ただ、転職活動のたびに思うことではあるのですが、1年も経つとそれまでやっていたことを詳細に思い出すことは難しくなるので、転職意向の有無に関わらず、定期的にキャリアを振り返る機会を設けることが大事だと改めて感じました。</p>
<h2 id="最後に"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#最後に"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>最後に</h2>
<p>ラクスルでは、屋台骨として成長し続けるプロダクトの商品開発から組織づくりまで積極的に関わっていきたいと思っています。数多くの課題の解決に向けてトライできる環境ですので、興味がある方はお気軽にご連絡ください！</p>
<small><p>※ 本記事は <a href="https://forkwell.notion.site/Forkwell-13c8e16b2bb08020bf1bc01d6e68fe6b" rel="nofollow" target="_blank">Forkwell
転職体験談投稿キャンペーン</a>
に参加しています</p></small>]]></content:encoded></item><item><title><![CDATA[ESLint のカスタムルールでディレクトリに配置するファイルの拡張子を制限する]]></title><description><![CDATA[プロダクト開発において、コーディング規約を定めておくことはコードの品質を保つ上で重要です。]]></description><link>https://reona.dev/posts/20240109181019</link><guid isPermaLink="false">/posts/20240109181019</guid><category><![CDATA[eslint]]></category><category><![CDATA[javascript]]></category><category><![CDATA[typescript]]></category><pubDate>Tue, 09 Jan 2024 09:10:19 GMT</pubDate><content:encoded><![CDATA[<link rel="preload" as="image" href="https://i.gyazo.com/42f643d809cd42fc4606d39acb2282b2.png"/><h2 id="はじめに"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#はじめに"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>はじめに</h2>
<p>プロダクト開発において、コーディング規約を定めておくことはコードの品質を保つ上で重要です。しかし、ドキュメンテーションを行なう場合にあがるのがメンテナンスの問題です。ドキュメントは定期的に見直して更新していく必要がありますが、更新するのも一定のコストがかかります。更新されないことでドキュメント自体が負債になるケースも考えられるでしょう。</p>
<p>基本的には開発ルールを <strong>意識せずに</strong> 遵守していくために、Linter や Formatter の力を借りるのがベストだと考えています。</p>
<p>今回は ESLint のカスタムルールで指定した拡張子以外のファイルを配置した場合にエラーを発生させる仕組みを作ったのでご紹介します。</p>
<h2 id="手順"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#手順"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>手順</h2>
<p>今回は ESLint のプラグインとしてルールを追加し、package.json で依存関係として管理する方法を選択しました。</p>
<h3 id="プラグインを作成する"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#プラグインを作成する"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>プラグインを作成する</h3>
<p>次のコマンドを実行し、プラグインのひな形を作成していきます。
便宜上ルートディレクトリにディレクトリやファイルを作成していますが、より適切なディレクトリに配置できるとよいでしょう。</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="shell" data-theme="github-dark"><code data-language="shell" data-theme="github-dark" style="display:grid"><span class="line" data-line=""><span style="color:#B392F0">mkdir</span><span style="color:#9ECBFF"> eslint-custom-rules</span></span>
<span class="line" data-line=""><span style="color:#79B8FF">cd</span><span style="color:#9ECBFF"> eslint-custom-rules</span></span>
<span class="line" data-line=""><span style="color:#B392F0">npm</span><span style="color:#9ECBFF"> init</span><span style="color:#79B8FF"> -y</span></span>
<span class="line" data-line=""><span style="color:#B392F0">touch</span><span style="color:#9ECBFF"> index.js</span></span>
<span class="line" data-line=""><span style="color:#B392F0">mkdir</span><span style="color:#9ECBFF"> rules</span></span>
<span class="line" data-line=""><span style="color:#B392F0">touch</span><span style="color:#9ECBFF"> rules/restrict-extensions.js</span></span>
<span class="line" data-line=""><span style="color:#B392F0">mkdir</span><span style="color:#9ECBFF"> tests</span></span>
<span class="line" data-line=""><span style="color:#B392F0">touch</span><span style="color:#9ECBFF"> tests/restrict-extensions.spec.js</span></span></code></pre></figure>
<p>ESLint のプラグインとして package.json で管理したいため、追加した eslint-custom-rules ディレクトリに移動して <code>npm init -y</code> コマンドで初期化しています。</p>
<p>package.json がデフォルトで追加されるので、<code>name</code> を <code>eslint-plugin-&lt;plugin-name&gt;</code> のフォーマットに変更します。（他のプロパティは初期値のままです）</p>
<figure data-rehype-pretty-code-figure=""><figcaption data-rehype-pretty-code-title="" data-language="json" data-theme="github-dark">package.json</figcaption><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="json" data-theme="github-dark"><code data-line-numbers="" data-language="json" data-theme="github-dark" style="display:grid" data-line-numbers-max-digits="2"><span class="line" data-line=""><span style="color:#E1E4E8">{</span></span>
<span class="line" data-line=""><span style="color:#79B8FF">  &quot;name&quot;</span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">&quot;eslint-plugin-custom-rules&quot;</span><span style="color:#E1E4E8">,</span></span>
<span class="line" data-line=""><span style="color:#79B8FF">  &quot;version&quot;</span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">&quot;1.0.0&quot;</span><span style="color:#E1E4E8">,</span></span>
<span class="line" data-line=""><span style="color:#79B8FF">  &quot;description&quot;</span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">&quot;&quot;</span><span style="color:#E1E4E8">,</span></span>
<span class="line" data-line=""><span style="color:#79B8FF">  &quot;main&quot;</span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">&quot;index.js&quot;</span><span style="color:#E1E4E8">,</span></span>
<span class="line" data-line=""><span style="color:#79B8FF">  &quot;scripts&quot;</span><span style="color:#E1E4E8">: {</span></span>
<span class="line" data-line=""><span style="color:#79B8FF">    &quot;test&quot;</span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">&quot;echo </span><span style="color:#79B8FF">\&quot;</span><span style="color:#9ECBFF">Error: no test specified</span><span style="color:#79B8FF">\&quot;</span><span style="color:#9ECBFF"> &amp;&amp; exit 1&quot;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  },</span></span>
<span class="line" data-line=""><span style="color:#79B8FF">  &quot;keywords&quot;</span><span style="color:#E1E4E8">: [],</span></span>
<span class="line" data-line=""><span style="color:#79B8FF">  &quot;author&quot;</span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">&quot;&quot;</span><span style="color:#E1E4E8">,</span></span>
<span class="line" data-line=""><span style="color:#79B8FF">  &quot;license&quot;</span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">&quot;ISC&quot;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">}</span></span></code></pre></figure>
<p><code>main</code> に指定している index.js が Entry point となるため、Export するルールを追加します。</p>
<figure data-rehype-pretty-code-figure=""><figcaption data-rehype-pretty-code-title="" data-language="js" data-theme="github-dark">index.js</figcaption><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="js" data-theme="github-dark"><code data-line-numbers="" data-language="js" data-theme="github-dark" style="display:grid" data-line-numbers-max-digits="1"><span class="line" data-line=""><span style="color:#79B8FF">module</span><span style="color:#E1E4E8">.</span><span style="color:#79B8FF">exports</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> {</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  rules: {</span></span>
<span class="line" data-line=""><span style="color:#9ECBFF">    &quot;restrict-extensions&quot;</span><span style="color:#E1E4E8">: </span><span style="color:#B392F0">require</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">&quot;./rules/restrict-extensions&quot;</span><span style="color:#E1E4E8">),</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">};</span></span></code></pre></figure>
<h3 id="ルールの記述"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#ルールの記述"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>ルールの記述</h3>
<p>本題であるカスタムルールを書いていきます。フォーマットは <a href="https://eslint.org/docs/latest/extend/custom-rules" rel="nofollow" target="_blank">ESLint の Custom Rules ドキュメント</a>を参考にしています。</p>
<figure data-rehype-pretty-code-figure=""><figcaption data-rehype-pretty-code-title="" data-language="js" data-theme="github-dark">restrict-extensions.js</figcaption><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="js" data-theme="github-dark"><code data-line-numbers="" data-language="js" data-theme="github-dark" style="display:grid" data-line-numbers-max-digits="2"><span class="line" data-line=""><span style="color:#9ECBFF">&quot;use strict&quot;</span><span style="color:#E1E4E8">;</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#79B8FF">module</span><span style="color:#E1E4E8">.</span><span style="color:#79B8FF">exports</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> {</span></span>
<span class="line" data-line=""><span style="color:#B392F0">  create</span><span style="color:#E1E4E8">: </span><span style="color:#F97583">function</span><span style="color:#E1E4E8"> (</span><span style="color:#FFAB70">context</span><span style="color:#E1E4E8">) {</span></span>
<span class="line" data-line=""><span style="color:#F97583">    return</span><span style="color:#E1E4E8"> {</span></span>
<span class="line" data-line=""><span style="color:#B392F0">      Program</span><span style="color:#E1E4E8">: </span><span style="color:#F97583">function</span><span style="color:#E1E4E8"> (</span><span style="color:#FFAB70">node</span><span style="color:#E1E4E8">) {</span></span>
<span class="line" data-line=""><span style="color:#F97583">        const</span><span style="color:#79B8FF"> options</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> context.options;</span></span>
<span class="line" data-line=""><span style="color:#F97583">        const</span><span style="color:#79B8FF"> filename</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> context.</span><span style="color:#B392F0">getFilename</span><span style="color:#E1E4E8">();</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#F97583">        for</span><span style="color:#E1E4E8"> (</span><span style="color:#F97583">const</span><span style="color:#E1E4E8"> { </span><span style="color:#79B8FF">directory</span><span style="color:#E1E4E8">, </span><span style="color:#79B8FF">extension</span><span style="color:#E1E4E8"> } </span><span style="color:#F97583">of</span><span style="color:#E1E4E8"> options) {</span></span>
<span class="line" data-line=""><span style="color:#F97583">          if</span><span style="color:#E1E4E8"> (directory </span><span style="color:#F97583">&amp;&amp;</span><span style="color:#E1E4E8"> extension) {</span></span>
<span class="line" data-line=""><span style="color:#F97583">            if</span><span style="color:#E1E4E8"> (filename.</span><span style="color:#B392F0">includes</span><span style="color:#E1E4E8">(directory) </span><span style="color:#F97583">&amp;&amp;</span><span style="color:#F97583"> !</span><span style="color:#E1E4E8">filename.</span><span style="color:#B392F0">endsWith</span><span style="color:#E1E4E8">(extension)) {</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">              context.</span><span style="color:#B392F0">report</span><span style="color:#E1E4E8">({</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">                node,</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">                message: </span><span style="color:#9ECBFF">`&#x27;${</span><span style="color:#E1E4E8">directory</span><span style="color:#9ECBFF">}&#x27;ディレクトリにファイルを配置する場合、ファイルの拡張子は&#x27;${</span><span style="color:#E1E4E8">extension</span><span style="color:#9ECBFF">}&#x27;としてください。`</span><span style="color:#E1E4E8">,</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">              });</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">            }</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">          }</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">        }</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">      },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    };</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">};</span></span></code></pre></figure>
<p>ルールのオプションとしてディレクトリと拡張子を渡します。また、いくつかルールを適用させたいディレクトリがある場合を考慮し、復数のオプション渡すことができるようにしています。</p>
<p>このルールを適用することで、ディレクトリ配下に指定した拡張子以外のファイルが検知された場合にエラーが発生します。</p>
<h3 id="テストの追加"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#テストの追加"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>テストの追加</h3>
<p>ESLint のバージョンアップやルール内容の更新を考慮してテストを用意しておきます。Testing library は jest を想定しています。</p>
<figure data-rehype-pretty-code-figure=""><figcaption data-rehype-pretty-code-title="" data-language="js" data-theme="github-dark">restrict-extensions.spec.js</figcaption><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="js" data-theme="github-dark"><code data-line-numbers="" data-language="js" data-theme="github-dark" style="display:grid" data-line-numbers-max-digits="2"><span class="line" data-line=""><span style="color:#9ECBFF">&quot;use strict&quot;</span><span style="color:#E1E4E8">;</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#F97583">import</span><span style="color:#E1E4E8"> { RuleTester } </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> &quot;eslint&quot;</span><span style="color:#E1E4E8">;</span></span>
<span class="line" data-line=""><span style="color:#F97583">import</span><span style="color:#E1E4E8"> Rule </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> &quot;../rules/restrict-extensions&quot;</span><span style="color:#E1E4E8">;</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#B392F0">describe</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">&quot;restrict-extensions&quot;</span><span style="color:#E1E4E8">, () </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line" data-line=""><span style="color:#F97583">  const</span><span style="color:#79B8FF"> tester</span><span style="color:#F97583"> =</span><span style="color:#F97583"> new</span><span style="color:#B392F0"> RuleTester</span><span style="color:#E1E4E8">({</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    parserOptions: { ecmaVersion: </span><span style="color:#79B8FF">2020</span><span style="color:#E1E4E8">, sourceType: </span><span style="color:#9ECBFF">&quot;module&quot;</span><span style="color:#E1E4E8"> },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  });</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#E1E4E8">  tester.</span><span style="color:#B392F0">run</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">&quot;restrict-extensions&quot;</span><span style="color:#E1E4E8">, Rule, {</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    valid: [</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">      {</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">        code: </span><span style="color:#9ECBFF">&quot;let validExtension;&quot;</span><span style="color:#E1E4E8">,</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">        filename: </span><span style="color:#9ECBFF">&quot;app/javascript/packs/file.ts&quot;</span><span style="color:#E1E4E8">,</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">        options: [{ directory: </span><span style="color:#9ECBFF">&quot;app/javascript/packs/&quot;</span><span style="color:#E1E4E8">, extension: </span><span style="color:#9ECBFF">&quot;.ts&quot;</span><span style="color:#E1E4E8"> }],</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">      },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">      {</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">        code: </span><span style="color:#9ECBFF">&quot;let validExtension;&quot;</span><span style="color:#E1E4E8">,</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">        filename: </span><span style="color:#9ECBFF">&quot;app/javascript/components/common/file.vue&quot;</span><span style="color:#E1E4E8">,</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">        options: [</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">          { directory: </span><span style="color:#9ECBFF">&quot;app/javascript/types/&quot;</span><span style="color:#E1E4E8">, extension: </span><span style="color:#9ECBFF">&quot;.ts&quot;</span><span style="color:#E1E4E8"> },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">          { directory: </span><span style="color:#9ECBFF">&quot;app/javascript/components/&quot;</span><span style="color:#E1E4E8">, extension: </span><span style="color:#9ECBFF">&quot;.tsx&quot;</span><span style="color:#E1E4E8"> },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">        ],</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">      },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    ],</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    invalid: [</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">      {</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">        code: </span><span style="color:#9ECBFF">&quot;let invalidExtension;&quot;</span><span style="color:#E1E4E8">,</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">        filename: </span><span style="color:#9ECBFF">&quot;app/javascript/packs/file.js&quot;</span><span style="color:#E1E4E8">,</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">        options: [{ directory: </span><span style="color:#9ECBFF">&quot;app/javascript/packs/&quot;</span><span style="color:#E1E4E8">, extension: </span><span style="color:#9ECBFF">&quot;.ts&quot;</span><span style="color:#E1E4E8"> }],</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">        errors: [</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">          {</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">            message:</span></span>
<span class="line" data-line=""><span style="color:#9ECBFF">              &quot;&#x27;app/javascript/packs/&#x27;ディレクトリにファイルを配置する場合、ファイルの拡張子は&#x27;.ts&#x27;としてください。&quot;</span><span style="color:#E1E4E8">,</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">          },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">        ],</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">      },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">      {</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">        code: </span><span style="color:#9ECBFF">&quot;let invalidExtension;&quot;</span><span style="color:#E1E4E8">,</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">        filename: </span><span style="color:#9ECBFF">&quot;app/javascript/components/common/file.ts&quot;</span><span style="color:#E1E4E8">,</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">        options: [</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">          { directory: </span><span style="color:#9ECBFF">&quot;app/javascript/types/&quot;</span><span style="color:#E1E4E8">, extension: </span><span style="color:#9ECBFF">&quot;.ts&quot;</span><span style="color:#E1E4E8"> },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">          { directory: </span><span style="color:#9ECBFF">&quot;app/javascript/components/&quot;</span><span style="color:#E1E4E8">, extension: </span><span style="color:#9ECBFF">&quot;.tsx&quot;</span><span style="color:#E1E4E8"> },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">        ],</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">        errors: [</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">          {</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">            message:</span></span>
<span class="line" data-line=""><span style="color:#9ECBFF">              &quot;&#x27;app/javascript/components/&#x27;ディレクトリにファイルを配置する場合、ファイルの拡張子は&#x27;.tsx&#x27;としてください。&quot;</span><span style="color:#E1E4E8">,</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">          },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">        ],</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">      },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    ],</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  });</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">});</span></span></code></pre></figure>
<p>テストを実行し、成功することを確認します。事前に <code>filename</code> や <code>options</code> の値を変更して意図的に失敗させておくとより安心でしょう。</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="shell" data-theme="github-dark"><code data-language="shell" data-theme="github-dark" style="display:grid"><span class="line" data-line=""><span style="color:#F97583">&gt;</span><span style="color:#E1E4E8"> jest --runInBand --runTestsByPath eslint-custom-rules/tests/restrict-extensions.spec.js</span></span>
<span class="line" data-line=""><span style="color:#B392F0">PASS</span><span style="color:#9ECBFF">  eslint-custom-rules/tests/restrict-extensions.spec.js</span></span>
<span class="line" data-line=""><span style="color:#B392F0">  restrict-extensions</span></span>
<span class="line" data-line=""><span style="color:#B392F0">    restrict-extensions</span></span>
<span class="line" data-line=""><span style="color:#B392F0">      valid</span></span>
<span class="line" data-line=""><span style="color:#B392F0">        ✓</span><span style="color:#9ECBFF"> let</span><span style="color:#9ECBFF"> validExtension</span><span style="color:#E1E4E8">; (</span><span style="color:#B392F0">14</span><span style="color:#9ECBFF"> ms</span><span style="color:#E1E4E8">)</span></span>
<span class="line" data-line=""><span style="color:#B392F0">        ✓</span><span style="color:#9ECBFF"> let</span><span style="color:#9ECBFF"> validExtension</span><span style="color:#E1E4E8">; (</span><span style="color:#B392F0">1</span><span style="color:#9ECBFF"> ms</span><span style="color:#E1E4E8">)</span></span>
<span class="line" data-line=""><span style="color:#B392F0">      invalid</span></span>
<span class="line" data-line=""><span style="color:#B392F0">        ✓</span><span style="color:#9ECBFF"> let</span><span style="color:#9ECBFF"> invalidExtension</span><span style="color:#E1E4E8">; (</span><span style="color:#B392F0">2</span><span style="color:#9ECBFF"> ms</span><span style="color:#E1E4E8">)</span></span>
<span class="line" data-line=""><span style="color:#B392F0">        ✓</span><span style="color:#9ECBFF"> let</span><span style="color:#9ECBFF"> invalidExtension</span><span style="color:#E1E4E8">; (</span><span style="color:#B392F0">1</span><span style="color:#9ECBFF"> ms</span><span style="color:#E1E4E8">)</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#B392F0">Test</span><span style="color:#9ECBFF"> Suites:</span><span style="color:#79B8FF"> 1</span><span style="color:#9ECBFF"> passed,</span><span style="color:#79B8FF"> 1</span><span style="color:#9ECBFF"> total</span></span>
<span class="line" data-line=""><span style="color:#B392F0">Tests:</span><span style="color:#79B8FF">       4</span><span style="color:#9ECBFF"> passed,</span><span style="color:#79B8FF"> 4</span><span style="color:#9ECBFF"> total</span></span>
<span class="line" data-line=""><span style="color:#B392F0">Snapshots:</span><span style="color:#79B8FF">   0</span><span style="color:#9ECBFF"> total</span></span>
<span class="line" data-line=""><span style="color:#B392F0">Time:</span><span style="color:#79B8FF">        1.221</span><span style="color:#9ECBFF"> s</span></span>
<span class="line" data-line=""><span style="color:#B392F0">Ran</span><span style="color:#9ECBFF"> all</span><span style="color:#9ECBFF"> test</span><span style="color:#9ECBFF"> suites</span><span style="color:#9ECBFF"> within</span><span style="color:#9ECBFF"> paths</span><span style="color:#9ECBFF"> &quot;eslint-custom-rules/tests/restrict-extensions.spec.js&quot;.</span></span>
<span class="line" data-line=""><span style="color:#B392F0">Done</span><span style="color:#9ECBFF"> in</span><span style="color:#9ECBFF"> 5.46s.</span></span></code></pre></figure>
<h3 id="ルールを適用させる"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#ルールを適用させる"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>ルールを適用させる</h3>
<p>ルールを適用させたいリポジトリの package.json に次のような記述を追加し、開発時の依存関係としてインストールします。</p>
<figure data-rehype-pretty-code-figure=""><figcaption data-rehype-pretty-code-title="" data-language="json" data-theme="github-dark">package.json</figcaption><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="json" data-theme="github-dark"><code data-language="json" data-theme="github-dark" style="display:grid"><span class="line" data-line=""><span style="color:#9ECBFF">  &quot;devDependencies&quot;</span><span style="color:#E1E4E8">: {</span></span>
<span class="line" data-line=""><span style="color:#79B8FF">    &quot;eslint-plugin-custom-rules&quot;</span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">&quot;file:./eslint-custom-rules&quot;</span><span style="color:#E1E4E8">,</span></span></code></pre></figure>
<p>.eslintrc.js にプラグイン・ルールを追加することで、カスタムルールが適用されます。</p>
<figure data-rehype-pretty-code-figure=""><figcaption data-rehype-pretty-code-title="" data-language="js" data-theme="github-dark">.eslintrc.js</figcaption><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="js" data-theme="github-dark"><code data-line-numbers="" data-language="js" data-theme="github-dark" style="display:grid" data-line-numbers-max-digits="2"><span class="line" data-line=""><span style="color:#79B8FF">module</span><span style="color:#E1E4E8">.</span><span style="color:#79B8FF">exports</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> {</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  plugins: [</span><span style="color:#9ECBFF">&quot;custom-rules&quot;</span><span style="color:#E1E4E8">],</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  rules: {</span></span>
<span class="line" data-line=""><span style="color:#9ECBFF">    &quot;custom-rules/restrict-extensions&quot;</span><span style="color:#E1E4E8">: [</span></span>
<span class="line" data-line=""><span style="color:#9ECBFF">      &quot;error&quot;</span><span style="color:#E1E4E8">,</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">      { directory: </span><span style="color:#9ECBFF">&quot;app/javascript/packs/&quot;</span><span style="color:#E1E4E8">, extension: </span><span style="color:#9ECBFF">&quot;.ts&quot;</span><span style="color:#E1E4E8"> },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">      { directory: </span><span style="color:#9ECBFF">&quot;app/javascript/components/&quot;</span><span style="color:#E1E4E8">, extension: </span><span style="color:#9ECBFF">&quot;.tsx&quot;</span><span style="color:#E1E4E8"> },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    ],</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">};</span></span></code></pre></figure>
<p>.tsx 拡張子に制限しているディレクトリ配下に .js 拡張子のファイルを配置すると次のようにエラーメッセージが表示されました。</p>
<p><a href="https://gyazo.com/42f643d809cd42fc4606d39acb2282b2" rel="nofollow" target="_blank"><img src="https://i.gyazo.com/42f643d809cd42fc4606d39acb2282b2.png" alt="Neovim 上で表示されるカスタムルールのエラーメッセージ"/></a></p>
<h2 id="最後に"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#最後に"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>最後に</h2>
<p>今回はプラグインとしてカスタムルールを作成する方法をご紹介しました。</p>
<p>ESLint の設定ファイルは今後 eslintrc から Flat config が推奨されることが<a href="https://eslint.org/blog/2023/10/flat-config-rollout-plans/" rel="nofollow" target="_blank">公式ブログの記事</a>で発表されました。Flat config に移行することで eslint.config.js 内でカスタムルールを直接 <code>import</code> できるようになります。Flat config をすぐに適用できる環境であれば、今回ご紹介した方法ではなくそちらを使う方がよいでしょう。</p>
<p>既存の ESLint のプラグインでは満たせないような仕組みが柔軟に作れるので、今後も積極的に使っていきたいです。</p>]]></content:encoded></item><item><title><![CDATA[Vue 3 の概要と Vue 2 との違いについて]]></title><description><![CDATA[2023年1月27日に実施した社内勉強会でのポストを一部改変して転記しています。]]></description><link>https://reona.dev/posts/20240104092054</link><guid isPermaLink="false">/posts/20240104092054</guid><category><![CDATA[vue]]></category><category><![CDATA[frontend]]></category><pubDate>Thu, 04 Jan 2024 00:20:54 GMT</pubDate><content:encoded><![CDATA[<link rel="preload" as="image" href="https://i.gyazo.com/0cb1b4226f83216a3e7eefbc177e49ed.png"/><h2 id="前置き"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#前置き"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>前置き</h2>
<p>2023 年 1 月 27 日に実施した社内勉強会でのポストを一部改変して転記しています。</p>
<h2 id="概要"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#概要"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>概要</h2>
<p>現在 Vue.js を使っている各プロジェクトにおいて、Vue 2 → Vue 3 へのアップグレードが進行しています。
<a href="https://v3-migration.vuejs.org/breaking-changes/" rel="nofollow" target="_blank">このアップグレードにおける破壊的変更</a>は非常に多く、今後フロントエンド開発を継続する上での学習コストは少なくないため、Vue 3 における主要機能やアップグレードすることによるメリットを Vue 2 までの機能と比較しながら解説していきます。</p>
<h2 id="vue-3について"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#vue-3について"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>Vue 3について</h2>
<p>Vue 3 は 2020 年 9 月 19 日にリリースされました。<a href="https://github.com/vuejs/core/releases" rel="nofollow" target="_blank">2023年01月27日現在の最新バージョンは v3.2.45</a>です。
Vue 2 と比較したメリットはざっくり次の通りです。</p>
<ul>
<li>Composition API などの主要機能追加によるコードの最適化</li>
<li>全面的な TypeScript のサポート</li>
<li>ビルド後のバンドルサイズが大きく改善したことによるパフォーマンスの向上</li>
</ul>
<h2 id="コードの最適化"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#コードの最適化"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>コードの最適化</h2>
<p>Vue 2 では Options API が主に利用されていましたが、Composition API に変更することで次のようなメリットがあります。</p>
<ul>
<li>JavaScript らしい記法でコンポーネントを記述できる</li>
<li>フレームワークにそこまで依存しない記法なので、変数や関数の型定義がしやすい</li>
<li>リアクティブな値（ref, reactive, computed）やそれに関するロジックが UI コンポーネントに依存しない
<ul>
<li>再利用性が向上し、Pure な JS/TS の関数になるためより testable になる</li>
</ul>
</li>
<li><a href="https://v3.ja.vuejs.org/guide/composition-api-lifecycle-hooks.html" rel="nofollow" target="_blank">ライフサイクルフック</a>が少し単純になった</li>
</ul>
<p>また、Vue 3.2 で追加された <code>&lt;script setup&gt;</code> 記法を使うことでよりコードがシンプルに記述できるようになります。</p>
<h3 id="javascript-らしい記法でコンポーネントを記述できる"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#javascript-らしい記法でコンポーネントを記述できる"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>JavaScript らしい記法でコンポーネントを記述できる</h3>
<p>Options API では、ボイラープレート的なフレームワークに依存した記法を覚える必要がありました。</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="js" data-theme="github-dark"><code data-language="js" data-theme="github-dark" style="display:grid"><span class="line" data-line=""><span style="color:#F97583">export</span><span style="color:#F97583"> default</span><span style="color:#E1E4E8"> Vue.</span><span style="color:#B392F0">extend</span><span style="color:#E1E4E8">({</span></span>
<span class="line" data-line=""><span style="color:#B392F0">  data</span><span style="color:#E1E4E8">: () </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> ({</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    name: </span><span style="color:#9ECBFF">&quot;&quot;</span><span style="color:#E1E4E8">,</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  }),</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  methods: {</span></span>
<span class="line" data-line=""><span style="color:#B392F0">    input</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">value</span><span style="color:#E1E4E8">) {</span></span>
<span class="line" data-line=""><span style="color:#79B8FF">      this</span><span style="color:#E1E4E8">.name </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> value;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  computed: {</span></span>
<span class="line" data-line=""><span style="color:#B392F0">    call</span><span style="color:#E1E4E8">() {</span></span>
<span class="line" data-line=""><span style="color:#F97583">      return</span><span style="color:#9ECBFF"> `${</span><span style="color:#79B8FF">this</span><span style="color:#9ECBFF">.</span><span style="color:#E1E4E8">name</span><span style="color:#9ECBFF">} 様`</span><span style="color:#E1E4E8">;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">});</span></span></code></pre></figure>
<p>Composition API を利用することで、フレームワーク独自の記法が少なくなるので、より JavaScript らしいコードでコンポーネントを記述できるようになります。</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="js" data-theme="github-dark"><code data-language="js" data-theme="github-dark" style="display:grid"><span class="line" data-line=""><span style="color:#F97583">export</span><span style="color:#F97583"> default</span><span style="color:#B392F0"> defineComponent</span><span style="color:#E1E4E8">({</span></span>
<span class="line" data-line=""><span style="color:#B392F0">  setup</span><span style="color:#E1E4E8">() {</span></span>
<span class="line" data-line=""><span style="color:#F97583">    const</span><span style="color:#79B8FF"> name</span><span style="color:#F97583"> =</span><span style="color:#B392F0"> ref</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">&quot;&quot;</span><span style="color:#E1E4E8">);</span></span>
<span class="line" data-line=""><span style="color:#F97583">    const</span><span style="color:#B392F0"> input</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> (</span><span style="color:#FFAB70">value</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">      name.value </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> value;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    };</span></span>
<span class="line" data-line=""><span style="color:#F97583">    const</span><span style="color:#79B8FF"> call</span><span style="color:#F97583"> =</span><span style="color:#B392F0"> computed</span><span style="color:#E1E4E8">(() </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line" data-line=""><span style="color:#F97583">      return</span><span style="color:#9ECBFF"> `${</span><span style="color:#79B8FF">this</span><span style="color:#9ECBFF">.</span><span style="color:#E1E4E8">name</span><span style="color:#9ECBFF">} 様`</span><span style="color:#E1E4E8">;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    });</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#F97583">    return</span><span style="color:#E1E4E8"> { name, input, call };</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">});</span></span></code></pre></figure>
<p><code>const</code>, <code>let</code> などの JavaScript のキーワードを用いて変数や関数を宣言できるので、<code>setup</code> 内のコードは非常に記述しやすくなります。</p>
<h3 id="リアクティブな値やロジックが-ui-コンポーネントに依存しない"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#リアクティブな値やロジックが-ui-コンポーネントに依存しない"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>リアクティブな値やロジックが UI コンポーネントに依存しない</h3>
<p><code>setup</code> 内で宣言するリアクティブな値や関数は、UI コンポーネントから切り離すことができます。</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="js" data-theme="github-dark"><code data-language="js" data-theme="github-dark" style="display:grid"><span class="line" data-line=""><span style="color:#F97583">export</span><span style="color:#F97583"> default</span><span style="color:#E1E4E8"> const </span><span style="color:#B392F0">useForm</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line" data-line=""><span style="color:#F97583">    const</span><span style="color:#79B8FF"> name</span><span style="color:#F97583"> =</span><span style="color:#B392F0"> ref</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">&#x27;&#x27;</span><span style="color:#E1E4E8">)</span></span>
<span class="line" data-line=""><span style="color:#F97583">    const</span><span style="color:#B392F0"> input</span><span style="color:#F97583"> =</span><span style="color:#FFAB70"> value</span><span style="color:#F97583"> =&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">      name.value </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> value</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    }</span></span>
<span class="line" data-line=""><span style="color:#F97583">    const</span><span style="color:#79B8FF"> call</span><span style="color:#F97583"> =</span><span style="color:#B392F0"> computed</span><span style="color:#E1E4E8">(() </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line" data-line=""><span style="color:#F97583">      return</span><span style="color:#9ECBFF"> `${</span><span style="color:#79B8FF">this</span><span style="color:#9ECBFF">.</span><span style="color:#E1E4E8">name</span><span style="color:#9ECBFF">} 様`</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    })</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#F97583">    return</span><span style="color:#E1E4E8"> { name, input, call }</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">}</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#6A737D">// Vue コンポーネント側</span></span>
<span class="line" data-line=""><span style="color:#F97583">export</span><span style="color:#F97583"> default</span><span style="color:#B392F0"> defineComponent</span><span style="color:#E1E4E8">({</span></span>
<span class="line" data-line=""><span style="color:#B392F0">  setup</span><span style="color:#E1E4E8">() {</span></span>
<span class="line" data-line=""><span style="color:#F97583">    const</span><span style="color:#E1E4E8"> { </span><span style="color:#79B8FF">name</span><span style="color:#E1E4E8">, </span><span style="color:#79B8FF">input</span><span style="color:#E1E4E8">, </span><span style="color:#79B8FF">call</span><span style="color:#E1E4E8"> } </span><span style="color:#F97583">=</span><span style="color:#B392F0"> useForm</span><span style="color:#E1E4E8">()</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#F97583">    return</span><span style="color:#E1E4E8"> { name, input, call }</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  }</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">})</span></span></code></pre></figure>
<p>コンポーネントに関係する値やロジックを独立できるので、単体テストが書きやすくなります。
また、複数コンポーネント間で値やロジックの使いまわしができるようになるのもメリットです。</p>
<h3 id="ライフサイクルフックが単純になった"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#ライフサイクルフックが単純になった"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>ライフサイクルフックが単純になった</h3>
<p><a href="https://gyazo.com/0cb1b4226f83216a3e7eefbc177e49ed" rel="nofollow" target="_blank"><img src="https://i.gyazo.com/0cb1b4226f83216a3e7eefbc177e49ed.png" alt="Vue.js ライフサイクルフックの早見表"/></a></p>
<p>refs: <a href="https://v3.ja.vuejs.org/guide/composition-api-lifecycle-hooks.html" rel="nofollow" target="_blank">ライフサイクルフック</a></p>
<p><code>beforeCreate</code>, <code>created</code> がなくなり、本来これらのライフサイクルに書かれていたロジックは <code>setup</code> 内で直接記述するようになりました。</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="js" data-theme="github-dark"><code data-language="js" data-theme="github-dark" style="display:grid"><span class="line" data-line=""><span style="color:#F97583">export</span><span style="color:#F97583"> default</span><span style="color:#B392F0"> defineComponent</span><span style="color:#E1E4E8">({</span></span>
<span class="line" data-line=""><span style="color:#B392F0">  setup</span><span style="color:#E1E4E8">() {</span></span>
<span class="line" data-line=""><span style="color:#6A737D">    // 従来の created のタイミングで実行される</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">&quot;Component is created!&quot;</span><span style="color:#E1E4E8">);</span></span>
<span class="line" data-line=""><span style="color:#6A737D">    // mounted</span></span>
<span class="line" data-line=""><span style="color:#B392F0">    onMounted</span><span style="color:#E1E4E8">(() </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">      console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">&quot;Component is mounted!&quot;</span><span style="color:#E1E4E8">);</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    });</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">});</span></span></code></pre></figure>
<h3 id="vue-32-で追加された記法について"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#vue-32-で追加された記法について"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>Vue 3.2 で追加された記法について</h3>
<p>Vue 3.2 からは <a href="https://v3.ja.vuejs.org/api/sfc-script-setup.html" rel="nofollow" target="_blank"><code>&lt;script setup&gt;</code></a>というシンタックスシュガーが追加され、よりシンプルにコンポーネントを構成できるようになります。
これまでの記法と比較することで違いがわかりやすくなるので、順を追ってコードを比較していきましょう。
（それぞれのタイトルが Playground のリンクになっています）</p>
<p><a href="https://sfc.vuejs.org/#eNpdkktuwjAQhq8ysioFJIj3UUDqBbrsKgtMMoEgv+QHpUK5R2/Qm/UcHTsQWja2x9/M75lfvrJXa8tzRFaxOqCyUgTcNhqg7o1ToDAcTbdpmDU+NCwTYlLsUQJlENFCIZE32mqewT1r0DYGGFL5lATntTIdysdF+LRIUcALqQP/X3mDPu7V8MA1T53RseZ/GqbQt26wAaTQhyTpc7ucw6CscQHeI0LvjIKCxi1SBTG8ZNZhL6LMOSW1grpbXBv9BOkGoBNBVLBYwmYLKSe1m2apoChWKRyXeZuM89VUBZAnWpyFjLi83wGE4+DLVA4byGwC46SU19YoqsRuVmqFlPT+rOEwRKdh93Kd1Ub4+f7aPWuNybLJJDKGrdhkzFoJW5680fQFsmhzA2Tg/GjDyLQUN+wYgvUV575v08c5+dK4A6dT6aIOgyIHvVrvnfnw6Ei4YbkBep+Nv7BjzZM=" rel="nofollow" target="_blank">Options API</a></p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="vue" data-theme="github-dark"><code data-language="vue" data-theme="github-dark" style="display:grid"><span class="line" data-line=""><span style="color:#E1E4E8">&lt;</span><span style="color:#85E89D">template</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  &lt;</span><span style="color:#85E89D">form</span><span style="color:#B392F0"> method</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;post&quot;</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    &lt;</span><span style="color:#85E89D">label</span><span style="color:#B392F0"> for</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;name&quot;</span><span style="color:#E1E4E8">&gt;Name&lt;/</span><span style="color:#85E89D">label</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    &lt;</span><span style="color:#85E89D">input</span><span style="color:#B392F0"> id</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;name&quot;</span><span style="color:#B392F0"> v-model</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;</span><span style="color:#E1E4E8">name</span><span style="color:#9ECBFF">&quot;</span><span style="color:#B392F0"> type</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;text&quot;</span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    &lt;</span><span style="color:#85E89D">input</span><span style="color:#B392F0"> type</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;submit&quot;</span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  &lt;/</span><span style="color:#85E89D">form</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">&lt;/</span><span style="color:#85E89D">template</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#E1E4E8">&lt;</span><span style="color:#85E89D">script</span><span style="color:#B392F0"> lang</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;ts&quot;</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#F97583">import</span><span style="color:#E1E4E8"> Vue </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> &#x27;vue&#x27;</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#F97583">export</span><span style="color:#F97583"> default</span><span style="color:#E1E4E8"> Vue.</span><span style="color:#B392F0">extend</span><span style="color:#E1E4E8">({</span></span>
<span class="line" data-line=""><span style="color:#B392F0">  data</span><span style="color:#E1E4E8">: () </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> ({</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    name: </span><span style="color:#9ECBFF">&#x27;&#x27;</span><span style="color:#E1E4E8">,</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  }),</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  methods: {</span></span>
<span class="line" data-line=""><span style="color:#B392F0">    input</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">value</span><span style="color:#E1E4E8">) {</span></span>
<span class="line" data-line=""><span style="color:#79B8FF">      this</span><span style="color:#E1E4E8">.name </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> value</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  computed: {</span></span>
<span class="line" data-line=""><span style="color:#B392F0">    call</span><span style="color:#E1E4E8">() {</span></span>
<span class="line" data-line=""><span style="color:#F97583">      return</span><span style="color:#9ECBFF"> `${</span><span style="color:#79B8FF">this</span><span style="color:#9ECBFF">.</span><span style="color:#E1E4E8">name</span><span style="color:#9ECBFF">} 様`</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">}</span></span>
<span class="line" data-line=""><span style="color:#F97583">&lt;/</span><span style="color:#E1E4E8">script</span><span style="color:#F97583">&gt;</span></span></code></pre></figure>
<p><a href="https://sfc.vuejs.org/#eNpVUltugzAQvMrKqgSVCPxHJFLV/56AjxBYEiK/ZC9pKsQ9eoPerOfo2oBCf2yvZ2d2PPIo3qzN7wOKvSgJlZU14bHSAGVnnAKFdDXtoRLWeKpERBiT9RklcAcjulbIyAdvZRGBtavXdiDoA31ugvtOmRbl84K+LHJF+GB1KP4zF9APZ9U/4bIIzvhYFhvDXPrG9ZZA1voSJH202ytrHMEILXa9xnfDtUZNGTjsMmi4HghbmKBzRkHCUSRBDR+Rx6x6kHHfstMxOPFIg01fIRbAWtoThIfBIainSfK6ReZHHeBey4FbjisPIidfrmd4RqYtvamlZHh1nPLgrYZjM07D6WWka+/zIDnB78/3aZFiK/NpaRzj1Gx2xUEE9TiPl9BcFnOenKHIxBzjTtU2v3mj+bfEwdUCcNb71UolOMNQV+JKZP2+KHzXhD9287lxl4JPuRs09fxo9Gp3dubTo2PhSqwGxPQH3kje/Q==" rel="nofollow" target="_blank">Composition API</a></p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="vue" data-theme="github-dark"><code data-language="vue" data-theme="github-dark" style="display:grid"><span class="line" data-line=""><span style="color:#E1E4E8">&lt;</span><span style="color:#85E89D">template</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  &lt;</span><span style="color:#85E89D">form</span><span style="color:#B392F0"> method</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;post&quot;</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    &lt;</span><span style="color:#85E89D">label</span><span style="color:#B392F0"> for</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;name&quot;</span><span style="color:#E1E4E8">&gt;Name&lt;/</span><span style="color:#85E89D">label</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    &lt;</span><span style="color:#85E89D">input</span><span style="color:#B392F0"> id</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;name&quot;</span><span style="color:#B392F0"> v-model</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;</span><span style="color:#E1E4E8">name</span><span style="color:#9ECBFF">&quot;</span><span style="color:#B392F0"> type</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;text&quot;</span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    &lt;</span><span style="color:#85E89D">input</span><span style="color:#B392F0"> type</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;submit&quot;</span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  &lt;/</span><span style="color:#85E89D">form</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">&lt;/</span><span style="color:#85E89D">template</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#E1E4E8">&lt;</span><span style="color:#85E89D">script</span><span style="color:#B392F0"> lang</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;ts&quot;</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#F97583">import</span><span style="color:#E1E4E8"> { defineComponent, ref, computed } </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> &quot;vue&quot;</span><span style="color:#E1E4E8">;</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#F97583">export</span><span style="color:#F97583"> default</span><span style="color:#B392F0"> defineComponent</span><span style="color:#E1E4E8">({</span></span>
<span class="line" data-line=""><span style="color:#B392F0">  setup</span><span style="color:#E1E4E8">() {</span></span>
<span class="line" data-line=""><span style="color:#F97583">    const</span><span style="color:#79B8FF"> name</span><span style="color:#F97583"> =</span><span style="color:#B392F0"> ref</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">&quot;&quot;</span><span style="color:#E1E4E8">);</span></span>
<span class="line" data-line=""><span style="color:#F97583">    const</span><span style="color:#B392F0"> input</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> (</span><span style="color:#FFAB70">value</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">      name.value </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> value;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    };</span></span>
<span class="line" data-line=""><span style="color:#F97583">    const</span><span style="color:#79B8FF"> call</span><span style="color:#F97583"> =</span><span style="color:#B392F0"> computed</span><span style="color:#E1E4E8">(() </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line" data-line=""><span style="color:#F97583">      return</span><span style="color:#9ECBFF"> `${</span><span style="color:#79B8FF">this</span><span style="color:#9ECBFF">.</span><span style="color:#E1E4E8">name</span><span style="color:#9ECBFF">} 様`</span><span style="color:#E1E4E8">;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    });</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#F97583">    return</span><span style="color:#E1E4E8"> { name, input, call };</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">});</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">&lt;/</span><span style="color:#85E89D">script</span><span style="color:#E1E4E8">&gt;</span></span></code></pre></figure>
<p><a href="https://sfc.vuejs.org/#eNpVUW1uwjAMvYoVTRpI0PyvCtIusBPkB6G4EJQvJS7bVPUeu8FutnPMaSlo+RPnPT/Hfh7EW4zVrUdRiya3yUSCjNRHsNqfd0pQVmKvvHExJIIBEnYbaIOLPeEJRuhScKAEV1BCeeXb4DOB1w5hV5JXr6/rBTWeVQzftO2Z3sOgPEy51R2aKeXHRdJqaxlePlyt1g9d4jaTh8PLQBeTq1JmhN+f7wPL+ctGzuNw8/wgdNFqQn4BNF1IDhzSJZx4xBgyTUMCn8bqI1rgDGZKTWbe+WrkRCxZ8yimyOckuG1dOKF9AvQVsRiIn1wd5H/lncz90Zkn3cjSGYeNfDQsNmI2f+t0rK45eF7VZIC6E7yherakYNMmag4uRDHXUuauLQu+5iqks+SoSr0nw6ZjdttjCh8ZExcu+wNg50cx/gHOVrbH" rel="nofollow" target="_blank"><code>&lt;script setup&gt;</code></a></p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="vue" data-theme="github-dark"><code data-language="vue" data-theme="github-dark" style="display:grid"><span class="line" data-line=""><span style="color:#E1E4E8">&lt;</span><span style="color:#85E89D">script</span><span style="color:#B392F0"> setup</span><span style="color:#B392F0"> lang</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;ts&quot;</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#F97583">import</span><span style="color:#E1E4E8"> { ref, computed } </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> &quot;vue&quot;</span><span style="color:#E1E4E8">;</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#F97583">const</span><span style="color:#79B8FF"> name</span><span style="color:#F97583"> =</span><span style="color:#B392F0"> ref</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">&quot;&quot;</span><span style="color:#E1E4E8">);</span></span>
<span class="line" data-line=""><span style="color:#F97583">const</span><span style="color:#B392F0"> input</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> (</span><span style="color:#FFAB70">value</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  name.value </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> value;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">};</span></span>
<span class="line" data-line=""><span style="color:#F97583">const</span><span style="color:#79B8FF"> call</span><span style="color:#F97583"> =</span><span style="color:#B392F0"> computed</span><span style="color:#E1E4E8">(() </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line" data-line=""><span style="color:#F97583">  return</span><span style="color:#9ECBFF"> `${</span><span style="color:#79B8FF">this</span><span style="color:#9ECBFF">.</span><span style="color:#E1E4E8">name</span><span style="color:#9ECBFF">} 様`</span><span style="color:#E1E4E8">;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">});</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">&lt;/</span><span style="color:#85E89D">script</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#E1E4E8">&lt;</span><span style="color:#85E89D">template</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  &lt;</span><span style="color:#85E89D">form</span><span style="color:#B392F0"> method</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;post&quot;</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    &lt;</span><span style="color:#85E89D">label</span><span style="color:#B392F0"> for</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;name&quot;</span><span style="color:#E1E4E8">&gt;Name&lt;/</span><span style="color:#85E89D">label</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    &lt;</span><span style="color:#85E89D">input</span><span style="color:#B392F0"> id</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;name&quot;</span><span style="color:#B392F0"> v-model</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;</span><span style="color:#E1E4E8">name</span><span style="color:#9ECBFF">&quot;</span><span style="color:#B392F0"> type</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;text&quot;</span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    &lt;</span><span style="color:#85E89D">input</span><span style="color:#B392F0"> type</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;submit&quot;</span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  &lt;/</span><span style="color:#85E89D">form</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">&lt;/</span><span style="color:#85E89D">template</span><span style="color:#E1E4E8">&gt;</span></span></code></pre></figure>
<p>とてもシンプルになりました🙌</p>
<p>一度 Composition API の記法でコードを書けるようになれば、<code>&lt;script setup&gt;</code> 構文に全く違和感なく、むしろ気持ちよく移行できるはずです。
公式のサンプルコードを見てもわかると思いますが、<code>script</code> → <code>template</code> の順序に変わっているので、本稿のサンプルコードもそちらに準拠しています。
ちなみに逆の順序でも問題なく動くので、Playground で試してみてください。</p>
<h4 id="language-server"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#language-server"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>Language server</h4>
<p>これまで Vue の Language server は <a href="https://github.com/vuejs/vetur" rel="nofollow" target="_blank">vuejs / vetur</a> でしたが、<code>&lt;script setup&gt;</code> 構文には対応していないため <a href="https://github.com/johnsoncodehk/volar" rel="nofollow" target="_blank">johnsoncodehk / volar</a> の利用が推奨されています。</p>
<p>以下公式ツイート
<a href="https://twitter.com/vuejs/status/1429195877365780486?s=20&amp;t=s8ZKmwmrabCWU7hhsx0eZw" rel="nofollow" target="_blank">https://twitter.com/vuejs/status/1429195877365780486?s=20&amp;t=s8ZKmwmrabCWU7hhsx0eZw</a></p>
<h4 id="components"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#components"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>Components</h4>
<p>これまではテンプレート内で <code>import</code> した components 使うには <code>props</code> などの並びで一度列挙して登録する必要がありましたが、 <code>import</code> するだけで直接利用できるようになりました。</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="vue" data-theme="github-dark"><code data-language="vue" data-theme="github-dark" style="display:grid"><span class="line" data-line=""><span style="color:#E1E4E8">&lt;</span><span style="color:#85E89D">script</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#F97583">import</span><span style="color:#E1E4E8"> MyComponent </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> &quot;./MyComponent.vue&quot;</span><span style="color:#E1E4E8">;</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#6A737D">// これまでは登録する必要があった</span></span>
<span class="line" data-line=""><span style="color:#F97583">export</span><span style="color:#F97583"> default</span><span style="color:#E1E4E8"> {</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  components: { MyComponent },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">};</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">&lt;/</span><span style="color:#85E89D">script</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#E1E4E8">&lt;</span><span style="color:#85E89D">template</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  &lt;</span><span style="color:#85E89D">MyComponent</span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">&lt;/</span><span style="color:#85E89D">template</span><span style="color:#E1E4E8">&gt;</span></span></code></pre></figure>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="vue" data-theme="github-dark"><code data-language="vue" data-theme="github-dark" style="display:grid"><span class="line" data-line=""><span style="color:#E1E4E8">&lt;</span><span style="color:#85E89D">script</span><span style="color:#B392F0"> setup</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#6A737D">// import のみでコンポーネントを使える</span></span>
<span class="line" data-line=""><span style="color:#F97583">import</span><span style="color:#E1E4E8"> MyComponent </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> &quot;./MyComponent.vue&quot;</span><span style="color:#E1E4E8">;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">&lt;/</span><span style="color:#85E89D">script</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#E1E4E8">&lt;</span><span style="color:#85E89D">template</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  &lt;</span><span style="color:#85E89D">MyComponent</span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">&lt;/</span><span style="color:#85E89D">template</span><span style="color:#E1E4E8">&gt;</span></span></code></pre></figure>
<h4 id="props-emit"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#props-emit"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>props, emit</h4>
<p><code>props</code> と <code>emit</code> については <code>defineProps</code>, <code>defineEmits</code> を利用することで <code>&lt;script setup&gt;</code> 構文内で宣言ができます。
これまでは <code>props</code>, <code>emit</code> の型定義や型推論や完全ではありませんでしたが、Pure な TypeScript の記法で宣言ができるようになるので自然に型を定義でき、型推論もされるようになります。</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="vue" data-theme="github-dark"><code data-language="vue" data-theme="github-dark" style="display:grid"><span class="line" data-line=""><span style="color:#E1E4E8">&lt;</span><span style="color:#85E89D">script</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#F97583">export</span><span style="color:#F97583"> default</span><span style="color:#E1E4E8"> {</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  props: {</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    name: { type: String },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  methods: {</span></span>
<span class="line" data-line=""><span style="color:#B392F0">    onInput</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">target</span><span style="color:#E1E4E8">) {</span></span>
<span class="line" data-line=""><span style="color:#79B8FF">      this</span><span style="color:#E1E4E8">.</span><span style="color:#B392F0">$emit</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">&quot;input&quot;</span><span style="color:#E1E4E8">, target.value);</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  },</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">};</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">&lt;/</span><span style="color:#85E89D">script</span><span style="color:#E1E4E8">&gt;</span></span></code></pre></figure>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="vue" data-theme="github-dark"><code data-language="vue" data-theme="github-dark" style="display:grid"><span class="line" data-line=""><span style="color:#E1E4E8">&lt;</span><span style="color:#85E89D">script</span><span style="color:#B392F0"> setup</span><span style="color:#B392F0"> lang</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;ts&quot;</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#F97583">const</span><span style="color:#79B8FF"> props</span><span style="color:#F97583"> =</span><span style="color:#B392F0"> defineProps</span><span style="color:#E1E4E8">&lt;{ </span><span style="color:#FFAB70">name</span><span style="color:#F97583">:</span><span style="color:#79B8FF"> string</span><span style="color:#E1E4E8"> }&gt;();</span></span>
<span class="line" data-line=""><span style="color:#6A737D">// デフォルト値を入れたい場合は withDefaults を使う</span></span>
<span class="line" data-line=""><span style="color:#6A737D">// const props = withDefaults(defineProps&lt;{ name: string }&gt;(), { name: &#x27;太郎&#x27; })</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#F97583">const</span><span style="color:#79B8FF"> emit</span><span style="color:#F97583"> =</span><span style="color:#B392F0"> defineEmits</span><span style="color:#E1E4E8">&lt;{ (</span><span style="color:#FFAB70">e</span><span style="color:#F97583">:</span><span style="color:#9ECBFF"> &quot;input&quot;</span><span style="color:#E1E4E8">, </span><span style="color:#FFAB70">value</span><span style="color:#F97583">:</span><span style="color:#79B8FF"> string</span><span style="color:#E1E4E8">)</span><span style="color:#F97583">:</span><span style="color:#79B8FF"> void</span><span style="color:#E1E4E8"> }&gt;();</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#F97583">const</span><span style="color:#B392F0"> onInput</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> ({ </span><span style="color:#FFAB70">target</span><span style="color:#E1E4E8"> }</span><span style="color:#F97583">:</span><span style="color:#E1E4E8"> { </span><span style="color:#FFAB70">target</span><span style="color:#F97583">:</span><span style="color:#B392F0"> HTMLInputElement</span><span style="color:#E1E4E8"> }) </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line" data-line=""><span style="color:#B392F0">  emit</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">&quot;input&quot;</span><span style="color:#E1E4E8">, target.value);</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">};</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">&lt;/</span><span style="color:#85E89D">script</span><span style="color:#E1E4E8">&gt;</span></span></code></pre></figure>
<p><code>defineProps</code>や <code>withDefaults</code>、 <code>defineEmits</code> は <code>&lt;script setup&gt;</code> 内でのみ使用可能なコンパイラマクロなので、インポートせずに利用できます。</p>
<h3 id="最後に"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#最後に"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>最後に</h3>
<p>今回紹介できなかった機能もたくさんあるので、ぜひ公式ドキュメントなどをチェックしてみてください！</p>
<p>また、TypeScript サポートが手厚くなっていることで今後も TypeScript のコードは増えていくと思うので、<a href="https://www.typescriptlang.org/docs/" rel="nofollow" target="_blank">ドキュメント</a>を読んでみたり <a href="https://github.com/type-challenges/type-challenges" rel="nofollow" target="_blank">実際に手を動かしてみる</a> のもいいと思います👩‍💻</p>
<p><a href="https://github.com/webfansplz/vuejs-challenges" rel="nofollow" target="_blank">vuejs-challenges</a> は Vue 3 対応しているので、課題にトライしていって今回紹介したような記法に慣れておくのもいいですね👍</p>
<h2 id="参考資料"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#参考資料"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>参考資料</h2>
<ul>
<li><a href="https://vuejs.org/guide/extras/composition-api-faq.html" rel="nofollow" target="_blank">Composition API FAQ</a></li>
<li><a href="https://ics.media/entry/220120/" rel="nofollow" target="_blank">2022年の最新標準！Vue 3の新しい開発体験に触れよう</a></li>
<li><a href="https://zenn.dev/844/articles/facd083b7df63e" rel="nofollow" target="_blank">Composition APIを使って感じた「これどうなの？」</a></li>
<li><a href="https://studist.tech/migration-to-vue-3-4b4c4fad0324" rel="nofollow" target="_blank">機能開発を止めずに、500コンポーネント規模の Vue 3 移行を完了させた開発プロセス</a></li>
<li><a href="https://zenn.dev/azukiazusa/articles/676d88675e4e74" rel="nofollow" target="_blank">【Vue.js 3.2】<code>&lt;script setup&gt;</code> 構文がすごくすごい</a></li>
</ul>]]></content:encoded></item><item><title><![CDATA[VoiceOver を使ってみた]]></title><description><![CDATA[VoiceOver とは MacOS や iOS に標準でインストールされているスクリーンリーダーです。VoiceOver を利用すれば、画面上のテキストや画像等の情報を音声で読み上げてくれるため、画面を見なくてもデバイスの操作ができるようになります。]]></description><link>https://reona.dev/posts/20231229095156</link><guid isPermaLink="false">/posts/20231229095156</guid><category><![CDATA[accessibility]]></category><pubDate>Fri, 29 Dec 2023 00:51:56 GMT</pubDate><content:encoded><![CDATA[<h2 id="voiceover-とは"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#voiceover-とは"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>VoiceOver とは</h2>
<p>VoiceOver とは MacOS や iOS に標準でインストールされているスクリーンリーダーです。VoiceOver を利用すれば、画面上にあるテキストや画像などの情報を音声で読み上げてくれるため、画面を見なくてもデバイスの操作ができるようになります。</p>
<h2 id="なぜ使ってみたのか"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#なぜ使ってみたのか"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>なぜ使ってみたのか</h2>
<p>スクリーンリーダーを一度使ってみたかったからです。</p>
<p>私は普段の業務でプロダクトを開発しているチームに所属し、Web サービスのバックエンドからフロントエンドまで開発を担っています。</p>
<p>プロダクトを利用するユーザーは非常に多様であり、より多くのユーザーにとって使いやすく不便さを感じさせないプロダクトを目指しています。</p>
<p>主な操作をスクリーンリーダーを介して行なっている人に対するプロダクトの使いやすさを考慮する上で、実際に自分が使ってみることは不可欠だと考えました。</p>
<h2 id="voiceover-の使い方"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#voiceover-の使い方"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>VoiceOver の使い方</h2>
<p>VoiceOver をオンにする方法は複数あります。</p>
<h3 id="macos"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#macos"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>MacOS</h3>
<ul>
<li>ショートカットキー
<ul>
<li><code>Command</code> ＋ <code>F5</code> キーを押す</li>
<li><code>Command</code> キーを押したまま Touch ID を素早く 3 回押す</li>
</ul>
</li>
<li>システム設定
<ul>
<li>サイドバーのアクセシビリティから VoiceOver を選択し、オンにする</li>
</ul>
</li>
<li>Siri に「VoiceOver をオンにして」と話しかける</li>
</ul>
<h3 id="ios"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#ios"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>iOS</h3>
<ul>
<li>設定
<ul>
<li>アクセシビリティ → VoiceOver を選択し、オンにする</li>
</ul>
</li>
<li>コントロールセンターに追加する</li>
<li>アクセシビリティのショートカットに設定して使用する</li>
<li>Siri に「VoiceOver をオンにして」と話しかける</li>
</ul>
<p>Siri は設定次第では音声入力のみで利用開始できる点が優れていると感じました。</p>
<h2 id="実際に使ってみて"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#実際に使ってみて"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>実際に使ってみて</h2>
<p>実際に画面を見ないで音声案内に従い、iPhone, MacBook を使って普段の操作をある程度再現できました。</p>
<p>一方で、実際に使ってみて操作するハードルも多分に感じました。</p>
<ul>
<li>操作前に音声を聞き取り理解することが前提である
<ul>
<li>聞き取り理解する行動がオーバーヘッドとなり、操作に時間がかかる</li>
<li>音声を正しく理解できないと意図した操作に繋がらない</li>
<li>アプリケーションやブラウザ上のページによっては、操作する上で必要十分な情報を音声として読み上げてくれない</li>
</ul>
</li>
</ul>
<p>特に後半の項目の改善はプロダクトの開発者次第なので、普段からスクリーンリーダーによってどのように読み上げられるのかを考えていく必要がありそうです。</p>
<h2 id="まとめ"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#まとめ"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>まとめ</h2>
<p>今回は複数のデバイスで VoiceOver を使ってみましたが、多くの気づきを得られました。</p>
<p>リンクやボタンのテキスト、要素によっては WAI-ARIA を使って音声のみでも操作可能なマークアップをすることが望ましいですが、実際にスクリーンリーダーを通して発見できる改善点も必ずあるはずです。</p>
<p>より多くの人に価値を届けられるプロダクト開発に繋がるはずなので、今後も開発する際には積極的に使っていこうと思いました。</p>
<h2 id="参考資料"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#参考資料"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>参考資料</h2>
<ul>
<li><a href="https://support.apple.com/ja-jp/guide/voiceover/welcome/mac" rel="nofollow" target="_blank">https://support.apple.com/ja-jp/guide/voiceover/welcome/mac</a></li>
<li><a href="https://support.apple.com/ja-jp/guide/iphone/iph3e2e415f/iOS" rel="nofollow" target="_blank">https://support.apple.com/ja-jp/guide/iphone/iph3e2e415f/iOS</a></li>
</ul>]]></content:encoded></item><item><title><![CDATA[Sass を使わずに CSS をネストさせる]]></title><description><![CDATA[CSS のネストを可能にする CSS Nesting がモダンブラウザでサポートされ、Sass に依存しない CSS の書き方が大きく変わり始めています。]]></description><link>https://reona.dev/posts/20231219193357</link><guid isPermaLink="false">/posts/20231219193357</guid><category><![CDATA[css]]></category><category><![CDATA[sass]]></category><category><![CDATA[scss]]></category><pubDate>Tue, 19 Dec 2023 10:33:57 GMT</pubDate><content:encoded><![CDATA[<link rel="preload" as="image" href="/2023-12-21-23-07-28.png"/><h2 id="css-nesting-とは"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#css-nesting-とは"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>CSS Nesting とは</h2>
<p>CSS で Sass や Less のような入れ子構造での記述を可能にするものです。</p>
<p>例えば</p>
<figure data-rehype-pretty-code-figure=""><figcaption data-rehype-pretty-code-title="" data-language="html" data-theme="github-dark">./foo.html</figcaption><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="html" data-theme="github-dark"><code data-line-numbers="" data-language="html" data-theme="github-dark" style="display:grid" data-line-numbers-max-digits="1"><span class="line" data-line=""><span style="color:#E1E4E8">&lt;</span><span style="color:#85E89D">div</span><span style="color:#B392F0"> class</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;container&quot;</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  &lt;</span><span style="color:#85E89D">p</span><span style="color:#B392F0"> class</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;container__text&quot;</span><span style="color:#E1E4E8">&gt;Hello&lt;/</span><span style="color:#85E89D">p</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">&lt;/</span><span style="color:#85E89D">div</span><span style="color:#E1E4E8">&gt;</span></span></code></pre></figure>
<p>このような HTML に CSS を当てる場合、</p>
<figure data-rehype-pretty-code-figure=""><figcaption data-rehype-pretty-code-title="" data-language="css" data-theme="github-dark">./foo.css</figcaption><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="css" data-theme="github-dark"><code data-line-numbers="" data-language="css" data-theme="github-dark" style="display:grid" data-line-numbers-max-digits="1"><span class="line" data-line=""><span style="color:#B392F0">.container</span><span style="color:#E1E4E8"> {</span></span>
<span class="line" data-line=""><span style="color:#79B8FF">  padding</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">16</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">}</span></span>
<span class="line" data-line=""> </span>
<span class="line line--highlighted" data-line="" data-highlighted-line=""><span style="color:#B392F0">.container</span><span style="color:#B392F0"> .container__text</span><span style="color:#E1E4E8"> {</span></span>
<span class="line line--highlighted" data-line="" data-highlighted-line=""><span style="color:#79B8FF">  font-size</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">12</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line line--highlighted" data-line="" data-highlighted-line=""><span style="color:#E1E4E8">}</span></span></code></pre></figure>
<p>これまでは親子関係にあるセレクタでも上記のように同じ階層に書いていましたが、CSS Nesting を使うと次のような記述ができるようになります。</p>
<figure data-rehype-pretty-code-figure=""><figcaption data-rehype-pretty-code-title="" data-language="css" data-theme="github-dark">./foo.css</figcaption><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="css" data-theme="github-dark"><code data-line-numbers="" data-language="css" data-theme="github-dark" style="display:grid" data-line-numbers-max-digits="1"><span class="line" data-line=""><span style="color:#B392F0">.container</span><span style="color:#E1E4E8"> {</span></span>
<span class="line" data-line=""><span style="color:#79B8FF">  padding</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">16</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line" data-line=""> </span>
<span class="line line--highlighted" data-line="" data-highlighted-line=""><span style="color:#E1E4E8">  .</span><span style="color:#79B8FF">container</span><span style="color:#E1E4E8">__</span><span style="color:#79B8FF">text</span><span style="color:#E1E4E8"> {</span></span>
<span class="line line--highlighted" data-line="" data-highlighted-line=""><span style="color:#79B8FF">    font-size</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">12</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line line--highlighted" data-line="" data-highlighted-line=""><span style="color:#E1E4E8">  }</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">}</span></span></code></pre></figure>
<p>セレクタの階層構造がネストによって表現され、適切に利用することで保守性が高まります。</p>
<h2 id="ネストの記法"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#ネストの記法"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>ネストの記法</h2>
<p>Sass を書いたことがあれば、基本的には同じようにネストして書くことができます。</p>
<h3 id="クラスや-id-を選択するセレクタの場合"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#クラスや-id-を選択するセレクタの場合"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>クラスや ID を選択するセレクタの場合</h3>
<p>冒頭で書いたような記法がスタンダードですが、Nesting Selector である <code>&amp;</code> を Prefix として付与できます。</p>
<figure data-rehype-pretty-code-figure=""><figcaption data-rehype-pretty-code-title="" data-language="css" data-theme="github-dark">./foo.css</figcaption><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="css" data-theme="github-dark"><code data-line-numbers="" data-language="css" data-theme="github-dark" style="display:grid" data-line-numbers-max-digits="1"><span class="line" data-line=""><span style="color:#B392F0">.container</span><span style="color:#E1E4E8"> {</span></span>
<span class="line" data-line=""><span style="color:#79B8FF">  padding</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">16</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line" data-line=""> </span>
<span class="line line--highlighted" data-line="" data-highlighted-line=""><span style="color:#E1E4E8">  &amp; .</span><span style="color:#79B8FF">container</span><span style="color:#E1E4E8">__</span><span style="color:#79B8FF">text</span><span style="color:#E1E4E8"> {</span></span>
<span class="line line--highlighted" data-line="" data-highlighted-line=""><span style="color:#79B8FF">    font-size</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">12</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line line--highlighted" data-line="" data-highlighted-line=""><span style="color:#E1E4E8">  }</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">}</span></span></code></pre></figure>
<h3 id="main-h1-といった要素を選択するセレクタの場合"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#main-h1-といった要素を選択するセレクタの場合"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a><code>main</code>, <code>h1</code> といった要素を選択するセレクタの場合</h3>
<p>要素をネストする場合は <code>&amp;</code> を付与したうえで選択します。</p>
<figure data-rehype-pretty-code-figure=""><figcaption data-rehype-pretty-code-title="" data-language="html" data-theme="github-dark">./foo.html</figcaption><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="html" data-theme="github-dark"><code data-line-numbers="" data-language="html" data-theme="github-dark" style="display:grid" data-line-numbers-max-digits="1"><span class="line" data-line=""><span style="color:#E1E4E8">&lt;</span><span style="color:#85E89D">main</span><span style="color:#B392F0"> class</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;container&quot;</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  &lt;</span><span style="color:#85E89D">h1</span><span style="color:#E1E4E8">&gt;Hello&lt;/</span><span style="color:#85E89D">h1</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">&lt;/</span><span style="color:#85E89D">main</span><span style="color:#E1E4E8">&gt;</span></span></code></pre></figure>
<p>このような HTML に CSS を当てる場合、</p>
<figure data-rehype-pretty-code-figure=""><figcaption data-rehype-pretty-code-title="" data-language="css" data-theme="github-dark">./foo.css</figcaption><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="css" data-theme="github-dark"><code data-line-numbers="" data-language="css" data-theme="github-dark" style="display:grid" data-line-numbers-max-digits="1"><span class="line" data-line=""><span style="color:#B392F0">.container</span><span style="color:#E1E4E8"> {</span></span>
<span class="line" data-line=""><span style="color:#79B8FF">  padding</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">16</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line" data-line=""> </span>
<span class="line line--highlighted" data-line="" data-highlighted-line=""><span style="color:#E1E4E8">  &amp; </span><span style="color:#79B8FF">h</span><span style="color:#E1E4E8">1 {</span></span>
<span class="line line--highlighted" data-line="" data-highlighted-line=""><span style="color:#79B8FF">    color</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">blue</span><span style="color:#E1E4E8">;</span></span>
<span class="line line--highlighted" data-line="" data-highlighted-line=""><span style="color:#E1E4E8">  }</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">}</span></span></code></pre></figure>
<p>このようにすることで、<code>.container</code> の子要素である <code>h1</code> をスタイリングできます。</p>
<p>一部のブラウザでは CSS Nesting のサポートが進んでおり、次のように <code>&amp;</code> なしで要素を選択できます。</p>
<figure data-rehype-pretty-code-figure=""><figcaption data-rehype-pretty-code-title="" data-language="css" data-theme="github-dark">./foo.css</figcaption><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="css" data-theme="github-dark"><code data-line-numbers="" data-language="css" data-theme="github-dark" style="display:grid" data-line-numbers-max-digits="1"><span class="line" data-line=""><span style="color:#B392F0">.container</span><span style="color:#E1E4E8"> {</span></span>
<span class="line" data-line=""><span style="color:#79B8FF">  padding</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">16</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line" data-line=""> </span>
<span class="line line--highlighted" data-line="" data-highlighted-line=""><span style="color:#79B8FF">  h</span><span style="color:#E1E4E8">1 {</span></span>
<span class="line line--highlighted" data-line="" data-highlighted-line=""><span style="color:#79B8FF">    color</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">blue</span><span style="color:#E1E4E8">;</span></span>
<span class="line line--highlighted" data-line="" data-highlighted-line=""><span style="color:#E1E4E8">  }</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">}</span></span></code></pre></figure>
<p>12/19 時点でサポートを開始したブラウザとバージョンは次の通りです。</p>
<ul>
<li>Chrome 120(2023/12/8~)</li>
<li>Safari 17.2(2023/12/11~)</li>
<li>Firefox 117(2023/8/29~)</li>
</ul>
<h3 id="---といった結合子を使って選択するセレクタの場合"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#---といった結合子を使って選択するセレクタの場合"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a><code>+</code>, <code>~</code>, <code>&gt;</code> といった結合子を使って選択するセレクタの場合</h3>
<figure data-rehype-pretty-code-figure=""><figcaption data-rehype-pretty-code-title="" data-language="html" data-theme="github-dark">./foo.html</figcaption><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="html" data-theme="github-dark"><code data-line-numbers="" data-language="html" data-theme="github-dark" style="display:grid" data-line-numbers-max-digits="1"><span class="line" data-line=""><span style="color:#E1E4E8">&lt;</span><span style="color:#85E89D">div</span><span style="color:#B392F0"> class</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;container&quot;</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  &lt;</span><span style="color:#85E89D">p</span><span style="color:#B392F0"> class</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;container__text&quot;</span><span style="color:#E1E4E8">&gt;Hello&lt;/</span><span style="color:#85E89D">p</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  &lt;</span><span style="color:#85E89D">div</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    &lt;</span><span style="color:#85E89D">p</span><span style="color:#B392F0"> class</span><span style="color:#E1E4E8">=</span><span style="color:#9ECBFF">&quot;container__text&quot;</span><span style="color:#E1E4E8">&gt;こんにちは&lt;/</span><span style="color:#85E89D">p</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  &lt;/</span><span style="color:#85E89D">div</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">&lt;/</span><span style="color:#85E89D">div</span><span style="color:#E1E4E8">&gt;</span></span></code></pre></figure>
<p>このような HTML の場合で、<code>.container</code> の子要素の <code>.container__text</code> のみ選択したい場合は次のように書くことができます。</p>
<figure data-rehype-pretty-code-figure=""><figcaption data-rehype-pretty-code-title="" data-language="css" data-theme="github-dark">./foo.css</figcaption><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="css" data-theme="github-dark"><code data-line-numbers="" data-language="css" data-theme="github-dark" style="display:grid" data-line-numbers-max-digits="1"><span class="line" data-line=""><span style="color:#B392F0">.container</span><span style="color:#E1E4E8"> {</span></span>
<span class="line" data-line=""><span style="color:#79B8FF">  padding</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">16</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line" data-line=""> </span>
<span class="line line--highlighted" data-line="" data-highlighted-line=""><span style="color:#E1E4E8">  &gt; .</span><span style="color:#79B8FF">container</span><span style="color:#E1E4E8">__</span><span style="color:#79B8FF">text</span><span style="color:#E1E4E8"> {</span></span>
<span class="line line--highlighted" data-line="" data-highlighted-line=""><span style="color:#79B8FF">    font-size</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">12</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line line--highlighted" data-line="" data-highlighted-line=""><span style="color:#E1E4E8">  }</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">}</span></span></code></pre></figure>
<h3 id="擬似クラス--や疑似要素--を使って選択する場合"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#擬似クラス--や疑似要素--を使って選択する場合"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>擬似クラス <code>:</code> や疑似要素 <code>::</code> を使って選択する場合</h3>
<p>Sass と同様に <code>&amp;</code> に連結することで選択できます。</p>
<figure data-rehype-pretty-code-figure=""><figcaption data-rehype-pretty-code-title="" data-language="css" data-theme="github-dark">./foo.css</figcaption><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="css" data-theme="github-dark"><code data-line-numbers="" data-language="css" data-theme="github-dark" style="display:grid" data-line-numbers-max-digits="1"><span class="line" data-line=""><span style="color:#85E89D">button</span><span style="color:#E1E4E8"> {</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  &amp;:hover {</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">    opacity: </span><span style="color:#79B8FF">0.5</span><span style="color:#E1E4E8">;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  }</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">}</span></span></code></pre></figure>
<p><code>has()</code> は本日 12/19 に Firefox 121 でサポートが開始されたことにより、すべてのモダンブラウザで利用できるようになりました。
このような関数擬似クラスを利用する場合は次のように書くことができます。</p>
<figure data-rehype-pretty-code-figure=""><figcaption data-rehype-pretty-code-title="" data-language="css" data-theme="github-dark">./foo.css</figcaption><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="css" data-theme="github-dark"><code data-line-numbers="" data-language="css" data-theme="github-dark" style="display:grid" data-line-numbers-max-digits="1"><span class="line" data-line=""><span style="color:#85E89D">html</span><span style="color:#E1E4E8"> {</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  &amp;:has(dialog[</span><span style="color:#79B8FF">open</span><span style="color:#E1E4E8">]) {</span></span>
<span class="line" data-line=""><span style="color:#79B8FF">    overflow</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">hidden</span><span style="color:#E1E4E8">;</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">  }</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">}</span></span></code></pre></figure>
<h2 id="サポート状況"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#サポート状況"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>サポート状況</h2>
<p><img src="/2023-12-21-23-07-28.png" alt="CSS Nesting のサポート状況"/>
<a href="https://caniuse.com/css-nesting" rel="nofollow" target="_blank">https://caniuse.com/css-nesting</a></p>
<h2 id="関連資料"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#関連資料"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>関連資料</h2>
<ul>
<li><a href="https://www.w3.org/TR/css-nesting-1/" rel="nofollow" target="_blank">https://www.w3.org/TR/css-nesting-1/</a></li>
<li><a href="https://drafts.csswg.org/css-nesting/" rel="nofollow" target="_blank">https://drafts.csswg.org/css-nesting/</a></li>
</ul>]]></content:encoded></item><item><title><![CDATA[出産後の手続きについて]]></title><description><![CDATA[子の出産後に必要な手続きについて必要だったものを記録します。]]></description><link>https://reona.dev/posts/20230921220346</link><guid isPermaLink="false">/posts/20230921220346</guid><category><![CDATA[child]]></category><pubDate>Thu, 21 Sep 2023 13:03:46 GMT</pubDate><content:encoded><![CDATA[<h2 id="はじめに"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#はじめに"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>はじめに</h2>
<p>今年の 3 月に子を授かり、半年間の育休を取得しました。出産が 2 週間早まってしまったため、育休の開始時期も早まり出産前後は落ち着かなかったです。
特に子に関するさまざまな手続きに関しては、提出先や期限が複数あり煩雑であったため、主にどのような手続きがあったのか振り返っておきます。</p>
<h2 id="職場での手続き"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#職場での手続き"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>職場での手続き</h2>
<p>基本的には会社からの指示に従って進めていきましたが、同僚への引き継ぎ等も並行して行なうことから、できるだけ余裕を持って進めるとよいでしょう。</p>
<p>具体的には、次のような手続きがあります。</p>
<ul>
<li>出産報告</li>
<li>育児休業申請</li>
<li>扶養追加申請</li>
<li>各出生関連書類の提出
<ul>
<li>夫婦共同扶養収入額確認票</li>
<li>母子手帳のコピー</li>
<li>育児休業にかかる記載内容に関する確認書</li>
</ul>
</li>
</ul>
<p>職場によって提出書類や手続きが異なる場合があります。
健康保険証の発行や育児休業給付金の申請に関して、健康保険組合ではなく国民健康保険である場合には役所での手続きが必要になるようです。</p>
<p>その他に、母親の場合は出産育児一時金や出産手当金の申請が必要です。特に出産手当金に関しては、職場に提出する請求書を産院で事前に記載してもらう必要があり、私の依頼先の病院では返却までに 1 週間ほど要したので、出産前に請求書を用意しておき早めに産院と連携しておくとスムーズでしょう。</p>
<h2 id="役所での手続き"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#役所での手続き"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>役所での手続き</h2>
<p>役所においてもいくつか手続きを進める必要がありますが、ものによって担当課が異なります。役所によっては課名が異なる場合があるのでご了承ください。</p>
<h3 id="出生届"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#出生届"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>出生届</h3>
<ul>
<li>担当課
<ul>
<li>戸籍課</li>
</ul>
</li>
<li>期限
<ul>
<li>生まれた日から 14 日以内</li>
</ul>
</li>
<li>必要なもの
<ul>
<li>産院でもらえる出生届</li>
<li>母子手帳</li>
<li>印鑑</li>
</ul>
</li>
</ul>
<h3 id="児童手当金"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#児童手当金"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>児童手当金</h3>
<p>自治体によっては郵送での申請が可能です。</p>
<ul>
<li>担当課
<ul>
<li>こども家庭支援課</li>
</ul>
</li>
<li>期限
<ul>
<li>生まれた日の翌日から 15 日以内</li>
</ul>
</li>
<li>必要なもの
<ul>
<li>申請用紙</li>
<li>印鑑</li>
<li>健康保険証</li>
<li>通帳又はキャッシュカードのコピー</li>
<li>申請者・配偶者のマイナンバーカード</li>
</ul>
</li>
</ul>
<h3 id="医療証"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#医療証"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>医療証</h3>
<ul>
<li>担当課
<ul>
<li>こども家庭支援課</li>
</ul>
</li>
<li>期限
<ul>
<li>なるべく早く（1 か月健診で必要になるため）</li>
</ul>
</li>
<li>必要なもの
<ul>
<li>申請用紙</li>
<li>印鑑</li>
<li>子の健康保険証のコピー</li>
<li>申請者のマイナンバーカード</li>
</ul>
</li>
</ul>
<h3 id="出生連絡票"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#出生連絡票"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>出生連絡票</h3>
<p>母子手帳に付属している用紙です。保健師の乳児家庭訪問に必要であるため、なるべく早く提出する必要があります。</p>
<h2 id="まとめ"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#まとめ"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>まとめ</h2>
<p>事前にどういった手続きが必要なのか知っておくことで余裕が生まれます。産後に母と子が退院するのはあっという間で、その後に怒涛の育児が始まることを考えると事務手続きは退院前にはできるだけ済ませておきたいところです。</p>]]></content:encoded></item><item><title><![CDATA[macOS のセットアップをする]]></title><description><![CDATA[M1 MacBook Air(2020) を初期化する機会があったため、セットアップの手順を記録しておきます。]]></description><link>https://reona.dev/posts/20230712194532</link><guid isPermaLink="false">/posts/20230712194532</guid><category><![CDATA[macos]]></category><category><![CDATA[environment-setup]]></category><pubDate>Wed, 12 Jul 2023 10:45:32 GMT</pubDate><content:encoded><![CDATA[<h2 id="はじめに"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#はじめに"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>はじめに</h2>
<p>プライベートで利用している M1 MacBook Air(2020) を初期化する機会があったため、セットアップの手順を記録しておきます。</p>
<h2 id="前提"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#前提"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>前提</h2>
<p>移行アシスタントや Time Machine を利用すれば基本的に待機するだけでセットアップが完了しますが、社用パソコンの初期セットアップなどそれらを利用できないケースが考えられます。</p>
<p>そのため、今回は新規にユーザーを作成したうえでセットアップを進めます。</p>
<h2 id="システム環境設定"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#システム環境設定"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>システム環境設定</h2>
<p>次の手順でシステム環境設定を行ないます。</p>
<ul>
<li>Apple ID でサインインする</li>
<li>Wi-Fi
<ul>
<li>ネットワークの接続をする</li>
</ul>
</li>
<li>Bluetooth
<ul>
<li>ワイヤレス機器を接続する</li>
</ul>
</li>
<li>サウンド
<ul>
<li>通知音を OFF にする</li>
</ul>
</li>
<li>一般
<ul>
<li>OS のソフトウェアアップデートをする</li>
<li>ログイン項目で必要なアプリケーションを追加する</li>
</ul>
</li>
<li>外観
<ul>
<li>外観モードをダークにする</li>
</ul>
</li>
<li>コントロールバー
<ul>
<li>メニューバーに表示する項目を設定する</li>
</ul>
</li>
<li>コントロールセンター
<ul>
<li>コントロールセンターに表示したい項目を選択する</li>
</ul>
</li>
<li>デスクトップと Docks
<ul>
<li>Docks のサイズ変更</li>
</ul>
</li>
<li>Touch ID とパスコード
<ul>
<li>Apple Watch でロックを解除できるようにする</li>
</ul>
</li>
<li>キーボード
<ul>
<li>キーのリピート速度を最速にする</li>
<li>リピート入力認識までの時間を最速にする</li>
<li>キーボードの輝度を最低にする</li>
<li>キーボードショートカット
<ul>
<li>入力ソース
<ul>
<li>前の入力ソースを選択
<ul>
<li>⌘ + Space</li>
</ul>
</li>
</ul>
</li>
<li>Spotlight
<ul>
<li>Spotlight 検索を表示を OFF にする（raycast による検索を利用するため）</li>
</ul>
</li>
<li>修飾キー
<ul>
<li>Caps Lock キーと Control キーを入れ替える</li>
</ul>
</li>
</ul>
</li>
<li>入力ソース
<ul>
<li>ABC, ひらがな（Google）を設定
<ul>
<li>Google 日本語入力の入力ソースが表示されない場合は、一度他の入力ソースを設定したうえで再度入力ソースの編集を行なう</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>トラックパッド
<ul>
<li>軌跡の速さを最速にする</li>
</ul>
</li>
</ul>
<h2 id="ターミナル"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#ターミナル"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>ターミナル</h2>
<p>次の手順でターミナル上で設定を行ないます。</p>
<ol>
<li>Homebrew をインストールする</li>
</ol>
<ul>
<li><code>/bin/bash -c &quot;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)&quot;</code></li>
</ul>
<ol start="2">
<li>Git をインストールする</li>
</ol>
<ul>
<li><code>brew install git</code></li>
</ul>
<ol start="3">
<li>dotfiles を clone する</li>
</ol>
<ul>
<li><code>git clone https://github.com/reona5/dotfiles.git</code></li>
<li><code>make</code> コマンドを実行し、セットアップを行なう</li>
</ul>
<ol start="4">
<li>asdf でプラグインを追加し、動作するバージョンをインストールする</li>
</ol>
<ul>
<li>Ruby、Go、Node.js</li>
</ul>
<ol start="5">
<li>pnpm でグローバルパッケージをインストールする</li>
</ol>
<ul>
<li><code>pnpm add -g typescript typescript-language-server prettier @fsouza/prettierd eslint eslint_d</code></li>
</ul>
<ol start="6">
<li>Neovim を起動し、次のコマンドを実行してプラグインをインストールする</li>
</ol>
<ul>
<li><code>:Lazy</code></li>
</ul>
<ol start="7">
<li>
<p>tmux server を起動した状態で prefix + I を押下し、プラグインをダウンロードする</p>
</li>
<li>
<p>GitHub の access token を設定する</p>
</li>
</ol>
<ul>
<li>以下を参考に access token を生成する
<ul>
<li><a href="https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-fine-grained-personal-access-token" rel="nofollow" target="_blank">https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-fine-grained-personal-access-token</a></li>
</ul>
</li>
<li>push 時に username と password を求められるため、username に GitHub のユーザー名、password に access token を入力</li>
</ul>
<h2 id="各種アプリケーション"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#各種アプリケーション"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>各種アプリケーション</h2>
<p>インストール済みの各種アプリケーションを起動し、初回設定を行ないます。アプリケーション一覧は Brewfile に書かれています。</p>
<ul>
<li><a href="https://github.com/reona5/dotfiles/blob/main/.Brewfile" rel="nofollow" target="_blank">https://github.com/reona5/dotfiles/blob/main/.Brewfile</a></li>
</ul>
<p>追加で設定が必要なアプリケーションは次のとおりです。</p>
<ul>
<li>Alacritty
<ul>
<li>Finder 上で ⌘ キーを押下しながらクリックして開く</li>
</ul>
</li>
<li>Google Chrome
<ul>
<li>Google アカウントでログインして設定の同期を行なう</li>
<li>Google Meet PWA をインストールする
<ul>
<li><a href="https://support.google.com/meet/answer/10708569?hl=ja" rel="nofollow" target="_blank">https://support.google.com/meet/answer/10708569?hl=ja</a></li>
</ul>
</li>
</ul>
</li>
<li>Raycast でショートカットキーを設定する
<ul>
<li>Raycast Hotkey
<ul>
<li>⌘ + Control</li>
</ul>
</li>
<li>Clipboard History
<ul>
<li>⌘ + Control + v</li>
</ul>
</li>
</ul>
</li>
<li>DeepL でショートカットキーを設定する
<ul>
<li>⌘ + ;</li>
</ul>
</li>
<li>LINE でトークの送信方法を変更する
<ul>
<li>⌘ + Enter</li>
</ul>
</li>
</ul>
<h2 id="終わりに"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#終わりに"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>終わりに</h2>
<p>今回は macOS のセットアップ手順をまとめました。</p>
<p>dotfiles を利用することでほとんどの設定を行なうことができますが、システム環境設定は初回に設定して頻繁に更新するこ伴いので、忘れていることもあり設定に予想以上に時間がかかりました。</p>
<p>また、dotfiles は CI で build 時の挙動を担保しているのですが、インストールしたアプリケーションを実際に起動しようとした際に依存しているリソースがなく立ち上がらないこともありました。
そのため、追加でライブラリをインストールするなど dotfiles の内容を見直すいい機会にもなりました。</p>
<p>今後も macOS をセットアップする機会はあると思うので、追加で気づいたことがあればこちらの記事に追記します 📝</p>]]></content:encoded></item><item><title><![CDATA[Astro でブログを作り直した]]></title><description><![CDATA[Next.js で作成したブログを Astro で作り直しました。]]></description><link>https://reona.dev/posts/20230316003523</link><guid isPermaLink="false">/posts/20230316003523</guid><category><![CDATA[astro]]></category><category><![CDATA[blog]]></category><pubDate>Wed, 15 Mar 2023 15:35:23 GMT</pubDate><content:encoded><![CDATA[<link rel="preload" as="image" href="/2023-04-09-00-53-17.png"/><p>Next.js のテンプレートを使って作られたブログを Astro で作り直しました。</p>
<p><strong>2023/06/29 追記：Next.js に出戻りしました。Astro 版はリポジトリを分けて残しています。<a href="https://github.com/reona5/dev-by-astro" rel="nofollow" target="_blank">https://github.com/reona5/dev-by-astro</a></strong></p>
<h2 id="astro-を選択した理由"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#astro-を選択した理由"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>Astro を選択した理由</h2>
<p>Astro は SSG として機能する Web フレームワークです。ブログのような静的コンテンツの配信を目的とするウェブサイトの構築に向いています。
ランタイムで JavaScript を生成しないことからパフォーマンス水準が高く、他の SSG フレームワークと比較しても高速なページの描画を可能とします。</p>
<p>当ブログでは記事の執筆やブログの構築を通しての知識のアウトプットを目的としており、Web アプリケーションのような複雑な挙動はそれほど必要としないことから、Astro が最適と考えました。</p>
<p>また、仮に JavaScript を利用して複雑な挙動を実現したい場合でも Components Island を利用することで最低限の JavaScript でパフォーマンスの低下を最小限にできます。
React や Vue などのコンポーネントを組み込むことができるのも、さまざまな技術を試すことができる点で魅力的に感じました。</p>
<p>Astro には他にもいくつかの利点があります。詳しくは次のドキュメントをご参照ください。</p>
<p><a href="https://docs.astro.build/ja/concepts/why-astro/" rel="nofollow" target="_blank">Astro を選ぶ理由</a></p>
<h2 id="構築手順"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#構築手順"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>構築手順</h2>
<p>全体の流れとして、<a href="https://github.com/reona5/dev" rel="nofollow" target="_blank">reona.dev</a> のリポジトリ内新規の Astro プロジェクトを立ち上げて、1 つの Pull request で移行を進めました。</p>
<p><a href="https://docs.astro.build/en/getting-started/" rel="nofollow" target="_blank">Getting Started</a> に沿って、CLI コマンドを実行します。執筆時点での Astro の最新バージョンは v2.2.1 です。パッケージマネージャーは <code>pnpm</code> を利用します。</p>
<ol>
<li><code>pnpm create astro</code> を実行</li>
</ol>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="shell" data-theme="github-dark"><code data-language="shell" data-theme="github-dark" style="display:grid"><span class="line" data-line=""><span style="color:#B392F0">❯</span><span style="color:#9ECBFF"> pnpm</span><span style="color:#9ECBFF"> create</span><span style="color:#9ECBFF"> astro</span></span>
<span class="line" data-line=""><span style="color:#B392F0">pnpm</span><span style="color:#9ECBFF"> create</span><span style="color:#9ECBFF"> v1.22.19</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">[1/4] 🔍  Resolving packages...</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">[2/4] 🚚  Fetching packages...</span></span>
<span class="line" data-line=""><span style="color:#B392F0">warning</span><span style="color:#9ECBFF"> prettier-plugin-astro@0.7.2:</span><span style="color:#9ECBFF"> The</span><span style="color:#9ECBFF"> engine</span></span>
<span class="line" data-line=""><span style="color:#B392F0">  -</span><span style="color:#9ECBFF"> pnpm</span><span style="color:#9ECBFF"> appears</span><span style="color:#9ECBFF"> to</span><span style="color:#9ECBFF"> be</span><span style="color:#9ECBFF"> invalid.</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">[3/4] 🔗  Linking dependencies...</span></span>
<span class="line" data-line=""><span style="color:#E1E4E8">[4/4] 🔨  Building fresh packages...</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#B392F0">success</span><span style="color:#9ECBFF"> Installed</span></span>
<span class="line" data-line=""><span style="color:#B392F0">  -</span><span style="color:#9ECBFF"> create-astro@3.1.2</span><span style="color:#9ECBFF"> with</span><span style="color:#9ECBFF"> binaries:</span></span>
<span class="line" data-line=""><span style="color:#B392F0">      -</span><span style="color:#9ECBFF"> create-astro</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#B392F0">╭─────╮</span><span style="color:#9ECBFF">  Houston:</span></span>
<span class="line" data-line=""><span style="color:#B392F0">│</span><span style="color:#9ECBFF"> ◠</span><span style="color:#9ECBFF"> ◡</span><span style="color:#9ECBFF"> ◠</span><span style="color:#9ECBFF">  Let&#x27;s build something fast!</span></span>
<span class="line" data-line=""><span style="color:#9ECBFF">╰─────╯</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#9ECBFF"> astro   v2.2.1 Launch sequence initiated.</span></span></code></pre></figure>
<ol start="2">
<li>プロジェクト名を入力する</li>
</ol>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="shell" data-theme="github-dark"><code data-language="shell" data-theme="github-dark" style="display:grid"><span class="line" data-line=""><span style="color:#B392F0">   dir</span><span style="color:#9ECBFF">   Where</span><span style="color:#9ECBFF"> should</span><span style="color:#9ECBFF"> we</span><span style="color:#9ECBFF"> create</span><span style="color:#9ECBFF"> your</span><span style="color:#9ECBFF"> new</span><span style="color:#9ECBFF"> project?</span></span>
<span class="line" data-line=""><span style="color:#B392F0">         ./dev</span></span></code></pre></figure>
<ol start="3">
<li>テンプレートを選択する</li>
</ol>
<p>今回の用途に沿うようブログのテンプレートを選択します。</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="shell" data-theme="github-dark"><code data-language="shell" data-theme="github-dark" style="display:grid"><span class="line" data-line=""><span style="color:#B392F0">  tmpl</span><span style="color:#9ECBFF">   How</span><span style="color:#9ECBFF"> would</span><span style="color:#9ECBFF"> you</span><span style="color:#9ECBFF"> like</span><span style="color:#9ECBFF"> to</span><span style="color:#9ECBFF"> start</span><span style="color:#9ECBFF"> your</span><span style="color:#9ECBFF"> new</span><span style="color:#9ECBFF"> project?</span></span>
<span class="line" data-line=""><span style="color:#B392F0">         ○</span><span style="color:#9ECBFF"> Include</span><span style="color:#9ECBFF"> sample</span><span style="color:#9ECBFF"> files</span></span>
<span class="line" data-line=""><span style="color:#B392F0">         ●</span><span style="color:#9ECBFF"> Use</span><span style="color:#9ECBFF"> blog</span><span style="color:#9ECBFF"> template</span></span>
<span class="line" data-line=""><span style="color:#B392F0">         ○</span><span style="color:#9ECBFF"> Empty</span></span></code></pre></figure>
<p>次のリポジトリがテンプレートとして採用されています。</p>
<p><a href="https://github.com/Charca/astro-blog-template" rel="nofollow" target="_blank">Charca / astro-blog-template</a></p>
<ol start="4">
<li>依存ライブラリのインストール有無を選択する</li>
</ol>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="shell" data-theme="github-dark"><code data-language="shell" data-theme="github-dark" style="display:grid"><span class="line" data-line=""><span style="color:#B392F0">  deps</span><span style="color:#9ECBFF">   Install</span><span style="color:#9ECBFF"> dependencies?</span><span style="color:#E1E4E8"> (recommended)</span></span>
<span class="line" data-line=""><span style="color:#B392F0">         ●</span><span style="color:#9ECBFF"> Yes</span><span style="color:#9ECBFF">  ○</span><span style="color:#9ECBFF"> No</span></span></code></pre></figure>
<ol start="5">
<li>TypeScript の利用有無を選択する</li>
</ol>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="shell" data-theme="github-dark"><code data-language="shell" data-theme="github-dark" style="display:grid"><span class="line" data-line=""><span style="color:#B392F0">    ts</span><span style="color:#9ECBFF">   Do</span><span style="color:#9ECBFF"> you</span><span style="color:#9ECBFF"> plan</span><span style="color:#9ECBFF"> to</span><span style="color:#9ECBFF"> write</span><span style="color:#9ECBFF"> TypeScript?</span></span>
<span class="line" data-line=""><span style="color:#B392F0">         Yes</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#B392F0">   use</span><span style="color:#9ECBFF">   How</span><span style="color:#9ECBFF"> strict</span><span style="color:#9ECBFF"> should</span><span style="color:#9ECBFF"> TypeScript</span><span style="color:#9ECBFF"> be?</span></span>
<span class="line" data-line=""><span style="color:#B392F0">         ●</span><span style="color:#9ECBFF"> Strict</span><span style="color:#E1E4E8"> (recommended)</span></span>
<span class="line" data-line=""><span style="color:#B392F0">         ○</span><span style="color:#9ECBFF"> Strictest</span></span>
<span class="line" data-line=""><span style="color:#B392F0">         ○</span><span style="color:#9ECBFF"> Relaxed</span></span></code></pre></figure>
<p>推奨されているとおりに strict モードを選択します。</p>
<ol start="6">
<li>Git リポジトリを作成有無を選択する</li>
</ol>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="shell" data-theme="github-dark"><code data-language="shell" data-theme="github-dark" style="display:grid"><span class="line" data-line=""><span style="color:#B392F0">   git</span><span style="color:#9ECBFF">   Initialize</span><span style="color:#9ECBFF"> a</span><span style="color:#9ECBFF"> new</span><span style="color:#9ECBFF"> git</span><span style="color:#9ECBFF"> repository?</span><span style="color:#E1E4E8"> (optional)</span></span>
<span class="line" data-line=""><span style="color:#B392F0">         ○</span><span style="color:#9ECBFF"> Yes</span><span style="color:#9ECBFF">  ●</span><span style="color:#9ECBFF"> No</span></span></code></pre></figure>
<p>これで新規の Astro プロジェクトが作成されました。
<code>pnpm dev</code> コマンドでサーバーを立ち上げることができます。</p>
<p><img src="/2023-04-09-00-53-17.png" alt=""/></p>
<h2 id="今後やりたいこと"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#今後やりたいこと"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>今後やりたいこと</h2>
<p>すでに TailwindCSS への変更やダークモード対応、下書き機能の追加や markuplint の追加等は実施しましたが、他にも <a href="https://github.com/reona5/dev/issues" rel="nofollow" target="_blank">issue</a> に起票して機能追加を実施していく予定です。</p>]]></content:encoded></item><item><title><![CDATA[True color 対応]]></title><description><![CDATA[情報が混在しており、定期的に対応に追われ結構な時間を使うので備忘録。]]></description><link>https://reona.dev/posts/20220205</link><guid isPermaLink="false">/posts/20220205</guid><category><![CDATA[tmux]]></category><pubDate>Sat, 05 Feb 2022 08:54:59 GMT</pubDate><content:encoded><![CDATA[<p>情報が混在しており、定期的に対応に追われ結構な時間を使うので備忘録。</p>
<h2 id="結論"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#結論"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>結論</h2>
<p>次の issue にある設定を行なう。
<a href="https://github.com/tmux/tmux/issues/1246" rel="nofollow" target="_blank">How to use true colors in vim under tmux? #1246</a></p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="vim" data-theme="github-dark"><code data-language="vim" data-theme="github-dark" style="display:grid"><span class="line" data-line=""><span style="color:#6A737D">&quot; 1. Edit .tmux.conf</span></span>
<span class="line" data-line=""><span style="color:#F97583">set</span><span style="color:#E1E4E8"> -g default-terminal</span></span>
<span class="line" data-line=""><span style="color:#F97583">  - </span><span style="color:#E1E4E8">tmux-256color</span></span>
<span class="line" data-line=""><span style="color:#F97583">set</span><span style="color:#E1E4E8"> -ga terminal-overrides</span></span>
<span class="line" data-line=""><span style="color:#F97583">  - </span><span style="color:#E1E4E8">,*256col*:Tc</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#6A737D">&quot; 2. Edit: .vimrc</span></span>
<span class="line" data-line=""><span style="color:#F97583">if</span><span style="color:#B392F0"> exists</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">&#x27;+termguicolors&#x27;</span><span style="color:#E1E4E8">)</span></span>
<span class="line" data-line=""><span style="color:#F97583">  let</span><span style="color:#E1E4E8"> &amp;t_8f </span><span style="color:#F97583">=</span></span>
<span class="line" data-line=""><span style="color:#F97583">  - \</span><span style="color:#E1E4E8">&lt;</span><span style="color:#79B8FF">Esc</span><span style="color:#E1E4E8">&gt;[</span><span style="color:#79B8FF">38</span><span style="color:#E1E4E8">;</span><span style="color:#79B8FF">2</span><span style="color:#E1E4E8">;%lu;%lu;%lum</span></span>
<span class="line" data-line=""><span style="color:#F97583">  let</span><span style="color:#E1E4E8"> &amp;t_8b </span><span style="color:#F97583">=</span></span>
<span class="line" data-line=""><span style="color:#F97583">  - \</span><span style="color:#E1E4E8">&lt;</span><span style="color:#79B8FF">Esc</span><span style="color:#E1E4E8">&gt;[</span><span style="color:#79B8FF">48</span><span style="color:#E1E4E8">;</span><span style="color:#79B8FF">2</span><span style="color:#E1E4E8">;%lu;%lu;%lum</span></span>
<span class="line" data-line=""><span style="color:#F97583">  set</span><span style="color:#79B8FF"> termguicolors</span></span>
<span class="line" data-line=""><span style="color:#F97583">endif</span></span></code></pre></figure>]]></content:encoded></item><item><title><![CDATA[ターミナルエミュレータを iTerm2 から Alacritty に乗り換えた]]></title><description><![CDATA[これまで開発時には iTerm2 を使っていて特段困ることはなかったが、 Neovim での開発時、特にファイルサイズが大きいと少々カクつくことがあるのは気になっていた。 そうは言っても Neovim 利用時に限定しているので、基本的にはプラグインの整理をして対処していたが、 Rust 製でパフォーマンスがよい Alacritty というターミナルエミュレータがあると Twitter でたまたま情報を見かけたので、一度試してみることにした。]]></description><link>https://reona.dev/posts/20210713</link><guid isPermaLink="false">/posts/20210713</guid><category><![CDATA[terminal]]></category><pubDate>Tue, 13 Jul 2021 14:13:37 GMT</pubDate><content:encoded><![CDATA[<link rel="preload" as="image" href="https://user-images.githubusercontent.com/46399968/125487027-3d0142e0-baa5-4d55-839f-458259518e3c.png"/><h2 id="はじめに"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#はじめに"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>はじめに</h2>
<p>これまで開発時には iTerm2 を使っていて特段困ることはなかったが、 Neovim での開発時、特にファイルサイズが大きいと少々カクつくことがあるのは気になっていた。 そうは言っても Neovim 利用時に限定しているので、基本的にはプラグインの整理をして対処していたが、 Rust 製でパフォーマンスがよい Alacritty というターミナルエミュレータがあると Twitter でたまたま情報を見かけたので、一度試してみることにした。</p>
<p><a href="https://github.com/alacritty/alacritty" rel="nofollow" target="_blank">Alacritty - A fast, cross-platform, OpenGL terminal emulator</a></p>
<h2 id="インストール"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#インストール"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>インストール</h2>
<p><a href="https://github.com/alacritty/alacritty/blob/master/INSTALL.md#manual-installation" rel="nofollow" target="_blank">Manual Installation</a> を見て一通りの設定を行なった。</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="shell" data-theme="github-dark"><code data-language="shell" data-theme="github-dark" style="display:grid"><span class="line" data-line=""><span style="color:#B392F0">git</span><span style="color:#9ECBFF"> clone</span><span style="color:#9ECBFF"> https://github.com/alacritty/alacritty.git</span></span>
<span class="line" data-line=""><span style="color:#79B8FF">cd</span><span style="color:#9ECBFF"> alacritty</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#B392F0">//</span><span style="color:#9ECBFF"> rustup</span><span style="color:#9ECBFF"> をインストール</span></span>
<span class="line" data-line=""><span style="color:#B392F0">curl</span><span style="color:#79B8FF"> --proto</span><span style="color:#9ECBFF"> &#x27;=https&#x27;</span><span style="color:#79B8FF"> --tlsv1.2</span><span style="color:#79B8FF"> -sSf</span><span style="color:#9ECBFF"> https://sh.rustup.rs</span><span style="color:#F97583"> |</span><span style="color:#B392F0"> sh</span></span>
<span class="line" data-line=""><span style="color:#B392F0">rustup</span><span style="color:#9ECBFF"> override</span><span style="color:#9ECBFF"> set</span><span style="color:#9ECBFF"> stable</span></span>
<span class="line" data-line=""><span style="color:#B392F0">rustup</span><span style="color:#9ECBFF"> update</span><span style="color:#9ECBFF"> stable</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#B392F0">//</span><span style="color:#9ECBFF"> MacOS</span><span style="color:#9ECBFF"> の場合</span></span>
<span class="line" data-line=""><span style="color:#B392F0">make</span><span style="color:#9ECBFF"> app</span></span>
<span class="line" data-line=""><span style="color:#B392F0">cp</span><span style="color:#79B8FF"> -r</span><span style="color:#9ECBFF"> target/release/osx/Alacritty.app</span><span style="color:#9ECBFF"> /Applications/</span></span>
<span class="line" data-line=""> </span>
<span class="line" data-line=""><span style="color:#B392F0">infocmp</span><span style="color:#9ECBFF"> alacritty</span></span>
<span class="line" data-line=""><span style="color:#B392F0">sudo</span><span style="color:#9ECBFF"> tic</span><span style="color:#79B8FF"> -xe</span><span style="color:#9ECBFF"> alacritty,alacritty-direct</span><span style="color:#9ECBFF"> extra/alacritty.info</span></span>
<span class="line" data-line=""><span style="color:#B392F0">sudo</span><span style="color:#9ECBFF"> mkdir</span><span style="color:#79B8FF"> -p</span><span style="color:#9ECBFF"> /usr/local/share/man/man1</span></span>
<span class="line" data-line=""><span style="color:#B392F0">gzip</span><span style="color:#79B8FF"> -c</span><span style="color:#9ECBFF"> extra/alacritty.man</span><span style="color:#F97583"> |</span><span style="color:#B392F0"> sudo</span><span style="color:#9ECBFF"> tee</span><span style="color:#9ECBFF"> /usr/local/share/man/man1/alacritty.1.gz</span><span style="color:#F97583"> &gt;</span><span style="color:#9ECBFF"> /dev/null</span></span></code></pre></figure>
<p>shell ごとに補完機能のインストール手順が最下部に書いてあるので、そちらも実行。</p>
<h3 id="つまづいた点"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#つまづいた点"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>つまづいた点</h3>
<p>tmux の prefix を Ctrl + q に設定しているのだが、反応せず。
ctrl + q を 2 回押すと tmux のキーバインドが反応したが、ピンポイントで Alacritty の Issue が挙がっていたのでこちらを参考に key_bindings を設定することで対応。</p>
<p><a href="https://github.com/alacritty/alacritty/issues/1359" rel="nofollow" target="_blank">Ctrl+q not working #1359</a></p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#24292e;color:#e1e4e8" tabindex="0" data-language="yaml" data-theme="github-dark"><code data-language="yaml" data-theme="github-dark" style="display:grid"><span class="line" data-line=""><span style="color:#E1E4E8">- { </span><span style="color:#85E89D">key</span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">Q</span><span style="color:#E1E4E8">, </span><span style="color:#85E89D">mods</span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">Control</span><span style="color:#E1E4E8">, </span><span style="color:#85E89D">chars</span><span style="color:#E1E4E8">: - </span><span style="color:#9ECBFF">\x11</span><span style="color:#E1E4E8"> }</span></span></code></pre></figure>
<h2 id="メリット"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#メリット"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>メリット</h2>
<ul>
<li>開発が活発に行なわされている印象</li>
</ul>
<p>メインのターミナルエミュレータにする上で、放置されているようなプロダクトは使いたくないので、この点に関しては非常に好印象。</p>
<ul>
<li>OS 間で互換性がある</li>
</ul>
<p><a href="https://iterm2.com/" rel="nofollow" target="_blank">iTerm2 - macOS Terminal Replacement</a></p>
<p>iTerm2 は MacOS 用のソフトウェアであるため、Linux であったり Windows 環境では使うことはできない。特にマシンを買い替えて違う OS での開発に主軸を置く予定はないが、いつ違う OS で検証が必要になるかなんてわからないし、互換性があるに越したことはない。</p>
<ul>
<li>alacritty.yml に設定をまとめることができる</li>
</ul>
<p>設定ファイルを yaml 形式で保管できるのは個人的には大きなメリット。互換性のメリットにも通ずるが、config 系のファイルは <a href="https://github.com/reona5/dotfiles" rel="nofollow" target="_blank">reona5/dotfiles</a> にまとめているので、マシンが変わってもコマンド 1 つで開発環境を再現できるのは嬉しいポイント。</p>
<ul>
<li>iTerm2 よりかなり速い</li>
</ul>
<p>割とこれはすぐに実感できるレベルで違いがわかる。 fzf のファイル検索とか ag でまだもたつきは感じるので、 Neovim のプラグイン周りで改善の余地がありそう。（この辺のベストプラクティスというか、他の人がどう管理してるか見てみたい）</p>
<h2 id="デメリット"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#デメリット"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>デメリット</h2>
<ul>
<li>機能が限定的である</li>
</ul>
<p>これは速さとトレードオフなポイントではあると思う。私の場合は、もともとタブやペインなどを Neovim + tmux で完結させていたので全く問題なかった。</p>
<ul>
<li>日本語入力のインライン入力ができない</li>
</ul>
<p>日本語を入力する際にインライン入力ができないので、google 日本語入力の補完候補はでるので使えなくはないが、かなり違和感がある。
ミスタイプをした際に delete キーを押すと、入力中の文字でなくその前の文字が消えてしまうので、ミスタイプが多い人はかなり大変だと思う。邪道ではあるが、私は Neovim の設定で emacs のキーバインドを有効にしているので ctrl + h で文字を削除することで入力中の文字を削除できた（普段 delete の方がよく使うので、慣れないといけない）</p>
<ul>
<li>日本語の表示がバグることがある</li>
</ul>
<p>これも致命的ではないけど結構気になる。Twitter とか見てるとインライン入力も含めて問題になってるみたい。</p>
<h2 id="最後に"><a class="headings-anchor-link" aria-hidden="true" tabindex="-1" href="#最後に"><svg fill="none" viewBox="0 0 24 24" width="16" height="16" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"></path></svg></a>最後に</h2>
<p>ターミナルエミュレータを変更したついでに colorscheme や font も変更した。</p>
<p>colorscheme: <a href="https://github.com/morhetz/gruvbox" rel="nofollow" target="_blank">morhetz/gruvbox</a> -&gt; <a href="https://www.nordtheme.com/" rel="nofollow" target="_blank">Nord</a></p>
<p>font: <a href="https://rictyfonts.github.io/" rel="nofollow" target="_blank">Ricty</a> -&gt; <a href="https://www.nerdfonts.com/font-downloads" rel="nofollow" target="_blank">JetBrainsMono Nerd Font</a></p>
<p><img src="https://user-images.githubusercontent.com/46399968/125487027-3d0142e0-baa5-4d55-839f-458259518e3c.png" alt="image"/></p>
<p>Nord は tmux, Alacritty, Vim それぞれのライブラリが用意されているので、統一感が出せて非常に気に入っている。</p>]]></content:encoded></item></channel></rss>