<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://blog.o3osatoshi.engr.work/feed.xml" rel="self" type="application/atom+xml" /><link href="https://blog.o3osatoshi.engr.work/" rel="alternate" type="text/html" /><updated>2026-02-02T14:09:56+00:00</updated><id>https://blog.o3osatoshi.engr.work/feed.xml</id><title type="html">o3osatoshi blog</title><entry><title type="html">Google Cloud Workload Identity 設定備忘録</title><link href="https://blog.o3osatoshi.engr.work/tech/conf/google-cloud-workload-identity" rel="alternate" type="text/html" title="Google Cloud Workload Identity 設定備忘録" /><published>2025-11-03T15:00:00+00:00</published><updated>2025-11-03T15:00:00+00:00</updated><id>https://blog.o3osatoshi.engr.work/tech/conf/google-cloud-workload-identity</id><content type="html" xml:base="https://blog.o3osatoshi.engr.work/tech/conf/google-cloud-workload-identity"><![CDATA[<p><img src="/assets/2025-11-04-google-cloud-workload-identity/thumbnail.png" alt="thumbnail" /></p>

<p>※本ブログの目的と内容<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup>、読者の方へ<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote" rel="footnote">2</a></sup></p>

<h2 id="概要">概要</h2>

<h3 id="workload-identityとは何か">Workload Identityとは何か</h3>
<p>Google CloudのWorkload Identity連携（Workload Identity Federation: WIF）は、外部IDプロバイダ（OIDC/SAML）が発行する短期トークンをGoogle CloudのSecurity Token Service（STS）で交換し、サービスアカウントの一時的な資格情報として利用する仕組み。<br />
サービスアカウント鍵を配布・保管せずに、GitHub ActionsなどのCI/CDや他クラウド・オンプレ環境から安全にGCPへアクセスできる。</p>

<h3 id="workload-identityのメリットデメリット">Workload Identityのメリット・デメリット</h3>
<h4 id="メリット">メリット</h4>
<ul>
  <li>サービスアカウント鍵の廃止（キーレス）で漏えいリスクを低減</li>
  <li>短命なトークンを都度発行・自動ローテーションし、運用負荷と影響範囲を最小化</li>
  <li>最小権限の原則を徹底（SA権限は最小限、紐付けは属性条件でリポジトリ/ブランチ単位に制限）</li>
  <li>監査性の向上（IAM監査ログとOIDCクレームで誰が何を実行したか追跡しやすい）</li>
  <li>マルチ環境対応（他クラウドやオンプレ、複数CIから安全に利用可能）</li>
</ul>

<h4 id="デメリット">デメリット</h4>
<ul>
  <li>初期設定がやや複雑（プール/プロバイダ、属性マッピングと条件式、バインディング設計）</li>
  <li>トラブルシュートに知識が必要（クレーム不一致、<code class="language-plaintext highlighter-rouge">aud</code>/<code class="language-plaintext highlighter-rouge">sub</code>、時刻ずれ、ロール不足）</li>
  <li>一部の古いツール/SDKでは対応が不十分な場合がある</li>
  <li>トークン有効期限の制約により長時間ジョブは再認証の考慮が必要</li>
</ul>

<h3 id="参考リンク">参考リンク</h3>

<ul>
  <li><a href="https://cloud.google.com/iam/docs/workload-identity-federation-with-deployment-pipelines?hl=ja#github-actions_2">デプロイメント パイプラインとの Workload Identity 連携を構成する</a></li>
  <li><a href="https://docs.github.com/en/actions/how-tos/secure-your-work/security-harden-deployments/oidc-in-google-cloud-platform">Configuring OpenID Connect in Google Cloud Platform</a></li>
  <li><a href="https://github.com/google-github-actions/auth#direct-wif">Authenticate to Google Cloud from GitHub Actions</a></li>
</ul>

<h2 id="workload-identity">Workload Identity</h2>
<p><code class="language-plaintext highlighter-rouge">Google Cloud Console &gt; IAMと管理 &gt; Workload Identity 連携</code> で以下の設定を行う。</p>

<h3 id="プール作成">プール作成</h3>

<h5 id="名前">名前</h5>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>GitHub
</code></pre></div></div>

<h5 id="プールid">プールID</h5>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>github
</code></pre></div></div>

<h3 id="プロバイダ作成">プロバイダ作成</h3>

<h5 id="名前-1">名前</h5>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>GitHub
</code></pre></div></div>

<h5 id="プロバイダid">プロバイダID</h5>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>github
</code></pre></div></div>

<h5 id="発行元url">発行元（URL）</h5>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://token.actions.githubusercontent.com
</code></pre></div></div>

<h5 id="jwkファイルjson">JWKファイル（JSON）</h5>
<p>ブランク</p>

<h5 id="オーディエンス">オーディエンス</h5>
<p>デフォルト</p>

<h5 id="属性のマッピング">属性のマッピング</h5>

<table>
  <thead>
    <tr>
      <th style="text-align: left">Google</th>
      <th style="text-align: left">OIDC</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">google.subject</code></td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">assertion.sub</code></td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">attribute.actor</code></td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">assertion.actor</code></td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">attribute.environment</code></td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">assertion.environment</code></td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">attribute.sha</code></td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">assertion.sha</code></td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">attribute.ref</code></td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">assertion.ref</code></td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">attribute.ref_type</code></td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">assertion.ref_type</code></td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">attribute.repository</code></td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">assertion.repository</code></td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">attribute.repository_owner</code></td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">assertion.repository_owner</code></td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">attribute.workflow</code></td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">assertion.workflow</code></td>
    </tr>
  </tbody>
</table>

<h5 id="属性条件">属性条件</h5>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>attribute.repository == "{ owner }/{ repo }"
</code></pre></div></div>

<h2 id="service-account">Service Account</h2>
<p><code class="language-plaintext highlighter-rouge">Google Cloud Console &gt; IAMと管理 &gt; サービス アカウント</code> で以下の設定を行う。</p>

<h3 id="サービスアカウント作成">サービスアカウント作成</h3>

<h5 id="名前-2">名前</h5>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>GitHub Actions
</code></pre></div></div>

<h5 id="サービスアカウントid">サービスアカウントID</h5>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>github-actions
</code></pre></div></div>

<h5 id="権限">権限</h5>
<p>デプロイ対象に応じて権限を変更する。以下は <code class="language-plaintext highlighter-rouge">functions</code> をデプロイする場合。</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Cloud Functions 開発者
Service Usage ユーザー
閲覧者
</code></pre></div></div>

<h5 id="アクセス権を持つプリンシパル">アクセス権を持つプリンシパル</h5>
<p>プリンシパル</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>principalSet://iam.googleapis.com/projects/{ project }/locations/global/workloadIdentityPools/github/attribute.repository/{ owner }/{ repo }
</code></pre></div></div>

<p>ロール</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Workload Identity ユーザー
</code></pre></div></div>

<h3 id="プリンシパル追加">プリンシパル追加</h3>

<h4 id="app-engine-default-service-account">App Engine default service account</h4>

<h5 id="アクセス権を持つプリンシパル-1">アクセス権を持つプリンシパル</h5>
<p>プリンシパル</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>github-actions@{ your-project-id }.iam.gserviceaccount.com
</code></pre></div></div>

<p>ロール</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>サービス アカウント ユーザー
</code></pre></div></div>

<h4 id="default-compute-service-account">Default compute service account</h4>

<h5 id="アクセス権を持つプリンシパル-2">アクセス権を持つプリンシパル</h5>
<p>プリンシパル</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>github-actions@{ your-project-id }.iam.gserviceaccount.com
</code></pre></div></div>

<p>ロール</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>サービス アカウント ユーザー
</code></pre></div></div>

<h2 id="github-actions">GitHub Actions</h2>
<p>以下のステップをデプロイ直前に追加する。</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="pi">-</span> <span class="na">id</span><span class="pi">:</span> <span class="s">auth</span>
  <span class="na">name</span><span class="pi">:</span> <span class="s">Authenticate to GCP (OIDC)</span>
  <span class="na">uses</span><span class="pi">:</span> <span class="s">google-github-actions/auth@v3</span>
  <span class="na">with</span><span class="pi">:</span>
    <span class="na">create_credentials_file</span><span class="pi">:</span> <span class="no">true</span>
    <span class="na">workload_identity_provider</span><span class="pi">:</span> <span class="s">projects/{ project }/locations/global/workloadIdentityPools/{ pool }/providers/{ provider }</span>
    <span class="na">service_account</span><span class="pi">:</span> <span class="s">github-actions@{ your-project-id }.iam.gserviceaccount.com</span>

<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">gcloud auth login</span>
  <span class="na">run</span><span class="pi">:</span> <span class="s">gcloud auth login --brief --cred-file="${ steps.auth.outputs.credentials_file_path }"</span>
</code></pre></div></div>
<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1" role="doc-endnote">
      <p>本ブログは「技術的自由研究の備忘録」を目的としている。ソースコードは <a href="https://github.com/o3osatoshi/portfolio">GitHubリポジトリ</a> に公開している <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2" role="doc-endnote">
      <p>お気づきの点や改善案があれば、遠慮なくお知らせいただきたい。ご意見やご感想を歓迎します <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name></name></author><category term="tech" /><category term="conf" /><category term="coding" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Deep TypeScript</title><link href="https://blog.o3osatoshi.engr.work/tech/lang/deep-typescript" rel="alternate" type="text/html" title="Deep TypeScript" /><published>2025-10-03T15:00:00+00:00</published><updated>2025-10-03T15:00:00+00:00</updated><id>https://blog.o3osatoshi.engr.work/tech/lang/deep-typescript</id><content type="html" xml:base="https://blog.o3osatoshi.engr.work/tech/lang/deep-typescript"><![CDATA[<p><img src="/assets/2025-10-04-deep-typescript/thumbnail.png" alt="thumbnail" /></p>

<h2 id="prototype">prototype</h2>
<p>JavaScriptは<strong>プロトタイプベース</strong>の言語。別のオブジェクト（＝プロトタイプ）を参照して性質を引き継ぐ。
あるオブジェクトにプロパティやメソッドが見つからなければ、プロトタイプをたどって探す。
prototypeに定義された関数はインスタンス間で共有され、メモリ効率も良い。</p>

<h3 id="サンプル">サンプル</h3>
<p><a href="####class構文">class構文</a>の実態は<a href="####prototype構文">prototype構文</a>である。</p>

<h4 id="class構文">class構文</h4>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">Animal</span> <span class="p">{</span>
  <span class="kd">constructor</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="nx">name</span><span class="p">;</span>
  <span class="p">}</span>
  
  <span class="nx">speak</span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">`</span><span class="p">${</span><span class="k">this</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2"> makes a sound`</span><span class="p">);</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">Dog</span> <span class="kd">extends</span> <span class="nx">Animal</span> <span class="p">{</span>
  <span class="kd">constructor</span><span class="p">(</span><span class="nx">name</span><span class="p">,</span> <span class="nx">breed</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">super</span><span class="p">(</span><span class="nx">name</span><span class="p">);</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">breed</span> <span class="o">=</span> <span class="nx">breed</span><span class="p">;</span>
  <span class="p">}</span>
  
  <span class="nx">bark</span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">`</span><span class="p">${</span><span class="k">this</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2"> barks!`</span><span class="p">);</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h4 id="prototype構文">prototype構文</h4>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">Animal</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">this</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="nx">name</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">Animal</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">speak</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">name</span> <span class="o">+</span> <span class="dl">"</span><span class="s2"> makes a sound</span><span class="dl">"</span><span class="p">);</span>
<span class="p">};</span>

<span class="c1">// Animal 概念</span>
<span class="cm">/*
  [[Prototype]]: Function.prototype,
  [[Call]]: (thisArg, [name]) =&gt; {
    // Animal("Pochi")
    thisArg.name = name;
    return undefined;
  },
  [[Construct]]: ([name], newTarget) =&gt; {
    // new Animal("Pochi")
    const obj = OrdinaryCreateFromConstructor(newTarget, Animal.prototype);
    Animal.[[Call]](obj, [name]);
    return obj;
  },
  prototype: {
    [[Prototype]]: Object.prototype,
    constructor: Animal,
    speak: function() {
      console.log(this.name + " makes a sound");
    }
  },
  name: "Animal",
  length: 1 // 仮引数の数（name）
*/</span>
</code></pre></div></div>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">Dog</span><span class="p">(</span><span class="nx">name</span><span class="p">,</span> <span class="nx">breed</span><span class="p">)</span> <span class="p">{</span>
  <span class="nx">Animal</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">name</span><span class="p">);</span>
  <span class="k">this</span><span class="p">.</span><span class="nx">breed</span> <span class="o">=</span> <span class="nx">breed</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">Dog</span><span class="p">.</span><span class="nx">prototype</span> <span class="o">=</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="nx">Animal</span><span class="p">.</span><span class="nx">prototype</span><span class="p">);</span>
<span class="nx">Dog</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="kd">constructor</span> <span class="o">=</span> <span class="nx">Dog</span><span class="p">;</span>
<span class="nx">Dog</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">bark</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">name</span> <span class="o">+</span> <span class="dl">"</span><span class="s2"> barks!</span><span class="dl">"</span><span class="p">);</span>
<span class="p">};</span>

<span class="c1">// Dog 概念</span>
<span class="cm">/*
  [[Prototype]]: Function.prototype,
  [[Call]]: (thisArg, [name, breed]) =&gt; {
    // Dog("Pochi", "Shiba")
    Animal.[[Call]](thisArg, [name]);
    thisArg.breed = breed;
    return undefined;
  },
  [[Construct]]: ([name, breed], newTarget) =&gt; {
    // new Dog("Pochi", "Shiba")
    obj = OrdinaryCreateFromConstructor(newTarget, "%Object.prototype%", internalProto = Dog.prototype);
    Dog.[[Call]](obj, [name, breed]);
    return obj;
  },
  prototype: {
    [[Prototype]]: Animal.prototype,
    constructor: Dog,
    bark: function() {
      console.log(this.name + " barks!");
    }
  },
  name: "Dog",
  length: 2 // 仮引数の数（name, breed）
*/</span>
</code></pre></div></div>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">dog</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Dog</span><span class="p">(</span><span class="dl">"</span><span class="s2">Pochi</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">Shiba</span><span class="dl">"</span><span class="p">);</span>
<span class="nx">dog</span><span class="p">.</span><span class="nx">speak</span><span class="p">();</span> <span class="c1">// Pochi makes a sound</span>
<span class="nx">dog</span><span class="p">.</span><span class="nx">bark</span><span class="p">();</span>  <span class="c1">// Pochi barks!</span>

<span class="c1">// dog 概念</span>
<span class="cm">/*
  [[Prototype]]: Dog.prototype,
  name: "Pochi",
  breed: "Shiba"
*/</span>

<span class="c1">// dog 全体像</span>
<span class="cm">/*
{
  [[Prototype]]: {
    [[Prototype]]: {
      [[Prototype]]: Object.prototype,
      constructor: Animal,
      speak: [Function: speak]
    },
    constructor: Dog,
    bark: [Function: bark]
  },
  name: "Pochi",
  breed: "Shiba"
};
*/</span>
</code></pre></div></div>

<h3 id="objectgetprototypeof">Object.getPrototypeOf</h3>
<p><code class="language-plaintext highlighter-rouge">prototype</code>を取得する。</p>

<h4 id="インスタンスオブジェクト">インスタンスオブジェクト</h4>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">Object</span><span class="p">.</span><span class="nx">getPrototypeOf</span><span class="p">(</span><span class="nx">dog</span><span class="p">)</span> <span class="o">===</span> <span class="nx">Dog</span><span class="p">.</span><span class="nx">prototype</span><span class="p">;</span>                   <span class="c1">// true</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">getPrototypeOf</span><span class="p">(</span><span class="nx">Dog</span><span class="p">.</span><span class="nx">prototype</span><span class="p">)</span> <span class="o">===</span> <span class="nx">Animal</span><span class="p">.</span><span class="nx">prototype</span><span class="p">;</span>      <span class="c1">// true</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">getPrototypeOf</span><span class="p">(</span><span class="nx">Animal</span><span class="p">.</span><span class="nx">prototype</span><span class="p">)</span> <span class="o">===</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">prototype</span><span class="p">;</span>   <span class="c1">// true</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">getPrototypeOf</span><span class="p">(</span><span class="nb">Object</span><span class="p">.</span><span class="nx">prototype</span><span class="p">)</span> <span class="o">===</span> <span class="kc">null</span><span class="p">;</span>               <span class="c1">// true</span>
</code></pre></div></div>

<h4 id="コンストラクタオブジェクト">コンストラクタオブジェクト</h4>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">Object</span><span class="p">.</span><span class="nx">getPrototypeOf</span><span class="p">(</span><span class="nx">Dog</span><span class="p">)</span> <span class="o">===</span> <span class="nb">Function</span><span class="p">.</span><span class="nx">prototype</span><span class="p">;</span>              <span class="c1">// true</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">getPrototypeOf</span><span class="p">(</span><span class="nb">Function</span><span class="p">.</span><span class="nx">prototype</span><span class="p">)</span> <span class="o">===</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">prototype</span><span class="p">;</span> <span class="c1">// true</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">getPrototypeOf</span><span class="p">(</span><span class="nb">Object</span><span class="p">.</span><span class="nx">prototype</span><span class="p">)</span> <span class="o">===</span> <span class="kc">null</span><span class="p">;</span>               <span class="c1">// true</span>
</code></pre></div></div>

<h3 id="instanceof">instanceof</h3>
<p>インスタンスオブジェクトが特定のコンストラクタオブジェクトから生成されたかどうかを判定する演算子。</p>

<h4 id="サンプル-1">サンプル</h4>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">dog</span> <span class="k">instanceof</span> <span class="nx">Dog</span><span class="p">;</span>       <span class="c1">// true</span>
<span class="nx">dog</span> <span class="k">instanceof</span> <span class="nx">Animal</span><span class="p">;</span>    <span class="c1">// true</span>
<span class="nx">dog</span> <span class="k">instanceof</span> <span class="nb">Object</span><span class="p">;</span>    <span class="c1">// true</span>
</code></pre></div></div>

<h4 id="内部処理イメージ">内部処理イメージ</h4>
<p>プロトタイプチェーンをたどって判定。</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">instanceOf</span><span class="p">(</span><span class="nx">left</span><span class="p">,</span> <span class="nx">right</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">proto</span> <span class="o">=</span> <span class="nx">right</span><span class="p">?.</span><span class="nx">prototype</span><span class="p">;</span>
  <span class="kd">let</span> <span class="nx">cur</span> <span class="o">=</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">getPrototypeOf</span><span class="p">(</span><span class="nx">left</span><span class="p">);</span>
  <span class="k">while</span> <span class="p">(</span><span class="nx">cur</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">cur</span> <span class="o">===</span> <span class="nx">proto</span><span class="p">)</span> <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
    <span class="nx">cur</span> <span class="o">=</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">getPrototypeOf</span><span class="p">(</span><span class="nx">cur</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="this">this</h2>

<h3 id="種類">種類</h3>

<h5 id="デフォルトバインディング">デフォルトバインディング</h5>
<p>this → strict: <code class="language-plaintext highlighter-rouge">undefined</code> / 非strict: <code class="language-plaintext highlighter-rouge">window</code>（または <code class="language-plaintext highlighter-rouge">global</code>）</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">showMessage</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="k">this</span><span class="p">?.</span><span class="nx">message</span> <span class="o">||</span> <span class="dl">"</span><span class="s2">no this</span><span class="dl">"</span><span class="p">);</span>
<span class="p">}</span>
<span class="kd">const</span> <span class="nx">message</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">global</span><span class="dl">"</span><span class="p">;</span>
<span class="nx">showMessage</span><span class="p">();</span> <span class="c1">// strict: no this / 非strict: global</span>
</code></pre></div></div>

<h5 id="暗黙的バインディング">暗黙的バインディング</h5>
<p>this → 呼び出し元のオブジェクト</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">user</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Alice</span><span class="dl">"</span><span class="p">,</span>
  <span class="nx">greet</span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">`Hello, I'm </span><span class="p">${</span><span class="k">this</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
  <span class="p">}</span>
<span class="p">};</span>
<span class="nx">user</span><span class="p">.</span><span class="nx">greet</span><span class="p">();</span> <span class="c1">// "Hello, I'm Alice"</span>
</code></pre></div></div>

<h5 id="明示的バインディング">明示的バインディング</h5>
<p>this → call / apply / bind の第1引数</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">introduce</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">`I'm </span><span class="p">${</span><span class="k">this</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2">, </span><span class="p">${</span><span class="k">this</span><span class="p">.</span><span class="nx">age</span><span class="p">}</span><span class="s2"> years old.`</span><span class="p">);</span>
<span class="p">}</span>
<span class="kd">const</span> <span class="nx">person</span> <span class="o">=</span> <span class="p">{</span> <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Bob</span><span class="dl">"</span><span class="p">,</span> <span class="na">age</span><span class="p">:</span> <span class="mi">25</span> <span class="p">};</span>
<span class="nx">introduce</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">person</span><span class="p">);</span> <span class="c1">// "I'm Bob, 25 years old."</span>
</code></pre></div></div>

<h5 id="コンストラクタ呼び出し暗黙的バインディングの一種">コンストラクタ呼び出し（暗黙的バインディングの一種）</h5>
<p>this → 新しく生成されたオブジェクト<br />
※以下の例では <code class="language-plaintext highlighter-rouge">increment</code> がインスタンスごとに生成されるため、メモリ効率が悪い。通常は <code class="language-plaintext highlighter-rouge">Counter.prototype</code> に定義する</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">Counter</span><span class="p">()</span> <span class="p">{</span>
  <span class="k">this</span><span class="p">.</span><span class="nx">count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
  <span class="k">this</span><span class="p">.</span><span class="nx">increment</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">count</span><span class="o">++</span><span class="p">;</span>
    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">count</span><span class="p">);</span>
  <span class="p">};</span>
<span class="p">}</span>
<span class="kd">const</span> <span class="nx">c</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Counter</span><span class="p">();</span>
<span class="nx">c</span><span class="p">.</span><span class="nx">increment</span><span class="p">();</span> <span class="c1">// 1</span>

<span class="c1">// c 概念</span>
<span class="cm">/*
  [[Prototype]]: Counter.prototype,
  count: 0,
  increment: function() {
    this.count++;
    console.log(this.count);
  }
*/</span>

<span class="c1">// c 全体像</span>
<span class="cm">/*
  [[Prototype]]: {
    [[Prototype]]: Object.prototype,
    constructor: Counter,
  },
  count: 0,
  increment: function() {
    this.count++;
    console.log(this.count);
  }
*/</span>
</code></pre></div></div>

<h5 id="クラスのインスタンスメソッド暗黙的バインディングの一種">クラスのインスタンスメソッド（暗黙的バインディングの一種）</h5>
<p>this → そのクラスのインスタンス<br />
※詳しい仕組みは <a href="##prototype">prototype</a> や <a href="###Array">Array</a> 参照のこと</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">Player</span> <span class="p">{</span>
  <span class="kd">constructor</span><span class="p">(</span><span class="nx">name</span><span class="p">:</span> <span class="kr">string</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="nx">name</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">hp</span> <span class="o">=</span> <span class="mi">100</span><span class="p">;</span>
  <span class="p">}</span>
  <span class="nx">attack</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">hp</span> <span class="o">-=</span> <span class="mi">10</span><span class="p">;</span>
    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">`</span><span class="p">${</span><span class="k">this</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2"> attacked! HP: </span><span class="p">${</span><span class="k">this</span><span class="p">.</span><span class="nx">hp</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
  <span class="p">}</span>
<span class="p">}</span>
<span class="kd">const</span> <span class="nx">p</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Player</span><span class="p">(</span><span class="dl">"</span><span class="s2">Rin</span><span class="dl">"</span><span class="p">);</span>
<span class="nx">p</span><span class="p">.</span><span class="nx">attack</span><span class="p">();</span> <span class="c1">// "Rin attacked! HP: 90"</span>
</code></pre></div></div>

<h5 id="アロー関数レキシカル-this">アロー関数（レキシカル this）</h5>
<p>this → 定義されたときの外側スコープの this</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">team</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Red</span><span class="dl">"</span><span class="p">,</span>
  <span class="na">members</span><span class="p">:</span> <span class="p">[</span><span class="dl">"</span><span class="s2">Ken</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">Mia</span><span class="dl">"</span><span class="p">],</span>
  <span class="nx">showMembers</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">members</span><span class="p">.</span><span class="nx">forEach</span><span class="p">(</span><span class="nx">member</span> <span class="o">=&gt;</span> <span class="p">{</span>
      <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">`</span><span class="p">${</span><span class="nx">member</span><span class="p">}</span><span class="s2"> from </span><span class="p">${</span><span class="k">this</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
    <span class="p">});</span>
  <span class="p">}</span>
<span class="p">};</span>
<span class="nx">team</span><span class="p">.</span><span class="nx">showMembers</span><span class="p">();</span> 
<span class="c1">// "Ken from Red", "Mia from Red"</span>
</code></pre></div></div>

<h5 id="dom-イベントハンドラ">DOM イベントハンドラ</h5>
<p>this → イベントを受け取った要素</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">document</span><span class="p">.</span><span class="nx">querySelector</span><span class="p">(</span><span class="dl">"</span><span class="s2">button</span><span class="dl">"</span><span class="p">).</span><span class="nx">addEventListener</span><span class="p">(</span><span class="dl">"</span><span class="s2">click</span><span class="dl">"</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">textContent</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">Clicked!</span><span class="dl">"</span><span class="p">;</span>
    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="k">this</span><span class="p">);</span> <span class="c1">// &lt;button&gt;Clicked!&lt;/button&gt;</span>
<span class="p">});</span>
</code></pre></div></div>

<h3 id="array">Array</h3>
<p>JavaScriptのArrayはオブジェクトであり、ブラケット記法で要素にアクセスする。
<code class="language-plaintext highlighter-rouge">push</code>や<code class="language-plaintext highlighter-rouge">pop</code>はArrayオブジェクトのメソッドであり、<strong>暗黙的バインディング</strong>により<code class="language-plaintext highlighter-rouge">this</code>は配列オブジェクトを指す。</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">arr</span> <span class="o">=</span> <span class="p">[</span><span class="mi">10</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="mi">30</span><span class="p">];</span>
<span class="nx">arr</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="mi">40</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">arr</span><span class="p">[</span><span class="mi">3</span><span class="p">]);</span> <span class="c1">// 40</span>

<span class="c1">// Array 概念</span>
<span class="cm">/*
  [[Prototype]]: Array.prototype,
  0: 10,
  1: 20,
  2: 30,
  length: 3,
*/</span>

<span class="c1">// Array 全体像</span>
<span class="cm">/*
  [[Prototype]]: {
    push: function(...items) {
      let len = this.length &gt;&gt;&gt; 0;
      for (let i = 0; i &lt; items.length; i++) {
        this[len] = items[i];
        len++;
      }
      this.length = len;
      return len;
    },
    pop: function() {
      let len = this.length &gt;&gt;&gt; 0;
      len--;
      const value = this[len];
      delete this[len];
      this.length = len;
      return value;
    }
  },
  0: 10,
  1: 20,
  2: 30,
  length: 3,
*/</span>
</code></pre></div></div>

<h2 id="closure">closure</h2>
<p>外部の変数情報を保持した関数のこと。
外部の変数情報は<strong>レキシカル環境</strong>に保持される。</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">createAdder</span><span class="p">(</span><span class="nx">a</span><span class="p">:</span> <span class="kr">number</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">return</span> <span class="kd">function</span> <span class="nx">add</span><span class="p">(</span><span class="nx">b</span><span class="p">:</span> <span class="kr">number</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">sum</span> <span class="o">=</span> <span class="nx">a</span> <span class="o">+</span> <span class="nx">b</span><span class="p">;</span>
    <span class="k">return</span> <span class="nx">sum</span><span class="p">;</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// createAdder 概念</span>
<span class="cm">/*
  [[Prototype]]: Function.prototype,
  [[Call]]: (thisArg, [a]) =&gt; {
    // createAdder(2)
    const add = function add(b) {
      const sum = a + b;
      return sum;
    };
    return add;
  },
  prototype: { constructor: createAdder },
  name: "createAdder",
  length: 1
*/</span>
</code></pre></div></div>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">addTo2</span> <span class="o">=</span> <span class="nx">createAdder</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>
<span class="nx">addTo2</span><span class="p">(</span><span class="mi">5</span><span class="p">);</span> <span class="c1">// 7</span>

<span class="c1">// addTo2 概念</span>
<span class="cm">/*
  [[Prototype]]: Function.prototype,
  [[Call]]: (thisArg, [b]) =&gt; {
    // addTo2(5)
    const sum = [[Environment]].a + b; // 2 + 5
    return sum;
  },
  [[Environment]]: {
    // 実行時のレキシカル環境
    a: 2,             // 環境レコード
    outer: GlobalEnv  // 外側のレキシカル環境への参照
  },
  name: "add",
  length: 1
*/</span>
</code></pre></div></div>

<h2 id="asynchronous">asynchronous</h2>

<h3 id="promise">Promise</h3>
<p>「未来の結果を入れる箱」を作る。
<code class="language-plaintext highlighter-rouge">resolve()</code> が呼ばれると「成功」状態に、 <code class="language-plaintext highlighter-rouge">reject()</code> が呼ばれると「失敗」状態になる。</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">promise</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Promise</span><span class="p">((</span><span class="nx">resolve</span><span class="p">,</span> <span class="nx">reject</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="k">if</span> <span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">&lt;</span> <span class="mf">0.5</span><span class="p">)</span> <span class="nx">resolve</span><span class="p">(</span><span class="dl">"</span><span class="s2">成功しました</span><span class="dl">"</span><span class="p">);</span>
  <span class="k">else</span> <span class="nx">reject</span><span class="p">(</span><span class="dl">"</span><span class="s2">失敗しました</span><span class="dl">"</span><span class="p">);</span>
<span class="p">});</span>

<span class="nx">promise</span>
  <span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="nx">result</span> <span class="o">=&gt;</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">result</span><span class="p">))</span>
  <span class="p">.</span><span class="k">catch</span><span class="p">(</span><span class="nx">error</span> <span class="o">=&gt;</span> <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="nx">error</span><span class="p">));</span>
</code></pre></div></div>

<h3 id="settimeout">setTimeout</h3>
<p>「一定時間後に関数を実行する予約」を行う。
呼び出し時点で関数はまだ実行されず、タイマーを設定して即座に戻る（ノンブロッキング）。</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">setTimeout</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">1秒後に実行されました</span><span class="dl">"</span><span class="p">);</span>
<span class="p">},</span> <span class="mi">1000</span><span class="p">);</span>
</code></pre></div></div>

<h3 id="cleartimeout">clearTimeout</h3>
<p><code class="language-plaintext highlighter-rouge">setTimeout</code> の返す「タイマーID」を <code class="language-plaintext highlighter-rouge">clearTimeout</code> に渡して呼ぶと、その予約はキャンセルされる。</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">timerId</span> <span class="o">=</span> <span class="nx">setTimeout</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">これは実行されません</span><span class="dl">"</span><span class="p">);</span>
<span class="p">},</span> <span class="mi">3000</span><span class="p">);</span>

<span class="nx">clearTimeout</span><span class="p">(</span><span class="nx">timerId</span><span class="p">);</span>
</code></pre></div></div>

<h3 id="abortcontroller">AbortController</h3>

<h5 id="controllersignal">controller.signal</h5>
<p>スイッチの状態を監視するオブジェクト。</p>

<h5 id="controllerabort">controller.abort()</h5>
<p>中断スイッチ。 <code class="language-plaintext highlighter-rouge">signal.aborted</code> が <code class="language-plaintext highlighter-rouge">true</code> になり、 <code class="language-plaintext highlighter-rouge">"abort"</code> イベントが発火する。</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">controller</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">AbortController</span><span class="p">();</span>
<span class="kd">const</span> <span class="p">{</span> <span class="nx">signal</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">controller</span><span class="p">;</span>

<span class="nx">signal</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="dl">"</span><span class="s2">abort</span><span class="dl">"</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">中断されました！</span><span class="dl">"</span><span class="p">);</span>
<span class="p">});</span>

<span class="nx">setTimeout</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="nx">controller</span><span class="p">.</span><span class="nx">abort</span><span class="p">();</span>
<span class="p">},</span> <span class="mi">2000</span><span class="p">);</span>
</code></pre></div></div>]]></content><author><name></name></author><category term="tech" /><category term="lang" /><category term="cheating" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">自分を操る超集中力</title><link href="https://blog.o3osatoshi.engr.work/life/super-focus" rel="alternate" type="text/html" title="自分を操る超集中力" /><published>2025-09-27T15:00:00+00:00</published><updated>2025-09-27T15:00:00+00:00</updated><id>https://blog.o3osatoshi.engr.work/life/super-focus</id><content type="html" xml:base="https://blog.o3osatoshi.engr.work/life/super-focus"><![CDATA[<p><img src="/assets/2025-09-28-super-focus/thumbnail.png" alt="thumbnail" /></p>

<p>※本ブログの目的と内容<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup>、著作者の方へ<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote" rel="footnote">2</a></sup></p>

<h2 id="集中力を自在に操る３つのルール">集中力を自在に操る３つのルール</h2>

<ul>
  <li>ルール１：<strong>鍛え方を知っている</strong>
    <ul>
      <li>ウィルパワー <br />
思考や感情をコントロールする力。
ウィルパワーの総量には限りがあり、集中することで消耗する</li>
      <li>集中力を鍛える２つのアプローチ
        <ol>
          <li>ウィルパワーの総量を増やす</li>
          <li>ウィルパワーを節約する</li>
        </ol>
      </li>
    </ul>
  </li>
  <li>ルール２：<strong>長時間集中していない</strong>
    <ul>
      <li>そもそも人間の脳は集中を維持させないようにできている</li>
    </ul>
  </li>
  <li>ルール３：<strong>「疲れ」を脳でコントロールしている</strong>
    <ul>
      <li>「疲れているから、集中できない」は錯覚</li>
    </ul>
  </li>
</ul>

<h2 id="高い集中力を生み出す７つのエンジン">高い集中力を生み出す７つのエンジン</h2>

<h3 id="環境">環境</h3>
<p>行動しやすい「環境」をつくる。
選択肢やモノを減らし、集中力を奪う迷いや決断を減らす。</p>

<ul>
  <li>集中力を奪うモノ
    <ul>
      <li><strong>スマホ</strong>（注意をそらすものは断捨離する）</li>
      <li><strong>散らかったモノ</strong>（モノを減らすほど自己コントロール力が増す）</li>
    </ul>
  </li>
  <li>集中力を高めるモノ
    <ul>
      <li><strong>目的にあったモノ</strong>（自分の重視したい目的に向けて部屋を整える）</li>
      <li><strong>鏡</strong>（だらけ始めた自分に気づき、「いかん、いかん」と戒める）</li>
    </ul>
  </li>
</ul>

<h3 id="姿勢">姿勢</h3>
<p>だらけた姿勢はウィルパワーを浪費する。
１日に何回か<strong>座り直す習慣</strong>をつくる。
１５分に１回のペースでイスから立ち上がる。
脳に新しい刺激が伝わり、集中力を持続させる効果がえられる。</p>

<h5 id="理想的な姿勢">理想的な姿勢</h5>

<ul>
  <li><strong>あごを引いて頭は首の上にのせる</strong></li>
  <li><strong>お尻と腰を直角にする</strong></li>
  <li><strong>両膝をつける</strong></li>
  <li><strong>足の裏を床につける</strong></li>
</ul>

<h3 id="食事">食事</h3>
<p>ブドウ糖はウィルパワーの燃料庫。
「低GI食品」を中心とした3食とナッツ類を中心とした「おやつ」の補給が、集中力を深め、持続させる。
血糖値の乱高下に、人間は強いストレスを感じる。
血糖値のつなぎとして「間食」がおすすめ。</p>

<ul>
  <li>低GI食品
    <ul>
      <li>そば、玄米、全粒粉パン、リンゴ、チーズ、ヨーグルト</li>
    </ul>
  </li>
  <li>間食
    <ul>
      <li>ピーナッツ、ヘイゼルナッツ等のナッツ系、クルミ、アーモンド、カボチャの種、ひまわりの種</li>
    </ul>
  </li>
  <li>コップ一杯の水
    <ul>
      <li>水を飲まないと集中力と記憶力が落ちる</li>
      <li>１〜２時間にコップ１杯ほどの水分を補給する</li>
    </ul>
  </li>
  <li>セロトニン（幸せホルモン）
    <ul>
      <li>バナナ、卵、鶏肉、ひじき</li>
    </ul>
  </li>
</ul>

<h3 id="感情">感情</h3>
<p>怒りには人を突き動かす強い力が秘められている。
怒りは「目標思考行動」を強く促す。</p>

<h5 id="フロー体験">フロー体験</h5>

<ul>
  <li><strong>ちょうどいい難易度</strong></li>
  <li><strong>コントロール感覚</strong></li>
  <li><strong>直接的なフィードバック</strong></li>
  <li><strong>集中が邪魔されない</strong></li>
</ul>

<h3 id="習慣">習慣</h3>
<p><strong>習慣化でウィルパワーを温存</strong>し、新しい習慣やスキルを身につけるためにウィルパワーを使う。
<strong>「意思決定」で人は疲れる</strong>。即時判断がウィルパワーの浪費を防ぐ。</p>

<h5 id="７本のハンガーが集中力をつくり出す">７本のハンガーが集中力をつくり出す</h5>
<p>日常の生活の中で、<strong>選ぶ場面が少なければ少ないほど集中力は上がる</strong>。
目的に向かって集中できる人は、この「仕組み化」に力を入れ、ウィルパワーを節約し、人生で大切なことに集中している。</p>

<h3 id="運動">運動</h3>
<p>運動は<strong>脳をリセットする</strong>。
２０分の軽い運動をした後の３〜４時間は認知能力、集中力や考察力が高まる。
運動には人の感情をポジティブにする働きもある。</p>

<h5 id="グリーンエクササイズ">グリーンエクササイズ</h5>
<p>緑の中を５分ほど散歩する。
水の側＆午前中の陽の光を浴びるとさらに効果が高まる。</p>

<h5 id="アクティブレスト">アクティブレスト</h5>
<p>軽い運動をすることで効果的にウィルパワーを回復させられる。</p>

<h3 id="瞑想">瞑想</h3>
<p>集中力が向上する。</p>

<h5 id="やり方">やり方</h5>

<ol>
  <li>体を動かさず、じっと座る</li>
  <li>ゆっくりと呼吸する
    <ul>
      <li>７秒かけて吸い、７秒かけて吐く</li>
    </ul>
  </li>
</ol>

<h2 id="疲れをリセットする３つの回復法">疲れをリセットする３つの回復法</h2>

<h3 id="睡眠">睡眠</h3>
<p>睡眠不足は集中力を奪う要因。
成功している人たちは<strong>長時間眠っている</strong>。
平均睡眠時間は約８時間。一方、一般人の平均睡眠時間は６時間。</p>

<ul>
  <li>何時に寝たかが重要
    <ul>
      <li>眠り方の基本はやはり朝型の生活スタイル</li>
      <li>睡眠の質は<strong>２２時から夜中２時の間に深い眠り</strong>に落ちているかどうかで決まる</li>
    </ul>
  </li>
  <li>音ではなく「<strong>光</strong>」で起きる
    <ul>
      <li>質の高い睡眠には、暗闇の中での睡眠と、光での目覚めが必要</li>
    </ul>
  </li>
  <li>１５分の<strong>パワーナップ</strong>
    <ul>
      <li>仮眠することで日中でもウィルパワーを回復できる</li>
    </ul>
  </li>
</ul>

<h3 id="感覚から癒やす">感覚から癒やす</h3>
<p>「<strong>目の疲れ</strong>」を「脳の疲れ」と錯覚する。
脳が処理している情報のうちの８割以上は、視覚を通して集められる。
「目を休ませる」には、<strong>視覚情報をシャットアウト</strong>する。</p>

<h3 id="不安を書き出す">不安を書き出す</h3>
<p>不安を書き出すことでワーキングメモリーが増える。</p>

<h2 id="集中力を自動でつくり出す５つの時間術">集中力を自動でつくり出す５つの時間術</h2>

<h3 id="超朝早起き">超朝早起き</h3>
<p>社会的成功者の４時半起床・２０時半就寝といった生活リズムは、体にとっては最適なリズム。</p>

<h5 id="朝のゴールデンタイムを自分のために使う">朝のゴールデンタイムを自分のために使う</h5>
<p>集中力が最も高くなるのは朝の２時間。その中でも朝食を摂った後の３０分が特に重要。
何か新しいことを始めたい、資格を取るための勉強をしたいと思っているなら、この３０分を有効に活用すべき。</p>

<h5 id="朝行うべき７つの行動">朝、行うべき７つの行動</h5>

<ol>
  <li>早起きして、<strong>朝食</strong>を摂る</li>
  <li><strong>朝日</strong>を浴びながら軽く<strong>汗を流す</strong></li>
  <li>モチベーションが上がる話題や言葉、詩に触れる</li>
  <li>日常の幸せへの感謝を書き留める</li>
  <li>「今日が人生最後の日ならどうする」と自分に問う</li>
  <li>その日の<strong>計画</strong>を１０分以内に立てる</li>
  <li>短時間の<strong>瞑想</strong>をする</li>
</ol>

<h3 id="ポモドーロテクニック">ポモドーロ・テクニック</h3>
<p>２５分の集中と５分の休憩を繰り返す。
<strong>作業に飽きる前に休憩する（焦らす）</strong>ことで、再開したときもスムーズに集中状態に戻れる。
休憩中は、瞑想したりする。
ポモドーロ・テクニックの優れた点は、「やる気が起こるから行動するのではない。行動したからやる気が出る」という作業興奮の原理を実践しやすい点にある。</p>

<h5 id="集中することはたった１つ">集中することはたった１つ</h5>
<p>２５分間では<strong>「１つのこと」に集中</strong>する。
<strong>「他のことをしない」というルールを守るだけで、集中力が必ず高まる</strong>。</p>

<h5 id="観念によって人の行動が変わるプライミング効果">観念によって人の行動が変わる（プライミング効果）</h5>
<p><strong>どこに意識を向けているかによって同じ時間、同じ作業をしていても成果には大きな差が開く</strong>。
集中力が高い人は、自分の集中しやすい環境にこだわり、入ってくる情報やモノ、単語（言葉）ですら選び取っている。
<strong>「集中力を保てた」と感じられた環境や時間を記録する</strong>。</p>

<h5 id="取り組む時間を短くするほど早く終る">取り組む時間を短くするほど、早く終る</h5>
<p>人は目に見えないと、つい「無限にある」と思い込んでしまう。
「あれもこれもやれる」と思っている状態ほど、集中できず、結果に結びつかない可能性が高い。
<strong>集中力は自由なときよりも制限のある状態のほうが高まる</strong>。</p>

<h3 id="ウルトラディアンリズム">ウルトラディアンリズム</h3>
<p>ポモドーロ・テクニックの応用編。９０分集中、２０分休憩。</p>

<h3 id="アイビーリーメソッド">アイビー・リー・メソッド</h3>
<p><strong>１つの作業が終わるまで、断固として次のことをやらない</strong>。
選択と集中によって、本当に大事なことのみ全力を尽くす。
それ以外のことは、やらない、あるいは、誰かにやってもらう。
それにより迷いを消し、行動につなげる。</p>

<h5 id="６つのステップ">６つのステップ</h5>

<ol>
  <li>「明日やるべきこと」を６つ、メモする</li>
  <li>重要な順に並べ替える</li>
  <li>翌日、順番に取り組む</li>
  <li>全部できなくても、悔やむことなく忘れる</li>
  <li>明日のための６つの項目を新しくメモする</li>
  <li>１〜５を丁重に繰り返す</li>
</ol>

<h3 id="スケジュールに余白をつくる">スケジュールに余白をつくる</h3>
<p>後悔したり自分を責めるようになると、結局、人は行動しなくなる。
多少ズレても吸収できるようにするためのあそびを持たせる。
また、あえてサボる時間をつくり、リラックスする習慣を持つことで、結果的に翌日以降の集中力を高められる。</p>
<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1" role="doc-endnote">
      <p>本ブログは「本を読み、理解した内容の備忘録（自分用）」を目的としている。重要なアイディアを昇華させ、自分の言葉でまとめるように努めている <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2" role="doc-endnote">
      <p>内容に不快を感じ、ブログの取り下げを希望される著作者の方は、個別にご連絡いただけると幸いに思う <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name></name></author><category term="life" /><category term="reading" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">モノレポ設定 tsconfig/tsup/biome/eslint</title><link href="https://blog.o3osatoshi.engr.work/tech/conf/monorepo-config" rel="alternate" type="text/html" title="モノレポ設定 tsconfig/tsup/biome/eslint" /><published>2025-09-21T15:00:00+00:00</published><updated>2025-09-21T15:00:00+00:00</updated><id>https://blog.o3osatoshi.engr.work/tech/conf/monorepo-config</id><content type="html" xml:base="https://blog.o3osatoshi.engr.work/tech/conf/monorepo-config"><![CDATA[<p><img src="/assets/2025-09-22-monorepo-config/thumbnail.png" alt="thumbnail" /></p>

<p>※本ブログの目的と内容<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup>、読者の方へ<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote" rel="footnote">2</a></sup></p>

<h2 id="config">config</h2>

<p>モノレポ運用で必要な設定をパッケージで管理している。</p>

<ul>
  <li><a href="https://www.npmjs.com/package/@o3osatoshi/config">npm</a></li>
  <li><a href="https://github.com/o3osatoshi/portfolio/tree/main/packages/config">GitHub</a></li>
</ul>

<h3 id="コンセプト">コンセプト</h3>

<ul>
  <li>共通設定を <code class="language-plaintext highlighter-rouge">@o3osatoshi/config</code> に集約し、モノレポ全体で型・ビルド・リントを一貫管理する</li>
  <li>各アプリはベース設定を継承し、必要な差分だけを上書きすることでメンテナンスコストを抑える</li>
</ul>

<h3 id="役割">役割</h3>

<ul>
  <li>tsconfig … 型チェック</li>
  <li>tsup … ビルド＆バンドル</li>
  <li>biome … フォーマット＆リント</li>
  <li>eslint … ソート</li>
</ul>

<h2 id="tsconfig">tsconfig</h2>

<p>型チェックのみに利用する。
共通の設定を <code class="language-plaintext highlighter-rouge">base.json</code> にまとめ、各パッケージ・アプリケーションで継承する。</p>

<h3 id="basejson">base.json</h3>

<h4 id="厳格性に関する設定">厳格性に関する設定</h4>

<p>厳格さをできる限り高める。</p>

<table>
  <thead>
    <tr>
      <th style="text-align: left">設定</th>
      <th style="text-align: left">解説</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">noUncheckedIndexedAccess</code></td>
      <td style="text-align: left">添字アクセスの未定義性を明示<br /><code class="language-plaintext highlighter-rouge">arr[i]</code> や <code class="language-plaintext highlighter-rouge">obj[key]</code> の結果型に <code class="language-plaintext highlighter-rouge">undefined</code> が付き取りこぼし検出</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">exactOptionalPropertyTypes</code></td>
      <td style="text-align: left">オプショナルと <code class="language-plaintext highlighter-rouge">undefined</code> を厳密に区別<br />「存在しない」と「存在して <code class="language-plaintext highlighter-rouge">undefined</code>」の混同を防止</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">noPropertyAccessFromIndexSignature</code></td>
      <td style="text-align: left">インデックスシグネチャ経由の安易なアクセスを禁止<br />マップ/辞書型での誤アクセスを型で検出</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">noImplicitThis</code></td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">this</code> の暗黙 <code class="language-plaintext highlighter-rouge">any</code> を禁止<br />コールバック等での文脈ミスを抑止</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">noImplicitReturns</code></td>
      <td style="text-align: left">すべての分岐で <code class="language-plaintext highlighter-rouge">return</code> を要求<br />値の返し忘れを検出</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">noFallthroughCasesInSwitch</code></td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">switch</code> の意図しないフォールスルーを禁止<br /><code class="language-plaintext highlighter-rouge">break</code> 書き忘れによるバグを防止</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">noImplicitOverride</code></td>
      <td style="text-align: left">派生クラスでの上書きに <code class="language-plaintext highlighter-rouge">override</code> を必須化<br />親の変更で別メソッド扱いになる事故を防ぐ</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">noUnusedLocals</code></td>
      <td style="text-align: left">未使用ローカル変数をエラーに<br />デッドコードを早期発見。意図的未使用は <code class="language-plaintext highlighter-rouge">_</code> 始まりに</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">noUnusedParameters</code></td>
      <td style="text-align: left">未使用の関数引数をエラーに<br />API 設計を明確化。意図的未使用は <code class="language-plaintext highlighter-rouge">_</code> 始まりに</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">useUnknownInCatchVariables</code></td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">catch (e)</code> を <code class="language-plaintext highlighter-rouge">unknown</code> とする<br />例外を型安全に絞り込みできる（型ガード必須）</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">forceConsistentCasingInFileNames</code></td>
      <td style="text-align: left">ファイル名の大文字小文字ゆれをエラー化<br />OS 差によるビルド/実行不一致を防止</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">resolveJsonModule</code></td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">*.json</code> を型付きで import 可能に<br />JSON 構造の型検査・補完が有効に</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">esModuleInterop</code></td>
      <td style="text-align: left">CJS/ESM の相互運用を改善<br /><code class="language-plaintext highlighter-rouge">default</code> 周りの非互換を緩和しつつ型整合</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">isolatedModules</code></td>
      <td style="text-align: left">各ファイル単体で安全にトランスパイル<br /><code class="language-plaintext highlighter-rouge">const enum</code> 等を禁止しバンドラ互換性を確保</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">verbatimModuleSyntax</code></td>
      <td style="text-align: left">import/export の書き換え最小化<br />ツリーシェイク精度向上・不要コード混入防止</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">skipLibCheck</code></td>
      <td style="text-align: left">外部型定義の再検査をスキップ<br />ビルド高速化。ただし外部 <code class="language-plaintext highlighter-rouge">.d.ts</code> の不整合は見逃す</td>
    </tr>
  </tbody>
</table>

<h4 id="互換性に関する設定">互換性に関する設定</h4>

<p>ESMをベースとしつつ、CJSやバンドラ挙動とも整合を取る。</p>

<table>
  <thead>
    <tr>
      <th style="text-align: left">設定</th>
      <th style="text-align: left">解説</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">esModuleInterop</code></td>
      <td style="text-align: left">CJS と ESM の相互運用を改善（<code class="language-plaintext highlighter-rouge">default</code> 周りの扱いを円滑化）<br /> 既存の CJS ライブラリを <code class="language-plaintext highlighter-rouge">import foo from "lib"</code> で扱いやすく、互換性の罠を回避</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">isolatedModules</code></td>
      <td style="text-align: left">各ファイル単位で安全に変換できる制約を導入（バンドラ互換）<br /> esbuild/tsup/Babel 等との相性が安定し、部分ビルドや並列ビルドで破綻しにくい</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">moduleDetection: "force"</code></td>
      <td style="text-align: left">すべてのファイルをモジュールとして扱い、暗黙スクリプトを排除<br /> グローバル汚染や読み込み順依存を避け、大規模構成での挙動を安定化</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">resolveJsonModule</code></td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">*.json</code> を型付き import 可能にして設定/定数の取り回しを改善<br /> JSON の構造に補完が効き、設定の互換性チェックがしやすい</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">skipLibCheck</code></td>
      <td style="text-align: left">外部 <code class="language-plaintext highlighter-rouge">.d.ts</code> の再検査を省き、外部依存の型ズレで止まりにくくする<br /> 依存更新に強く、CI/ローカルの型チェックも軽量化（厳密性はやや下げる）</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">verbatimModuleSyntax</code></td>
      <td style="text-align: left">import/export の書き換えを最小化して意味を保持<br /> ツリーシェイクの結果が安定し、最終成果物が軽量化しやすい（バンドラ互換性↑）</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">forceConsistentCasingInFileNames</code></td>
      <td style="text-align: left">ファイル名の大文字小文字ゆれをエラー化<br /> mac では動くのに CI(Linux) で壊れる、といったクロスOS不整合を事前に回避</td>
    </tr>
  </tbody>
</table>

<h3 id="nextjsonnextアプリ">next.json（Nextアプリ）</h3>

<h4 id="汎用設定">汎用設定</h4>

<table>
  <thead>
    <tr>
      <th style="text-align: left">設定</th>
      <th style="text-align: left">解説</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">jsx: "preserve"</code></td>
      <td style="text-align: left">JSX を TS が変換せずそのまま残し、後段（SWC/webpack）が処理できるようにする<br /> <code class="language-plaintext highlighter-rouge">use client</code> の境界判定や Server/Client Component の最適化を Next に委譲でき、RSC 変換と整合が取れる</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">lib: ["ES2022","DOM","DOM.Iterable"]</code></td>
      <td style="text-align: left">ブラウザ API（DOM/Iterable）とモダン標準 API を型として有効化<br /> Client Component で DOM 補完が利く一方、Server 側で DOM を参照すると型で気づける（境界違反の早期発見）</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">moduleResolution: "Bundler"</code></td>
      <td style="text-align: left">パッケージ解決をバンドラ挙動に合わせる（<code class="language-plaintext highlighter-rouge">exports</code> 条件・サブパス・エイリアスなど）<br /> 型解決と実行時解決が一致し、「型だけ赤い/実行は通る」ズレを解消。<code class="language-plaintext highlighter-rouge">next/*</code> 仮想モジュールとも相性良い</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">plugins: [{ "name": "next" }]</code></td>
      <td style="text-align: left">Next.js 用 TS プラグインでフレームワーク固有の検査を強化<br /> <code class="language-plaintext highlighter-rouge">generateMetadata</code> / <code class="language-plaintext highlighter-rouge">generateStaticParams</code> / Route Handlers などの型誤用を早期に検出できる</td>
    </tr>
  </tbody>
</table>

<h4 id="個別設定">個別設定</h4>

<table>
  <thead>
    <tr>
      <th style="text-align: left">設定</th>
      <th style="text-align: left">解説</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">include: ["**/*.ts", "**/*.tsx", "next-env.d.ts", ".next/types/**/*.ts"]</code></td>
      <td style="text-align: left">型チェック対象を TS/TSX ファイルと Next.js が自動生成する型ファイルに限定<br /> <br />・<code class="language-plaintext highlighter-rouge">next-env.d.ts</code>: Next.js 基本型（<code class="language-plaintext highlighter-rouge">NextPage</code> や <code class="language-plaintext highlighter-rouge">next/image</code> 等）を有効化。外すと Next 固有の型がエラーになる<br />・<code class="language-plaintext highlighter-rouge">.next/types/**/*.ts</code>: App Router 専用に生成されるルート型を取り込み。外すと <code class="language-plaintext highlighter-rouge">params</code> や <code class="language-plaintext highlighter-rouge">generateMetadata</code> が <code class="language-plaintext highlighter-rouge">any</code> になり型安全性を失う</td>
    </tr>
  </tbody>
</table>

<h3 id="browserjsonreact-uiライブラリ">browser.json（React UIライブラリ）</h3>

<h4 id="汎用設定-1">汎用設定</h4>

<table>
  <thead>
    <tr>
      <th style="text-align: left">設定</th>
      <th style="text-align: left">解説</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">jsx: "react-jsx"</code></td>
      <td style="text-align: left">TypeScript に新しい React JSX 変換を使わせる設定<br /> <code class="language-plaintext highlighter-rouge">React.createElement</code> を書かずにコンパクトなコードを扱える。UIライブラリとして利用される側でも、JSX の型推論が正しく効く</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">types: ["react","react-dom","node"]</code></td>
      <td style="text-align: left">グローバルに読み込む型定義を指定<br /> <code class="language-plaintext highlighter-rouge">react</code>/<code class="language-plaintext highlighter-rouge">react-dom</code> の型で JSX/DOM の型付けが安定。Node 型は UI 専用なら不要だが、SSRやStorybookでの Node API 利用を想定するなら役立つ</td>
    </tr>
  </tbody>
</table>

<h2 id="tsup">tsup</h2>

<p>ビルド＆バンドルに利用する。</p>

<h3 id="共通設定">共通設定</h3>

<table>
  <thead>
    <tr>
      <th style="text-align: left">設定</th>
      <th style="text-align: left">解説</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">treeshake: true</code></td>
      <td style="text-align: left">すべてのビルドでツリーシェイクを有効化<br /> 未使用コードを落としてバンドルを軽量化UI/Functions/Libraryすべてに有効</td>
    </tr>
  </tbody>
</table>

<h3 id="browserpresetreact-uiライブラリ"><code class="language-plaintext highlighter-rouge">browserPreset</code>（React UIライブラリ）</h3>

<table>
  <thead>
    <tr>
      <th style="text-align: left">設定</th>
      <th style="text-align: left">解説</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">format: ["esm"]</code></td>
      <td style="text-align: left">ESM のみ<br /> モダンバンドラ/Next 環境は ESM 前提。CJS は不要かつ複雑化要因</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">platform: "browser"</code></td>
      <td style="text-align: left">ブラウザ実行を前提に解決/ポリフィルを最適化<br /> DOM 依存や Web API 前提コードが混在しうる UI 層に適合</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">target: "es2022"</code></td>
      <td style="text-align: left">モダンブラウザ向け出力<br /> Next/ESBuild の既定と親和性高く、不要なダウンレベル化を避ける</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">splitting: true</code></td>
      <td style="text-align: left">コード分割を許可<br /> 複数エントリ/動的 import でのキャッシュ・再利用・初期ロード削減に有利</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">sourcemap: false</code></td>
      <td style="text-align: left">既定ではオフ<br /> 最終アプリ側のビルド/デバッグフローと二重になりがち。必要時のみON</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">minify: false</code></td>
      <td style="text-align: left">既定は可読性優先<br /> Next 本体側で最終最適化されるため、ここでは縮小必須でない</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">external: ["react","react-dom","next", ...]</code></td>
      <td style="text-align: left">React/Next を確実に external<br /> ダブルバンドル回避とホストアプリ（Next）側の最適化を尊重</td>
    </tr>
  </tbody>
</table>

<h4 id="ビルド">ビルド</h4>

<p>Client Componentの成果物には、先頭に<code class="language-plaintext highlighter-rouge">"use client";</code>が必要。
しかし、<code class="language-plaintext highlighter-rouge">tsup</code>等でビルドすると、tsxファイル先頭の<code class="language-plaintext highlighter-rouge">"use client";</code>は削除されてしまう。
対策として、ビルド完了後に成果物の先頭に<code class="language-plaintext highlighter-rouge">"use client";</code>を後から付与する。</p>

<h5 id="ポイント">ポイント</h5>
<ul>
  <li>ClientサイドのコードとSeverサイドのコードを別々にバレルする</li>
  <li>成果物はClientサイドとServerサイドのそれぞれでバンドルする</li>
  <li><code class="language-plaintext highlighter-rouge">tsup</code>の<code class="language-plaintext highlighter-rouge">onSuccess</code>フックで、Clientサイドの成果物の先頭に<code class="language-plaintext highlighter-rouge">"use client";</code>を付与する</li>
</ul>

<p>※コンポーネント毎にビルドし、それぞれに<code class="language-plaintext highlighter-rouge">"use client";</code>を付与する方法もあるが、管理が少々煩雑になる</p>

<h5 id="設定">設定</h5>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// tsup.client.config.mjs</span>
<span class="k">export</span> <span class="k">default</span> <span class="k">await</span> <span class="nx">browserPreset</span><span class="p">({</span>
  <span class="na">bundle</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
  <span class="na">entry</span><span class="p">:</span> <span class="p">{</span> <span class="na">index</span><span class="p">:</span> <span class="dl">"</span><span class="s2">src/index.client.ts</span><span class="dl">"</span> <span class="p">},</span>
  <span class="na">onSuccess</span><span class="p">:</span> <span class="dl">"</span><span class="s2">node ./scripts/ensure-use-client.mjs dist/client/index.js</span><span class="dl">"</span><span class="p">,</span>
  <span class="na">outDir</span><span class="p">:</span> <span class="dl">"</span><span class="s2">dist/client</span><span class="dl">"</span><span class="p">,</span>
  <span class="na">splitting</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
<span class="p">});</span>
</code></pre></div></div>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// tsup.server.config.mjs</span>
<span class="k">export</span> <span class="k">default</span> <span class="k">await</span> <span class="nx">browserPreset</span><span class="p">({</span>
  <span class="na">bundle</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
  <span class="na">entry</span><span class="p">:</span> <span class="p">{</span> <span class="na">index</span><span class="p">:</span> <span class="dl">"</span><span class="s2">src/index.server.ts</span><span class="dl">"</span> <span class="p">},</span>
  <span class="na">outDir</span><span class="p">:</span> <span class="dl">"</span><span class="s2">dist/server</span><span class="dl">"</span><span class="p">,</span>
  <span class="na">splitting</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
<span class="p">});</span>
</code></pre></div></div>

<h3 id="functionspresetfirebase-functions">functionsPreset（Firebase Functions）</h3>

<table>
  <thead>
    <tr>
      <th style="text-align: left">設定項目</th>
      <th style="text-align: left">解説</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">format: ["esm"]</code></td>
      <td style="text-align: left">ESM 出力<br /> Node 18+／22 環境での ESM サポートに合わせ、将来性と互換性を確保</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">platform: "node"</code></td>
      <td style="text-align: left">Node 向け解決・ポリフィル<br /> GCF/Functions の Node 実行に適合</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">target: "node22"</code></td>
      <td style="text-align: left">Functions の実行環境（Node 22）に最適化<br /> 余計なトランスパイルを避け、起動速度/互換性を担保</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">splitting: false</code></td>
      <td style="text-align: left">コード分割しない<br /> 単一ファイルのほうがデプロイ/コールドスタートの挙動が読みやすく、運用が安定</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">sourcemap: true</code></td>
      <td style="text-align: left">常時ソースマップ<br /> 本番障害解析（Stacktrace 解決）が重要Functions では運用保守性を優先</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">minify: isProd</code></td>
      <td style="text-align: left">本番/CI では縮小、それ以外は可読性優先<br /> ランタイム転送量/起動時間を抑えつつ、ローカル開発はデバッグ性を維持</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">dts: false</code></td>
      <td style="text-align: left">型定義は配布不要<br /> 実行用アプリケーション配布（＝ライブラリ配布ではない）ため</td>
    </tr>
  </tbody>
</table>

<h4 id="ビルド-1">ビルド</h4>

<p>Firebaseの仕様から、ビルドまわり（特に依存管理）が少々特殊になっている。
詳細は<a href="https://blog.o3osatoshi.engr.work/tech/arch/firebase-monorepo-with-turborepo">こちらの投稿</a>を参照のこと。</p>

<h3 id="publicdualpreset外部配布ライブラリ">publicDualPreset（外部配布ライブラリ）</h3>

<table>
  <thead>
    <tr>
      <th style="text-align: left">設定項目</th>
      <th style="text-align: left">解説</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">format: ["esm","cjs"]</code></td>
      <td style="text-align: left"><strong>デュアル出力</strong><br /> 依然として CJS を要求するツール/環境に配慮しつつ、モダン環境の ESM も提供採用障壁を下げる</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">platform: "node"</code><br /> <code class="language-plaintext highlighter-rouge">target: "es2022"</code></td>
      <td style="text-align: left">ライブラリ出力としてモダン Node/バンドラで扱いやすい設定<br /> 余計なダウンレベル化を避けつつ、幅広いツールチェーンで安定動作</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">splitting: true</code></td>
      <td style="text-align: left">コード分割許可<br /> 複数エントリや副次的モジュールを持つ配布に対応消費側のバンドラにとっても再利用性が高い</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">sourcemap: isProd</code></td>
      <td style="text-align: left">本番ビルドでソースマップを同梱<br /> 利用者のデバッグ体験向上開発時は不要、配布時のみ付けるバランス</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">minify: false</code></td>
      <td style="text-align: left">既定は非縮小<br /> 配布ライブラリは利用側で最終最適化されることが多く、可読性・差分レビューを重視必要に応じて ON 可</td>
    </tr>
  </tbody>
</table>

<h2 id="biome">biome</h2>

<p>フォーマット＆リントに利用する。</p>

<h3 id="basejson-1">base.json</h3>

<table>
  <thead>
    <tr>
      <th style="text-align: left">設定</th>
      <th style="text-align: left">解説</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left">assist.actions.source.organizeImports</td>
      <td style="text-align: left">インポート整理の自動修正をオフ<br />ESLintの <code class="language-plaintext highlighter-rouge">perfectionist</code> を優先</td>
    </tr>
    <tr>
      <td style="text-align: left">linter.domains.project</td>
      <td style="text-align: left">Project ドメインの推奨ルールを有効化<br />依存関係や import サイクルなどを検知</td>
    </tr>
    <tr>
      <td style="text-align: left">linter.domains.test</td>
      <td style="text-align: left">Test ドメインの推奨ルールを有効化<br />テストコードの品質と誤用防止に寄与</td>
    </tr>
    <tr>
      <td style="text-align: left">linter.rules.complexity.useLiteralKeys</td>
      <td style="text-align: left">リテラルキー強制をオフ<br />TS の <code class="language-plaintext highlighter-rouge">noPropertyAccessFromIndexSignature</code> を優先し、ブラケット記法を許容</td>
    </tr>
  </tbody>
</table>

<h4 id="適用">適用</h4>

<p>全体にbiomeを反映させるため、ルートに以下の<code class="language-plaintext highlighter-rouge">biome.json</code>を配置する。</p>

<pre><code class="language-json5">// /biome.json
{
  "extends": ["@o3osatoshi/config/biome/base.json"],
  "root": true
}
</code></pre>

<h3 id="nextjsonnextアプリ-1">next.json（Nextアプリ）</h3>

<table>
  <thead>
    <tr>
      <th style="text-align: left">設定</th>
      <th style="text-align: left">解説</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left">linter.domains.next</td>
      <td style="text-align: left">Next.js ドメインの推奨ルールを有効化<br />Next.js 固有のアンチパターン防止やベストプラクティスを自動検知</td>
    </tr>
  </tbody>
</table>

<h4 id="適用-1">適用</h4>

<p>個別に<code class="language-plaintext highlighter-rouge">biome.json</code>を配置することで、設定の上書きが可能。nextやreact用の設定反映範囲を限定できる。</p>

<pre><code class="language-json5">// /apps/web/biome.json
{
  "extends": [
    "@o3osatoshi/config/biome/base.json",
    "@o3osatoshi/config/biome/react.json",
    "@o3osatoshi/config/biome/next.json"
  ],
  "root": false
}
</code></pre>

<h3 id="readjsonreactアプリ">read.json（Reactアプリ）</h3>

<table>
  <thead>
    <tr>
      <th style="text-align: left">設定</th>
      <th style="text-align: left">解説</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left">linter.domains.react</td>
      <td style="text-align: left">React ドメインの推奨ルールを有効化<br />Hooks や JSX に関するベストプラクティスを自動検知</td>
    </tr>
    <tr>
      <td style="text-align: left">linter.rules.nursery.useSortedClasses</td>
      <td style="text-align: left">JSX の className 等をソート<br /><code class="language-plaintext highlighter-rouge">clsx</code>, <code class="language-plaintext highlighter-rouge">cva</code>, <code class="language-plaintext highlighter-rouge">tw</code> 系関数や <code class="language-plaintext highlighter-rouge">classList</code> 属性のクラス順序を強制</td>
    </tr>
    <tr>
      <td style="text-align: left">linter.rules.suspicious.noDuplicateJsxProps</td>
      <td style="text-align: left">JSX 属性の重複を禁止<br />予期しない上書きやバグを防止</td>
    </tr>
  </tbody>
</table>

<h4 id="適用-2">適用</h4>

<pre><code class="language-json5">// /packages/ui/biome.json
{
  "extends": [
    "@o3osatoshi/config/biome/base.json",
    "@o3osatoshi/config/biome/react.json"
  ],
  "root": false
}
</code></pre>

<h2 id="eslint">eslint</h2>

<p>ソートのみに利用する。
biomeのカバー範囲がまだまだ狭いため、補完的にeslintを利用する。</p>

<h3 id="config-1">config</h3>

<p>ライブラリ毎にconfigを作成し、一つにまとめてexportする。</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="nx">jsonc</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">./jsonc.mjs</span><span class="dl">"</span><span class="p">;</span>
<span class="k">import</span> <span class="nx">perfectionist</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">./perfectionist.mjs</span><span class="dl">"</span><span class="p">;</span>
<span class="k">import</span> <span class="nx">vitest</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">./vitest.mjs</span><span class="dl">"</span><span class="p">;</span>

<span class="k">export</span> <span class="k">default</span> <span class="p">[</span>
  <span class="p">{</span>
    <span class="na">ignores</span><span class="p">:</span> <span class="p">[</span>
      <span class="dl">"</span><span class="s2">**/node_modules/**</span><span class="dl">"</span><span class="p">,</span>
      <span class="dl">"</span><span class="s2">**/dist/**</span><span class="dl">"</span><span class="p">,</span>
      <span class="dl">"</span><span class="s2">**/generated/**</span><span class="dl">"</span><span class="p">,</span>
      <span class="dl">"</span><span class="s2">**/.next/**</span><span class="dl">"</span><span class="p">,</span>
      <span class="dl">"</span><span class="s2">**/.turbo/**</span><span class="dl">"</span><span class="p">,</span>
      <span class="dl">"</span><span class="s2">**/.idea/**</span><span class="dl">"</span><span class="p">,</span>
      <span class="dl">"</span><span class="s2">**/storybook-static/**</span><span class="dl">"</span><span class="p">,</span>
    <span class="p">],</span>
  <span class="p">},</span>
  <span class="p">...</span><span class="nx">perfectionist</span><span class="p">,</span>
  <span class="p">...</span><span class="nx">jsonc</span><span class="p">,</span>
  <span class="p">...</span><span class="nx">vitest</span><span class="p">,</span>
<span class="p">];</span>
</code></pre></div></div>

<h3 id="適用-3">適用</h3>

<p>プロジェクトルートでは、importしたconfigをそのままexportする。</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// /eslint.config.mjs</span>
<span class="k">import</span> <span class="nx">config</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@o3osatoshi/config/eslint/config.mjs</span><span class="dl">"</span><span class="p">;</span>

<span class="k">export</span> <span class="k">default</span> <span class="p">[...</span><span class="nx">config</span><span class="p">];</span>
</code></pre></div></div>
<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1" role="doc-endnote">
      <p>本ブログは「技術的自由研究の備忘録」を目的としている。ソースコードは <a href="https://github.com/o3osatoshi/portfolio">GitHubリポジトリ</a> に公開している <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2" role="doc-endnote">
      <p>お気づきの点や改善案があれば、遠慮なくお知らせいただきたい。ご意見やご感想を歓迎します <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name></name></author><category term="tech" /><category term="conf" /><category term="coding" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Turborepoで構築するFirebaseモノレポ環境</title><link href="https://blog.o3osatoshi.engr.work/tech/arch/firebase-monorepo-with-turborepo" rel="alternate" type="text/html" title="Turborepoで構築するFirebaseモノレポ環境" /><published>2025-08-12T15:00:00+00:00</published><updated>2025-08-12T15:00:00+00:00</updated><id>https://blog.o3osatoshi.engr.work/tech/arch/firebase-monorepo-with-turborepo</id><content type="html" xml:base="https://blog.o3osatoshi.engr.work/tech/arch/firebase-monorepo-with-turborepo"><![CDATA[<p><img src="/assets/2025-08-13-firebase-monorepo-with-turborepo/thumbnail.png" alt="thumbnail" /></p>

<p>※本ブログの目的と内容<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup>、読者の方へ<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote" rel="footnote">2</a></sup></p>

<h2 id="前提">前提</h2>

<ul>
  <li>functionsのみのモノレポ化を対象としている</li>
  <li>hostingはモノレポ化の対象外（当方はvercelを利用している）</li>
</ul>

<h2 id="デプロイフロー">デプロイフロー</h2>

<h3 id="firebase-functionsモノレポの問題点">Firebase Functionsモノレポの問題点</h3>

<h4 id="firebase-functionsのデプロイフロー仕様">Firebase Functionsのデプロイフロー（仕様）</h4>

<ol>
  <li>対象ディレクトリ（ <code class="language-plaintext highlighter-rouge">apps/functions</code> ）をサーバにアップロード</li>
  <li>アップロードされたディレクトリで <code class="language-plaintext highlighter-rouge">npm install</code> を実行</li>
</ol>

<h4 id="問題点">問題点</h4>
<p><code class="language-plaintext highlighter-rouge">npm install</code> 時に、ローカルパッケージ（ <code class="language-plaintext highlighter-rouge">packages/application</code>等 ）を見つけられずにエラーになる。</p>

<h3 id="解決策">解決策</h3>

<h4 id="バンドルを組み合わせたデプロイフロー">バンドルを組み合わせたデプロイフロー</h4>

<ol>
  <li>functionsのビルド＆バンドルをデプロイ前に行う</li>
  <li>対象ディレクトリ（ <code class="language-plaintext highlighter-rouge">apps/functions</code> ）をサーバにアップロード</li>
  <li>アップロードされたディレクトリで <code class="language-plaintext highlighter-rouge">npm install</code> を実行</li>
</ol>

<h4 id="ポイント">ポイント</h4>
<p>ローカルパッケージへの依存をバンドルにより事前に解決する。</p>

<h2 id="構成">構成</h2>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>⏺ root/
  ├── 📁 apps/
  │   ├── 📁 web/                          # Next.js
  │   │
  │   └── 📁 functions/                    # Firebase Cloud Functions
  │       ├── 📁 src/
  │       │   └── 📄 index.ts
  │       ├── 📄 package.json
  │       ├── 📄 tsconfig.json
  │       ├── 📄 tsup.config.ts
  │       └── 📄 turbo.json
  │
  ├── 📁 packages/
  │   ├── 📁 application/                  # アプリケーション層
  │   │   ├── 📁 src/
  │   │   │   └── 📄 index.ts
  │   │   ├── 📄 package.json
  │   │   └── 📄 tsconfig.json
  │   ├── 📁 domain/                       # ドメイン層
  │   │   ├── 📁 src/
  │   │   │   └── 📄 index.ts
  │   │   ├── 📄 package.json
  │   │   └── 📄 tsconfig.json
  │   └── 📁 prisma/                       # インフラストラクチャ層
  │       ├── 📁 src/
  │       │   └── 📄 index.ts
  │       ├── 📄 package.json
  │       └── 📄 tsconfig.json
  │
  ├── 📄 package.json                      # ワークスペース設定
  ├── 📄 turbo.json                        # Turborepo設定
  └── 📄 firebase.json                     # Firebase設定
</code></pre></div></div>

<h2 id="設定">設定</h2>
<p>モノレポ化にあたって、重要なポイントのみ説明する。
フルコードは、<a href="https://github.com/o3osatoshi/portfolio">GitHubリポジトリ</a>を参照のこと。</p>

<h3 id="appsfunctions">apps/functions</h3>

<h4 id="functionssrcindexts">functions/src/index.ts</h4>

<ol>
  <li>通常通りにローカルパッケージからインポートする</li>
</ol>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">GetTransactionsUseCase</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@repo/application</span><span class="dl">"</span><span class="p">;</span> <span class="c1">// &lt;------------- 1</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">PrismaTransactionRepository</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@repo/prisma</span><span class="dl">"</span><span class="p">;</span> <span class="c1">// &lt;------------- 1</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">onRequest</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">firebase-functions/v2/https</span><span class="dl">"</span><span class="p">;</span>

<span class="kd">const</span> <span class="nx">repo</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">PrismaTransactionRepository</span><span class="p">();</span>
<span class="kd">const</span> <span class="nx">usecase</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">GetTransactionsUseCase</span><span class="p">(</span><span class="nx">repo</span><span class="p">);</span>

<span class="k">export</span> <span class="kd">const</span> <span class="nx">getTransactions</span> <span class="o">=</span> <span class="nx">onRequest</span><span class="p">(</span><span class="k">async</span> <span class="p">(</span><span class="nx">request</span><span class="p">,</span> <span class="nx">response</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">transactions</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">usecase</span><span class="p">.</span><span class="nx">execute</span><span class="p">();</span>
  <span class="nx">response</span><span class="p">.</span><span class="nx">json</span><span class="p">(</span><span class="nx">transactions</span><span class="p">);</span>
<span class="p">});</span>
</code></pre></div></div>

<h4 id="functionspackagejson">functions/package.json</h4>

<ol>
  <li><code class="language-plaintext highlighter-rouge">tsup</code> でビルド＆バンドルを行う</li>
  <li>ローカルパッケージへの依存を明記しない</li>
</ol>

<pre><code class="language-json5">{
  "scripts": {
    "build": "tsup" // &lt;----------------------------------------------------- 1
  },
  "dependencies": { // &lt;----------------------------------------------------- 2
    "firebase-admin": "^12.6.0",
    "firebase-functions": "^6.0.1"
  },
  "devDependencies": { // &lt;-------------------------------------------------- 2
    "firebase-functions-test": "^3.1.0",
    "tsup": "^8.4.0",
    "typescript": "^4.9.0"
  }
}
</code></pre>

<p>applicationパッケージ等への依存を明記すると、Firebase側のインストールでエラーが発生してしまう。
ローカルビルド時にバンドルすることでエラーを避ける。</p>

<h4 id="functionstsconfigjson">functions/tsconfig.json</h4>

<ol>
  <li>applicationパッケージ等への依存はパスエイリアスで解決する</li>
</ol>

<pre><code class="language-json5">{
  "compilerOptions": {
    "paths": {
      "@repo/application": ["../../packages/application/src"], // &lt;---------- 1
      "@repo/prisma": ["../../packages/prisma/src"] // &lt;--------------------- 1
    }
  }
}
</code></pre>

<h4 id="functionstsupconfigts">functions/tsup.config.ts</h4>

<ol>
  <li>バンドルサイズ削減とビルド短縮のため基本的に除外し、Firebase側のインストールに任せる<br />
※ <code class="language-plaintext highlighter-rouge">autoExternals</code> でpackage.jsonの <code class="language-plaintext highlighter-rouge">dependencies</code> と <code class="language-plaintext highlighter-rouge">devDependencies</code> を配列化する</li>
</ol>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="k">async</span> <span class="kd">function</span> <span class="nx">functionsPreset</span><span class="p">(</span><span class="nx">opts</span><span class="p">:</span> <span class="nx">Options</span> <span class="o">=</span> <span class="p">{})</span> <span class="p">{</span>
  <span class="k">return</span> <span class="nx">defineConfig</span><span class="p">({</span>
    <span class="na">external</span><span class="p">:</span> <span class="p">[</span> <span class="c1">// &lt;--------------------------------------------------------- 1</span>
      <span class="p">...</span><span class="nx">autoExternals</span><span class="p">(),</span>
      <span class="p">...((</span><span class="nx">opts</span><span class="p">.</span><span class="nx">external</span> <span class="o">??</span> <span class="p">[])</span> <span class="k">as</span> <span class="nx">NonNullable</span><span class="o">&lt;</span><span class="nx">Options</span><span class="p">[</span><span class="dl">"</span><span class="s2">external</span><span class="dl">"</span><span class="p">]</span><span class="o">&gt;</span><span class="p">),</span>
    <span class="p">],</span>
    <span class="na">format</span><span class="p">:</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">format</span> <span class="o">??</span> <span class="p">[</span><span class="dl">"</span><span class="s2">cjs</span><span class="dl">"</span><span class="p">],</span>
  <span class="p">});</span>
<span class="p">}</span>
</code></pre></div></div>

<h4 id="functionsturbojson">functions/turbo.json</h4>

<ol>
  <li>ルートの <code class="language-plaintext highlighter-rouge">turbo.json</code> を継承する</li>
  <li>application等への依存を明示する</li>
</ol>

<pre><code class="language-json5">{
  "extends": ["//"], // &lt;---------------------------------------------------- 1
  "tasks": {
    "build": {
      "dependsOn": ["@repo/application#build", "@repo/prisma#build"] // &lt;---- 2
    }
  }
}
</code></pre>

<p>Turborepoは <code class="language-plaintext highlighter-rouge">package.json</code> の <code class="language-plaintext highlighter-rouge">dependencies</code> と <code class="language-plaintext highlighter-rouge">devDependencies</code> に記載された情報から依存関係を自動検知する。
今回の場合、 <code class="language-plaintext highlighter-rouge">package.json</code> でapplicationパッケージ等への依存を明記していないため、Turborepoには依存関係が認識されない。
この状態で <code class="language-plaintext highlighter-rouge">turbo run build --filter=functions...</code> を実行しても、applicationパッケージ等のビルドは行われない。
そこで <code class="language-plaintext highlighter-rouge">turbo.json</code> にapplicationパッケージ等への依存を明示することで、functionsのビルド前にapplicationパッケージ等のビルドを強要する。</p>

<h3 id="packagesapplication">packages/application</h3>
<p>Firebaseを意識した特別な設定はなし。</p>

<h4 id="applicationsrcindexts">application/src/index.ts</h4>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">class</span> <span class="nx">GetTransactionsUseCase</span> <span class="p">{</span>
  <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="k">readonly</span> <span class="nx">repo</span><span class="p">:</span> <span class="nx">TransactionRepository</span><span class="p">)</span> <span class="p">{}</span>

  <span class="nx">execute</span><span class="p">():</span> <span class="nx">ResultAsync</span><span class="o">&lt;</span><span class="nx">GetTransactionsResponse</span><span class="p">,</span> <span class="nb">Error</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">repo</span><span class="p">.</span><span class="nx">findMany</span><span class="p">().</span><span class="nx">map</span><span class="p">(</span><span class="nx">toTransactionsResponse</span><span class="p">);</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h4 id="applicationpackagejson">application/package.json</h4>

<ol>
  <li>src-firstにexportsを設定する<br />
※ dist-firstでも問題はない</li>
</ol>

<pre><code class="language-json5">{
  "exports": {
    ".": "./src/index.ts" // &lt;----------------------------------------------- 1
  },
}
</code></pre>

<h3 id="packagesprisma">packages/prisma</h3>
<p>Firebaseを意識した特別な設定はなし。</p>

<h4 id="prismaschemaschemaprism">prisma/schema/schema.prism</h4>
<p>v16.16.0からrustエンジンの利用を避けられる（詳細は<a href="https://www.prisma.io/docs/orm/prisma-client/setup-and-configuration/no-rust-engine">こちら</a>）。
rustエンジンは往々にしてデプロイ関連でエラーを引き起こすため使用を避ける。</p>

<pre><code class="language-prisma">generator client {
  provider   = "prisma-client"
  output     = "../generated/prisma"
  engineType = "client"
}
</code></pre>

<h4 id="prismasrcindexts">prisma/src/index.ts</h4>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">class</span> <span class="nx">PrismaTransactionRepository</span> <span class="k">implements</span> <span class="nx">TransactionRepository</span> <span class="p">{</span>
  <span class="nx">findMany</span><span class="p">():</span> <span class="nx">ResultAsync</span><span class="o">&lt;</span><span class="nx">Transaction</span><span class="p">[],</span> <span class="nb">Error</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">ResultAsync</span><span class="p">.</span><span class="nx">fromPromise</span><span class="p">(</span>
      <span class="nx">prisma</span><span class="p">.</span><span class="nx">transaction</span><span class="p">.</span><span class="nx">findMany</span><span class="p">(),</span>
      <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="o">=&gt;</span>
        <span class="nx">newPrismaError</span><span class="p">({</span>
          <span class="na">action</span><span class="p">:</span> <span class="dl">"</span><span class="s2">FindTransactions</span><span class="dl">"</span><span class="p">,</span>
          <span class="na">cause</span><span class="p">:</span> <span class="nx">e</span><span class="p">,</span>
        <span class="p">}),</span>
    <span class="p">).</span><span class="nx">andThen</span><span class="p">((</span><span class="nx">rows</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">Result</span><span class="p">.</span><span class="nx">combine</span><span class="p">(</span><span class="nx">rows</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">toEntity</span><span class="p">)));</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="root">root</h3>

<h4 id="packagejson">package.json</h4>
<p>Firebaseを意識した特別な設定はなし。</p>

<pre><code class="language-json5">{
  "scripts": {
    "build:functions": "turbo run build --filter=@o3osatoshi/functions...",
    "deploy:functions": "firebase deploy --only functions"
  }
}
</code></pre>

<h4 id="turbojson">turbo.json</h4>
<p>Firebaseを意識した特別な設定はなし。</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"tasks"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"build"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"dependsOn"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"^build"</span><span class="p">],</span><span class="w">
      </span><span class="nl">"inputs"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"$TURBO_DEFAULT$"</span><span class="p">,</span><span class="w"> </span><span class="s2">".env*"</span><span class="p">],</span><span class="w">
      </span><span class="nl">"outputs"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"dist/**"</span><span class="p">]</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h4 id="firebasejson">firebase.json</h4>

<ol>
  <li>rootからの相対パスでfunctionsを指定する</li>
  <li>デプロイ前にfunctionsのビルド（ <code class="language-plaintext highlighter-rouge">pnpm build:functions</code> ）を実行する</li>
</ol>

<pre><code class="language-json5">{
  "functions": [
    {
      "source": "apps/functions", // &lt;--------------------------------------- 1
      "predeploy": "pnpm build:functions" // &lt;------------------------------- 2
    }
  ]
}
</code></pre>

<h2 id="メリットデメリット">メリット・デメリット</h2>

<h3 id="メリット">メリット</h3>
<ul>
  <li>Firebaseの問題をfunctionsディレクトリ内で完結して解消している
    <ul>
      <li>applicationやrootの設定・コードに変更が不要（汚染されない）</li>
    </ul>
  </li>
  <li>バンドルの設定がシンプル
    <ul>
      <li>複雑な設定・構成を必要としない</li>
    </ul>
  </li>
  <li>ソースコード（ <code class="language-plaintext highlighter-rouge">functions/src/index.ts</code> ）内でローカルパッケージをインポートできる
    <ul>
      <li>ローカルパッケージへのジャンプも機能し、開発体験を損なわない（その逆も可能）</li>
    </ul>
  </li>
</ul>

<h3 id="デメリット">デメリット</h3>
<ul>
  <li>今のところ見つかっていない</li>
</ul>
<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1" role="doc-endnote">
      <p>本ブログは「技術的自由研究の備忘録」を目的としている。ソースコードは <a href="https://github.com/o3osatoshi/portfolio">GitHubリポジトリ</a> に公開している <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2" role="doc-endnote">
      <p>お気づきの点や改善案があれば、遠慮なくお知らせいただきたい。ご意見やご感想を歓迎します <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name></name></author><category term="tech" /><category term="arch" /><category term="coding" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Claude Codeの開発効率を3倍に引き上げる7つの上級者向けTips</title><link href="https://blog.o3osatoshi.engr.work/tech/ai/7-tips-triple-claude-code-productivity" rel="alternate" type="text/html" title="Claude Codeの開発効率を3倍に引き上げる7つの上級者向けTips" /><published>2025-08-10T15:00:00+00:00</published><updated>2025-08-10T15:00:00+00:00</updated><id>https://blog.o3osatoshi.engr.work/tech/ai/7-tips-triple-claude-code-productivity</id><content type="html" xml:base="https://blog.o3osatoshi.engr.work/tech/ai/7-tips-triple-claude-code-productivity"><![CDATA[<p><img src="/assets/2025-08-11-7-tips-triple-claude-code-productivity/thumbnail.png" alt="thumbnail" /></p>

<p>※本ブログの目的と内容<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup>、著作者の方へ<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote" rel="footnote">2</a></sup></p>

<p>※本ブログは、YouTube動画（<a href="https://youtu.be/4AMjoQsOLOg?si=PEnf7R06cC0YRCCr">Claude Codeの開発効率を3倍に引き上げる7つの上級者向けTips</a>）の視聴備忘録である</p>

<h3 id="開発の進め方">開発の進め方</h3>

<ol>
  <li>要件定義
    <ul>
      <li>はじめに <code class="language-plaintext highlighter-rouge">init</code> を実行</li>
      <li>ヌケモレなく要件定義するために、<strong>AIにヒアリングさせる</strong>
        <ul>
          <li>大枠の要望を記述した上で、「要件を詰めたいので、ヒアリングしてください」と追記する</li>
        </ul>
      </li>
      <li>ヒアリング結果は、<strong>要件定義書としてCLAUDE.mdに出力</strong>させておく
        <ul>
          <li>CLAUDE.md
            <ul>
              <li>守ってほしいルールなどを一般的に記述する</li>
              <li>使用する技術の<strong>ベストプラクティス</strong>も記載しておくと良い</li>
              <li>モノレポ構成でアプリごとに配置することも可能</li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </li>
  <li>チケット分割
    <ul>
      <li>要件定義書に基づいて必要な機能を洗い出させる</li>
      <li>プロンプト例
        <blockquote>
          <p>要件定義書を機能毎にチケット分割してください。/docs配下にお願いします。
マークダウンファイルを使用し、ファイル名に連番を振ってください。
各ファイルでTodo管理も行います。- []で終わったら- [x]を入れるようにCLAUDE.mdファイルに記載しておいてください。</p>
        </blockquote>
      </li>
    </ul>
  </li>
  <li>チケットベースで開発を進めさせる</li>
</ol>

<h4 id="オプション-tips">オプション Tips</h4>

<ul>
  <li><code class="language-plaintext highlighter-rouge">--dangerously-skip-permissions</code> … 許可を求められない</li>
  <li><code class="language-plaintext highlighter-rouge">--resume</code> … 過去の会話を遡れる</li>
  <li><code class="language-plaintext highlighter-rouge">--continue</code> … 直近の会話から再開できる</li>
</ul>

<h3 id="hooks">hooks</h3>

<ul>
  <li><strong>PreToolUse</strong> … 事前処理を指定できる</li>
  <li><strong>PostToolUse</strong> … 事後処理を指定できる（prettierを実行するなど）</li>
  <li><strong>Stop</strong> … すべての処理が完了したあとの処理を指定できる（通知など）</li>
</ul>

<h3 id="github-との連携">GitHub との連携</h3>

<ol>
  <li>ghコマンドをインストールする</li>
  <li>リポジトリを作成させる
    <blockquote>
      <p>ghコマンドを使って、リポジトリを作成してください</p>
    </blockquote>
  </li>
  <li>issueを作成させる
    <blockquote>
      <p>今のアプリで、実装すべきissueを作成してください</p>
    </blockquote>
    <ul>
      <li>リポジトリ内でチケット管理しても良いし、GitHubのissueでチケット管理しても良い</li>
      <li>Claude GitHub Actionsで、issueベースに開発を進めていくことも可能
        <ul>
          <li><code class="language-plaintext highlighter-rouge">/install-github-app</code> で、Actionsがセットアップされる</li>
        </ul>
      </li>
    </ul>
  </li>
</ol>

<h3 id="mcp">MCP</h3>
<p>外部サービスをAI経由で操作できる。</p>

<ol>
  <li>プロジェクトルートに <code class="language-plaintext highlighter-rouge">.mcp.json</code> を作成する</li>
  <li><code class="language-plaintext highlighter-rouge">claude --mcp-config=.mcp.json</code> で接続</li>
  <li>playwrightでmcpのテスト
    <blockquote>
      <p>手動テストをPlaywrightMCPを起動して行ってください。講座が閲覧できてるか確認したいです。</p>
    </blockquote>
  </li>
</ol>

<h4 id="tips">Tips</h4>
<ul>
  <li><a href="https://mcp.so/">mcp.so</a> で人気なmcpを調べられる</li>
  <li><a href="https://mcpify.ai/">MCPify</a> でMCPサーバの作成も可能</li>
</ul>

<h3 id="agents">Agents</h3>
<p>各専門領域に特化したエージェントを作成できる。
Nextjs専門のエージェントやバックエンド専門のエージェントなど。
<strong>エージェント毎にコンテキストが保持</strong>されるため、分野毎のコンテキストを汚染せずに済む。</p>

<ol>
  <li><code class="language-plaintext highlighter-rouge">Create new agent</code></li>
  <li><code class="language-plaintext highlighter-rouge">Generate with Claude</code> ※推奨設定から作成する場合
    <ul>
      <li>エージェントの内容を指示　※以下は公式推奨文
        <blockquote>
          <p>User the code-reviewer subagent to check my recent changes</p>
        </blockquote>
      </li>
      <li><code class="language-plaintext highlighter-rouge">.claude/agents</code> 配下にエージェント用mdが生成される</li>
    </ul>
  </li>
</ol>

<h4 id="tips-1">Tips</h4>
<ul>
  <li>各分野用に調整されたmdを配布している人もいるので探してみると良い</li>
</ul>

<h3 id="カスタムスラッシュコマンド">カスタムスラッシュコマンド</h3>

<ol>
  <li><code class="language-plaintext highlighter-rouge">.claude/commands</code> ディレクトリを作成</li>
  <li><code class="language-plaintext highlighter-rouge">xx.md</code> でファイルを作成し、Claude Codeへの指示文を記載する</li>
  <li>スラッシュで追加したコマンド <code class="language-plaintext highlighter-rouge">xx</code> が使用できるようになる</li>
</ol>

<h4 id="tips-2">Tips</h4>
<ul>
  <li>Claude Codeにカスタムコマンドを作成させることも可能</li>
</ul>
<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1" role="doc-endnote">
      <p>本ブログは「動画を視聴し、理解した内容の備忘録（自分用）」を目的としている。重要なアイディアを昇華させ、自分の言葉でまとめるように努めている <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2" role="doc-endnote">
      <p>内容に不快を感じ、ブログの取り下げを希望される著作者の方は、個別にご連絡いただけると幸いに思う <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name></name></author><category term="tech" /><category term="ai" /><category term="watching" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">達人プログラマー</title><link href="https://blog.o3osatoshi.engr.work/tech/craft/the-pragmatic-programmer" rel="alternate" type="text/html" title="達人プログラマー" /><published>2025-07-16T15:00:00+00:00</published><updated>2025-07-16T15:00:00+00:00</updated><id>https://blog.o3osatoshi.engr.work/tech/craft/the-pragmatic-programmer</id><content type="html" xml:base="https://blog.o3osatoshi.engr.work/tech/craft/the-pragmatic-programmer"><![CDATA[<p><img src="/assets/2025-07-17-the-pragmatic-programmer/thumbnail.png" alt="thumbnail" /></p>

<p>※本ブログの目的と内容<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup>、著作者の方へ<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote" rel="footnote">2</a></sup></p>

<h2 id="哲学">哲学</h2>
<p>達人プログラマーは、眼の前の問題を考えるだけでなく、常にその問題をより<strong>大きなコンテキスト</strong>で捉え、<strong>ものごとの大局</strong>を見据えようとする。</p>

<h4 id="あなたの人生">あなたの人生</h4>
<p>あなたは自分自身の人生を生きている。あなたには<strong>現状を打開する力</strong>がある。
この業界には驚くほど多くの機会が横たわっている。積極的な行動に出て、機会をつかみ取る。</p>

<h4 id="気質">気質</h4>
<p>開発者には主体性が必要。</p>

<ul>
  <li>アーリーアダプター
    <ul>
      <li><strong>試すこと</strong>が生きがい</li>
    </ul>
  </li>
  <li>研究好き
    <ul>
      <li><strong>疑問</strong>を感じやすい</li>
    </ul>
  </li>
  <li><strong>批判的</strong>
    <ul>
      <li>額面どおりに受け取らない</li>
    </ul>
  </li>
  <li>現実的
    <ul>
      <li><strong>本質の理解</strong>に務める</li>
    </ul>
  </li>
  <li>何でも屋</li>
</ul>

<h5 id="謙虚である">謙虚である</h5>
<p>自らの<strong>無知や過ちを率直に認める</strong>。
すべての問題をベンダー、プログラミング言語、管理、同僚のせいにしてはいけない。
弁解の代わりに対策を提案する。</p>

<h5 id="自負と偏見">自負と偏見</h5>
<p><strong>他人のコードに対して敬意を払う</strong>。</p>

<p>我々は所有することによって誇りを持つべき。
「私はこれを記述した。そして、この仕事についてのすべての責任は私にある」と。
成果物には、品質の証明としてあなたの署名が入っているべき。</p>

<h5 id="ユーザを喜ばせる">ユーザを喜ばせる</h5>
<p>開発者としての我々の目標は、「ユーザを喜ばせる」こと。</p>

<h4 id="ポートフォリオ">ポートフォリオ</h4>
<p>知識と経験は、最も重要な資産。</p>

<ol>
  <li>定期的に投資する
    <ul>
      <li><strong>継続</strong>によって大きなものとなる</li>
    </ul>
  </li>
  <li><strong>多様化</strong>する
    <ul>
      <li>まず現在使っている技術の詳細を知る</li>
      <li>世界はどんどん変化する</li>
    </ul>
  </li>
  <li>リスクを管理する
    <ul>
      <li>技術という卵をすべて１つのかごの中に入れない</li>
    </ul>
  </li>
  <li>安値で買い、高値で売る</li>
  <li>見直しと再配分をする</li>
</ol>

<h5 id="ポートフォリを充実させる活動">ポートフォリを充実させる活動</h5>

<ul>
  <li>毎年少なくとも言語を１つ学習する</li>
  <li><strong>月に１冊</strong>のペースで技術書を読む</li>
  <li>技術書以外の書籍を読む</li>
  <li>講習を受講する</li>
  <li>近場の<strong>ユーザグループ</strong>に参加する
    <ul>
      <li>孤独はあなたの経歴によって避けるべき</li>
    </ul>
  </li>
  <li><strong>異なった環境</strong>に慣れ親しんでみる
    <ul>
      <li>Winのみで作業してきたのであれば、Linux環境に親しんでみる</li>
    </ul>
  </li>
  <li><strong>最先端</strong>にとどまり続ける
    <ul>
      <li>ニュースやオンライン投稿に目を通す</li>
    </ul>
  </li>
</ul>

<h5 id="継続は力なり">継続は力なり</h5>
<p><strong>数多くの小さな進歩を継続して積み重ねる</strong>。
スキルを日々磨き、新たなツールとレパートリーを増やしていく。</p>

<h2 id="開発手法">開発手法</h2>

<h4 id="チーム">チーム</h4>
<p>達人のチームは、10〜12人の<strong>小規模</strong>な構成になっている。
コードをエンドツーエンドで構築でき、インクリメンタルかつイテレーティブに開発できるチームを構成する。
チームメンバーに質問を投げかけると、<strong>すぐに答えが返ってくる</strong>ようになっているべき。
品質は、チームメンバー全員が個々に貢献することによってのみ達成できる。</p>

<h5 id="コンウェイの法則">コンウェイの法則</h5>
<p>開発しているプロダクトは、チームや組織の社会構造とコミュニケーション経路によって影響を受ける。</p>

<h4 id="ソフトウェアのエントロピー">ソフトウェアのエントロピー</h4>
<p>ソフトウェアも<strong>時間とともに無秩序</strong>になっていく。特に、<strong>プロジェクトの文化</strong>がソフトウェアの腐敗に大きな影響を与える。
ネガティブな考えには伝染性がある。放置は他のどのような要因よりも腐敗を「加速」させる。</p>

<h5 id="十分によいソフトウェア">十分によいソフトウェア</h5>
<p><strong>不可能なスケジュールを約束したり、納期に間に合わせるために基本的な技術面をおろそかにするのは、プロフェッショナルとしてあり得ない</strong>。</p>

<h4 id="見積もり">見積もり</h4>
<p>直感的にものごとの大きさを判断する。
見積もりを始める前に必ず問題領域について考える。
タスク（作業）ごとに「楽観的時間」、「最確時間」、「悲観的時間」の３つの時間を見積もる。</p>

<h4 id="万能な方策は存在しない">万能な方策は存在しない</h4>
<p>あらゆる方法論の良いところを<strong>抜き出し</strong>、利用できるように<strong>適合</strong>させる。
どんな状況にも適用できる万能の方策など存在しないため、普及している手法を１つ導入するだけでは済まない。</p>

<h5 id="あるべき方法">あるべき方法</h5>
<p>ソフトウェアを構築する唯一の方法は<strong>インクリメンタル</strong>に進めていくこと。
<strong>エンドツーエンドの小さな機能を構築</strong>し、そこから作業を進めながら問題について学習していく。</p>

<h5 id="アジャイルソフトウェア開発宣言">アジャイルソフトウェア開発宣言</h5>

<ul>
  <li>プロセスやツールよりも個人と対話を</li>
  <li>包括的なドキュメントよりも動くソフトウェアを</li>
  <li>契約交渉よりも顧客との協調を</li>
  <li>計画に従うことよりも変化への対応を</li>
</ul>

<h2 id="要件定義">要件定義</h2>

<h4 id="落とし穴">落とし穴</h4>
<p>要求とは通常、さまざまな仮定、誤解、政策の奥深くに埋められている。
<strong>自らが欲しているものを正確に認識している人などいない</strong>。
境界条件を探し出し、相談者に尋ねる。
要求はフィードバックループの中で学んでいく。
ユーザとともに働き、ユーザのように考える。
<strong>優れた要求は抽象的</strong>な記述からできあがっている。
要求とは「ニーズ」。
<strong>失敗プロジェクトの多くは、スコープの膨張が原因</strong>。
用語集を管理する。
プロジェクトの参加者は、全員、整合性を保証するためにこの用語集を使うべき。</p>

<h5 id="不可能なパズルを解決する">不可能なパズルを解決する</h5>
<p>ある制約は「絶対的なもの」であり、他のものは「<strong>単なる先入観</strong>」。</p>

<h4 id="曳光弾">曳光弾</h4>
<p>要求の段階で、システムの<strong>最終形態となるイメージ</strong>を目に見えるかたちで、<strong>何度も提示</strong>する。
最大のリスクを洗い出し、開発の優先順位を付ける。
コードは最小限だが、最終的には商用で利用する。</p>

<h5 id="目的">目的</h5>
<ul>
  <li>アプリケーション全体がどのように連携するのかを知る</li>
  <li>アーキテクチャ上の骨格を開発者に提示する</li>
</ul>

<h5 id="メリット">メリット</h5>
<ul>
  <li>テスト用プラットフォームになる
    <ul>
      <li>大々的な統合テストを実施するというビッグバン型の開発ではなく、毎日テストを実施できるようになる</li>
    </ul>
  </li>
  <li>進捗が明確になる
    <ul>
      <li>ユースケース単体で作業に取り組める</li>
    </ul>
  </li>
</ul>

<h4 id="プロトタイプ">プロトタイプ</h4>
<p>曳光弾の前に行う偵察、諜報活動。コードは破棄する。
コードではなく、学んだ教訓に勝ちがある。</p>

<h2 id="設計">設計</h2>

<h4 id="よい設計の本質">よい設計の本質</h4>
<p><strong>ETC原則 … Easier To Change（変更をしやすくする）</strong></p>

<p>世の中の設計原則は、ETC原則を特殊化したもの。
ETCは「ルール」ではなく「価値」。
常に<strong>「簡単に変更できる」という究極の選択肢を採用</strong>する。
鍵は「疎結合」と「高凝集」。</p>

<h4 id="dry原則">DRY原則</h4>
<p><strong>DRY原則 … Don’t Repeat Yourself（繰り返しを避ける）</strong></p>

<p>DRY原則は<strong>知恵や意図の二重化</strong>についての原則であり、
コードの二重化すべてが知識の二重化というわけではない。
あなたが行うべきことは、既にあるものを<strong>簡単に見つけ出して再利用できる</strong>ようにして、
同じものを何度も作成しないような<strong>環境を構築</strong>すること。
コードの二重化は、構造に問題がある証拠。</p>

<h5 id="開発者間で発生する二重化">開発者間で発生する二重化</h5>
<p>さまざまなところで必要となり、明確に責務を分類できない機能やデータは、何度も実装されてしまう。
開発者間での<strong>活発かつ頻繁なコミュニケーション</strong>が奨励される。</p>

<h4 id="直交性">直交性</h4>
<p>直交性とは、独立性であり、結合度を表す。
片方を変更しても他方に影響を与えない場合、それらは直行している。
直行していないシステムは本質的に変更や制御が難しくなる。
自己完結したコンポーネント（<strong>「凝集度」の高いコンポーネント</strong>）を設計するべき。</p>

<h5 id="メリット-1">メリット</h5>
<ul>
  <li>変更が局所化され、開発期間とテスト期間が短縮される</li>
  <li>再利用が促進される</li>
  <li>コンポーネントの組み合わせが容易になり、最小努力で多くの機能を手に入れられる</li>
</ul>

<h5 id="結合度の最小化">結合度の最小化</h5>
<p>不必要な情報は他のモジュールに<strong>公開せず</strong>、また、他のモジュールの<strong>実装を当てにしない</strong>記述を心がける。
オブジェクトの状態を変更する必要があるのであれば、それをオブジェクト自身に行わせる。</p>

<p>あるモジュールがデータ構造を露出させる時、そのデータ構造を使用するすべてのコードが該当モジュールの実装と結合する。
そのため、オブジェクトの属性を読み書きする際には、<strong>可能な限りアクセッサー関数</strong>を使用する。</p>

<h5 id="グローバル変数を避ける">グローバル変数を避ける</h5>
<p>グローバル変数の使用は、データを共有しているコンポーネント同士を結びつける。</p>

<h5 id="テスト">テスト</h5>
<p>直交性を念頭に置いた設計、実装されたシステムは、テストが簡単になる。
<strong>ユニットテストの記述自体が、直交性の興味深いテストになる</strong>。</p>

<h4 id="並行性">並行性</h4>

<ul>
  <li>並行処理
    <ul>
      <li>同時に実行されているように振る舞うこと</li>
      <li>ソフトウェアのメカニズム</li>
    </ul>
  </li>
  <li>並列処理
    <ul>
      <li>本当に同時に実行されていること</li>
      <li>ハードウェアの関心事</li>
    </ul>
  </li>
</ul>

<h5 id="時間的な結合を破壊する">時間的な結合を破壊する</h5>
<p>アーキテクチャの設計に取りかかったり、プログラムを書いたりする際には、ものごとは線形になりがち。
こういったアプローチでは<strong>柔軟性、現実性ともに乏しいものとなる</strong>。</p>

<h4 id="アーキテクチャ">アーキテクチャ</h4>
<p>アーキテクチャーは移り変わる。<strong>流行を追い求めない</strong>ようにする。
できることは変更を容易にすることだけ。<strong>抽象化レイヤーで隠蔽</strong>する。</p>

<h2 id="コーディング">コーディング</h2>
<p>プログラムを長期間にわかって正確かつ生産的なものに保つには、熟考や熟慮を要する意思決定が常に必要。
達人プログラマーは自分自身のコードを含めたすべてのコードに対して<strong>常に批判的な目</strong>を向ける。
テストの主な利点は、テストについて考え、テストを作り出している時に生み出される。</p>

<h4 id="契約による設計dbc">契約による設計（DbC）</h4>
<p>「コンポーネント間で”契約”を交わし、その契約を守る限りバグは起きにくい」という考え方。</p>

<table>
  <thead>
    <tr>
      <th style="text-align: left">用語</th>
      <th style="text-align: left">役割</th>
      <th style="text-align: left">例（<code class="language-plaintext highlighter-rouge">sqrt(x)</code>）</th>
      <th style="text-align: left">責務</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left">前提条件</td>
      <td style="text-align: left">呼び出し側が守るべき条件</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">x &gt;= 0</code></td>
      <td style="text-align: left">呼び出し側の責務</td>
    </tr>
    <tr>
      <td style="text-align: left">後続条件</td>
      <td style="text-align: left">実装側が保証する結果</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">result^2 == x</code></td>
      <td style="text-align: left">実装側の責務</td>
    </tr>
    <tr>
      <td style="text-align: left">不変条件</td>
      <td style="text-align: left">オブジェクトやデータ構造が常に満たすべき性質</td>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">balance &gt;= 0</code></td>
      <td style="text-align: left">実装側の責務</td>
    </tr>
  </tbody>
</table>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">assert</span><span class="p">(</span><span class="nx">cond</span><span class="p">:</span> <span class="nx">unknown</span><span class="p">,</span> <span class="nx">msg</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="nx">asserts</span> <span class="nx">cond</span> <span class="p">{</span>
  <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">cond</span><span class="p">)</span> <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s2">`Contract violated: </span><span class="p">${</span><span class="nx">msg</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nx">BankAccount</span> <span class="p">{</span>
  <span class="k">private</span> <span class="nx">_bal</span><span class="p">:</span> <span class="kr">number</span><span class="p">;</span>
  <span class="kd">constructor</span><span class="p">(</span><span class="nx">initial</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// 前提条件チェック</span>
    <span class="nx">assert</span><span class="p">(</span><span class="nx">initial</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">,</span> <span class="dl">"</span><span class="s2">initial ≥ 0</span><span class="dl">"</span><span class="p">);</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_bal</span> <span class="o">=</span> <span class="nx">initial</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">inv</span><span class="p">();</span>
  <span class="p">}</span>
  <span class="kd">get</span> <span class="nx">balance</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_bal</span><span class="p">;</span> <span class="p">}</span>

  <span class="nx">withdraw</span><span class="p">(</span><span class="nx">amount</span><span class="p">:</span> <span class="kr">number</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// 前提条件チェック</span>
    <span class="nx">assert</span><span class="p">(</span><span class="nx">amount</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">,</span> <span class="dl">"</span><span class="s2">withdraw &gt; 0</span><span class="dl">"</span><span class="p">);</span>
    <span class="nx">assert</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_bal</span> <span class="o">&gt;=</span> <span class="nx">amount</span><span class="p">,</span> <span class="dl">"</span><span class="s2">sufficient funds</span><span class="dl">"</span><span class="p">);</span>
    <span class="kd">const</span> <span class="nx">before</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_bal</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_bal</span> <span class="o">-=</span> <span class="nx">amount</span><span class="p">;</span>
    <span class="c1">// 後続条件チェック</span>
    <span class="nx">assert</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_bal</span> <span class="o">===</span> <span class="nx">before</span> <span class="o">-</span> <span class="nx">amount</span><span class="p">,</span> <span class="dl">"</span><span class="s2">post: bal decreased</span><span class="dl">"</span><span class="p">);</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">inv</span><span class="p">();</span>
  <span class="p">}</span>

  <span class="c1">// 不変条件チェック</span>
  <span class="k">private</span> <span class="nx">inv</span><span class="p">()</span> <span class="p">{</span> <span class="nx">assert</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_bal</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">,</span> <span class="dl">"</span><span class="s2">balance non-negative</span><span class="dl">"</span><span class="p">);</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h4 id="インヘリタンス相続税">インヘリタンス（相続）税</h4>
<p><strong>継承を使わない</strong>。</p>

<h5 id="問題点">問題点</h5>

<ul>
  <li>コード共有のために使う
    <ul>
      <li>結合を生む</li>
    </ul>
  </li>
  <li>型構築のために使う
    <ul>
      <li>複雑さが増す</li>
    </ul>
  </li>
</ul>

<h5 id="優れた代替">優れた代替</h5>
<p>以下の代替によって、継承を使わなくて済むようになる。</p>

<ul>
  <li><strong>委譲</strong>
    <ul>
      <li>機能の追加ができる</li>
      <li>has-a は is-a に勝る
        <ul>
          <li>has-a … A has a B AはBをプロパティとして持つ</li>
          <li>is-a … AはBを継承する</li>
        </ul>
      </li>
    </ul>
  </li>
  <li><strong>インターフェースとプロトコル</strong>
    <ul>
      <li>型情報を共有できる</li>
      <li>ポリモーフィズムを実現できる</li>
    </ul>
  </li>
  <li>mixin と trait
    <ul>
      <li>手段の共有ができる</li>
    </ul>
  </li>
</ul>

<h4 id="変換のプログラミング">変換のプログラミング</h4>
<p><strong>ある形式のデータや構造を別の形式に変換する処理を軸としたプログラミング手法</strong>。</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">names</span> <span class="o">=</span> <span class="nx">users</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">user</span> <span class="o">=&gt;</span> <span class="nx">user</span><span class="p">.</span><span class="nx">name</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">upper</span> <span class="o">=</span> <span class="nx">text</span><span class="p">.</span><span class="nx">toUpperCase</span><span class="p">();</span>
<span class="kd">const</span> <span class="nx">ids</span> <span class="o">=</span> <span class="nx">data</span><span class="p">.</span><span class="nx">filter</span><span class="p">(</span><span class="nx">d</span> <span class="o">=&gt;</span> <span class="nx">d</span><span class="p">.</span><span class="nx">active</span><span class="p">).</span><span class="nx">map</span><span class="p">(</span><span class="nx">d</span> <span class="o">=&gt;</span> <span class="nx">d</span><span class="p">.</span><span class="nx">id</span><span class="p">);</span>
</code></pre></div></div>

<h5 id="メリット-2">メリット</h5>
<ul>
  <li>副作用が少ない（元データを破壊しない）</li>
  <li>テストしやすい（入力と出力が明確）</li>
  <li>可読性が高い（意図が明確）</li>
  <li>再利用性・合成がしやすい（小さな関数の組み合わせで大きな処理）</li>
  <li>非同期処理などとの相性が良い</li>
</ul>

<h4 id="分離">分離</h4>
<p><strong>結合は変更の敵</strong>。
結合によって、離れた場所にある２つのものごとの整合性を常に取る必要が生み出され、
一方を変更した際に必ずもう一方も変更しなければならなくなる。</p>

<h5 id="tda原則tell-dont-ask">TDA原則（Tell, Don’t Ask）</h5>
<p>「<strong>教えるな、命令せよ</strong>」という設計原則。</p>

<p>悪い例</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">if</span> <span class="p">(</span><span class="nx">account</span><span class="p">.</span><span class="nx">getBalance</span><span class="p">()</span> <span class="o">&gt;=</span> <span class="nx">amount</span><span class="p">)</span> <span class="p">{</span>
  <span class="nx">account</span><span class="p">.</span><span class="nx">withdraw</span><span class="p">(</span><span class="nx">amount</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>良い例</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">account</span><span class="p">.</span><span class="nx">withdrawIfPossible</span><span class="p">(</span><span class="nx">amount</span><span class="p">);</span>
</code></pre></div></div>

<h4 id="キャッチリリースは魚釣りだけに">キャッチ＆リリースは魚釣りだけに</h4>
<p><strong>早めにクラッシュ</strong>させる。多くの場合、プログラムのクラッシュは最も正しい行いとなる。</p>

<p>達人のコード利点</p>
<ul>
  <li>エラーハンドリングが<strong>コードに埋もれない</strong></li>
  <li>コードの<strong>結合度を下げる</strong></li>
</ul>

<p>凡人のコード</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">try</span> <span class="p">{</span>
    <span class="nx">addScoreToBoard</span><span class="p">(</span><span class="nx">score</span><span class="p">);</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">error</span> <span class="k">instanceof</span> <span class="nx">InvalidScoreError</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="dl">"</span><span class="s2">Can't add invalid score. Exiting</span><span class="dl">"</span><span class="p">);</span>
        <span class="k">throw</span> <span class="nx">error</span><span class="p">;</span>
    <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">error</span> <span class="k">instanceof</span> <span class="nx">BoardServerDownError</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="dl">"</span><span class="s2">Can't add score: board is down. Exiting</span><span class="dl">"</span><span class="p">);</span>
        <span class="k">throw</span> <span class="nx">error</span><span class="p">;</span>
    <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">error</span> <span class="k">instanceof</span> <span class="nx">StaleTransactionError</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="dl">"</span><span class="s2">Can't add score: stale transaction. Exiting</span><span class="dl">"</span><span class="p">);</span>
        <span class="k">throw</span> <span class="nx">error</span><span class="p">;</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="k">throw</span> <span class="nx">error</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>達人のコード</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">addScoreToBoard</span><span class="p">(</span><span class="nx">score</span><span class="p">);</span>
</code></pre></div></div>

<h4 id="アルゴリズムのスピード">アルゴリズムのスピード</h4>
<p>単純なループを記述している場合であっても、それが<code class="language-plaintext highlighter-rouge">O(n)</code>アルゴリズムであるということを<strong>意識</strong>する。
アルゴリズムのオーダーを見積もること。</p>

<p><img src="/assets/2025-07-17-the-pragmatic-programmer/algorithm-runtime.png" alt="algorithm-runtime" /></p>

<table>
  <thead>
    <tr>
      <th style="text-align: left"><code class="language-plaintext highlighter-rouge">O</code>記法</th>
      <th style="text-align: left">概要</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">O(1)</code></td>
      <td style="text-align: left">定数（配列の要素へのアクセス、単純なステートメント）</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">O(log n)</code></td>
      <td style="text-align: left">対数（バイナリサーチ）対数の底はあまり関係ない</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">O(n)</code></td>
      <td style="text-align: left">線形（シーケンシャルサーチ）</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">O(n log n)</code></td>
      <td style="text-align: left">線形対数（クイックソート、ヒープソート）線形よりも悪いが、最悪というわけでもない</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">O(n^2)</code></td>
      <td style="text-align: left">２乗（選択ソートや挿入ソート）</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">O(n^3)</code></td>
      <td style="text-align: left">３乗（２つの行列 n x n の積）</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">O(C^n)</code></td>
      <td style="text-align: left">指数（巡回セールスマン問題、集合分割）</td>
    </tr>
  </tbody>
</table>

<h5 id="最善は常に最善ではない">最善は常に最善ではない</h5>
<p>アルゴリズムの改良は、それが本当に<strong>ボトルネックになっていることを確認してから</strong>行うべき。</p>

<h4 id="コードのためのテスト">コードのためのテスト</h4>
<p>テストは、<strong>コーディングの指針を与えてくれる極めて重要なフィードバック</strong>。
メソッドのテスト記述を考えることで、ユーザという観点に立ち、外部からメソッドを客観的に捉えられるようになる。</p>

<h5 id="テスト文化">テスト文化</h5>
<p><strong>テストコードは本番のコードと同じくらい慎重に扱う</strong>。
結合を低く抑え、クリーンかつ堅牢にしておく。
テストがプログラミングの一部であることを忘れない。</p>

<h5 id="達人のスターターキット">達人のスターターキット</h5>
<p><strong>早めにテスト、何度もテスト、自動でテスト</strong>。
優れたプロジェクトでは「成果物のコードよりも多くのテストコード」が存在する。
コードのカバレッジではなく、<strong>状態のカバレッジ</strong>をテストする。
バグが既存のテストの網の目をくぐり抜けたのであれば、次回はそれを捕まえることのできる新たなテストを追加する。</p>

<h5 id="テスト駆動コーディング">テスト駆動コーディング</h5>
<p>とにかくTDDを実践する。</p>

<p>テストについて考えることで、</p>
<ul>
  <li>コードの結合度が低下する（データベース接続を引き渡す等）</li>
  <li>柔軟性が向上する（テスト対象のフィールド名をパラメータにする等）</li>
</ul>

<h5 id="契約に対するテスト">契約に対するテスト</h5>
<p>契約が遵守されていることを確認するテストケースを記述する。</p>

<h5 id="プロパティベースのテスト">プロパティベースのテスト</h5>
<p>このテストでは、テスト時にランダムな値を生成する。
このテストでは、不変性と契約という観点からコードについて考えさせてくれる。</p>

<h4 id="リファクタリング">リファクタリング</h4>

<h5 id="いつリファクタリングを行うべきか">いつリファクタリングを行うべきか？</h5>
<p>「おかしなもの」に遭遇した時。</p>

<p>リファクタリングを避ける言い訳として、納期というプレッシャーがよく用いられる。
そういった理由でリファクタリングをやめてはいけない。
今リファクタリングすることをやめれば、将来問題が発生した際、
今以上に多くの依存関係を考慮しながら問題修復をするために大量の時間投資が必要になる。</p>

<p><strong>早めにリファクタリングすること、そしてこまめにリファクタリングすること</strong>。</p>

<h5 id="どのようにリファクタリングするか">どのようにリファクタリングするか？</h5>

<ol>
  <li>リファクタリングと機能の追加を同時に行わない</li>
  <li><strong>テスト</strong>を用意する</li>
  <li>小さな単位に作業をまとめ、慎重に進める</li>
</ol>

<h4 id="偶発的プログラミング">偶発的プログラミング</h4>
<p><strong>その場しのぎ</strong>でコードが構築されてしまうこと。または、<strong>本来意図しない</strong>形で「たまたま動いてしまうコード」を書いてしまうこと。
「とにかく今動いているんだから触らないほうがいい」と、簡単にこういった考え方に陥ってしまう。</p>

<h5 id="暗黙の仮定">暗黙の仮定</h5>
<p>すべての段階で、人々は心の中に多くの仮定を置いて作業を進めている。
しっかりとした事実に基づいていない仮定は、すべてのプロジェクトにとって有害なものとなる。</p>

<h4 id="ストループ効果">ストループ効果</h4>
<p><strong>単語は最優先で処理</strong>される。
何かに名前を付ける場合、常に自らの意図を明確にする方法を探し求める。</p>

<h4 id="リソースのバランス方法">リソースのバランス方法</h4>
<p>ファイル参照をどこかに保持しておくのではなく、パラメータとして引き渡すようにする。</p>

<h4 id="設定">設定</h4>
<p>変更する必要があると分かっているデータは、コードの外に出す。
外部に出した設定は、APIの裏側などに隠す。
設定の表現という詳細とコードを分離する。</p>

<h4 id="セキュリティの基本原則">セキュリティの基本原則</h4>

<ul>
  <li>攻撃界面を最小化する
    <ul>
      <li>複雑なコードは攻撃ベクターにつながる
        <ul>
          <li><strong>シンプルで小さなコード</strong>が優れている</li>
        </ul>
      </li>
      <li>出力データは攻撃ベクターとなる
        <ul>
          <li><strong>むやみに情報を提供してはいけない</strong></li>
        </ul>
      </li>
      <li>デバッグ情報は攻撃ベクターとなる
        <ul>
          <li>デバッギングを容易にするための情報は、ハッキングも容易にする</li>
        </ul>
      </li>
    </ul>
  </li>
  <li><strong>最小権限</strong>にする</li>
  <li>デフォルトをセキュアなものにする</li>
  <li>機密データを暗号化する</li>
  <li>セキュリティアップデートを適用する</li>
</ul>

<h2 id="ツール">ツール</h2>
<p>常に道具を増やすことを心がける。何をするにも<strong>常によりよい方法を探す</strong>ように心がける。</p>

<ul>
  <li>シェル
    <ul>
      <li>慣れ親しむことで生産性が向上する</li>
    </ul>
  </li>
  <li>パワーディット
    <ul>
      <li>繰り返し作業に「もっとよい方法があるはずた」と考える</li>
      <li>オートリピートを使わない</li>
      <li>マウス・トラックパッドを使わない</li>
    </ul>
  </li>
  <li>バージョン管理
    <ul>
      <li><strong>すべてのもの</strong>がバージョン管理されているようにする</li>
    </ul>
  </li>
  <li>デバッグ
    <ul>
      <li>常に<strong>問題の原因の根</strong>を見つけるように努力する</li>
      <li>緻密な観察を心がける</li>
      <li>デバッグの戦略
        <ol>
          <li><strong>バグを再現する</strong></li>
          <li><strong>テストを失敗される</strong>
            <ul>
              <li>テスト作成によってソリューションが見えてくる</li>
            </ul>
          </li>
        </ol>
      </li>
      <li>アプリがライブラリ・APIを<strong>正しく呼び出していない</strong>と考えたほうが一般的に正しい
        <ul>
          <li>バグがOSやサードパーティ製品内に内在する可能性もあるが、
そういった考えを最初に持つべきではない</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>テキスト操作言語
    <ul>
      <li>データをプレーンテキストで保存し、これらの言語を使用して操作する</li>
    </ul>
  </li>
</ul>
<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1" role="doc-endnote">
      <p>本ブログは「本を読み、理解した内容の備忘録（自分用）」を目的としている。重要なアイディアを昇華させ、自分の言葉でまとめるように努めている <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2" role="doc-endnote">
      <p>内容に不快を感じ、ブログの取り下げを希望される著作者の方は、個別にご連絡いただけると幸いに思う <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name></name></author><category term="tech" /><category term="craft" /><category term="reading" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">やり抜く力</title><link href="https://blog.o3osatoshi.engr.work/life/grit" rel="alternate" type="text/html" title="やり抜く力" /><published>2025-06-25T15:00:00+00:00</published><updated>2025-06-25T15:00:00+00:00</updated><id>https://blog.o3osatoshi.engr.work/life/grit</id><content type="html" xml:base="https://blog.o3osatoshi.engr.work/life/grit"><![CDATA[<p><img src="/assets/2025-06-26-grit/thumbnail.png" alt="thumbnail" /></p>

<p>※本ブログの目的と内容<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup>、著作者の方へ<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote" rel="footnote">2</a></sup></p>

<h2 id="達成の心理学">達成の心理学</h2>
<p>鉄人（大きな成功を収めた人たち）は、「<strong>やり抜く力（情熱・粘り強さ）</strong>」を持っている。</p>

<h3 id="達成の方程式">達成の方程式</h3>
<p><strong>努力は才能の2倍重要</strong>。努力によって才能はスキルになり、努力によってスキルが生きる。</p>

<ul>
  <li><strong>才能 x 努力 = スキル</strong></li>
  <li><strong>スキル x 努力 = 達成</strong></li>
</ul>

<h4 id="鉄人の神格化">鉄人の神格化</h4>
<p>常人の域をはるかに超えたパフォーマンスに圧倒され、それがすさまじい訓練と経験の積み重ねの成果であることが想像できないと、
なにも考えずにただ「生まれつき才能がある人」と決めつけてしまう。</p>

<h3 id="目標のピラミッド">目標のピラミッド</h3>
<p>目標のピラミッドが全体としてひとつにまとまり、各目標が関連性をもって、整然と並んでいる状態が望ましい。
たったひとつの究極の目標があり、ほぼすべての行動がその目標達成に向けられている。</p>

<p><img src="/assets/2025-06-26-grit/target-diagram.png" alt="target-diagram" /></p>

<p><strong>粘り強さ（必死に努力したり、挫折から立ち直ったり）よりも、情熱（長い間わき目もふらずに、同じ目標にずっと集中し続ける）の方がはるかに大変</strong>。
人間のどんなにとてつもない偉業も、実際は小さなことをたくさん積み重ねた結果。</p>

<ul>
  <li>重要度の高い目標 … 粘り強く努力を続ける（安易に妥協しない）</li>
  <li>重要度の低い目標 … 臨機応変に態度を切り替える（ほかのやり方を試す）</li>
</ul>

<h4 id="目標達成法">目標達成法</h4>

<ol>
  <li>目標を25個書き出す</li>
  <li>重要な5つにマルをつける</li>
  <li>残りの20個には関わらない</li>
</ol>

<p>「同じ目的」につながる目標を生かす。時間とエネルギーは限られている。</p>

<h2 id="やり抜く力を伸ばす">「やり抜く力」を伸ばす</h2>
<p>大変な方法は独力（内側）でがんばること。ラクな方法は同調性（外側）を利用すること。
私たちがどんな人間になるかは、「遺伝子」と「経験」の相互作用によって決まる。</p>

<h3 id="内側">内側</h3>

<ol>
  <li><strong>興味</strong>（初期）
    <ul>
      <li>自分がいちばん楽しいと思うことを見つけ、それに取り組む（仕事にする）
        <ul>
          <li>満足度と業績が高くなる</li>
        </ul>
      </li>
      <li>やりたいものが見つかるまでにはかなりの時間がかかる
        <ul>
          <li>子どものころには早すぎてわからない</li>
          <li>内省ではなく、外界との交流で生まれる</li>
        </ul>
      </li>
      <li>初心者のうちにあまり厳しくすると、せっかく芽生えた興味が台なしになってしまう</li>
      <li>興味を持続させるには、みずから積極的に掘り下げ、深めていく必要がある
        <ul>
          <li>自分から積極的に行動することが大事</li>
        </ul>
      </li>
    </ul>
  </li>
  <li><strong>練習</strong>（中期）
    <ul>
      <li><strong>意図的な練習</strong>を行う
        <ol>
          <li><strong>高めの目標</strong>を設定する</li>
          <li>集中して目標達成を目指す
            <ul>
              <li>フィードバックを求める</li>
            </ul>
          </li>
          <li>何度も繰り返して練習する</li>
        </ol>
      </li>
      <li><strong>ひとりで練習</strong>する時間が多い人ほど、スキルの上達が早い</li>
      <li>小さな弱点の克服を<strong>こつこつと積み重ねていく</strong>ことが、驚異的な熟練の境地に至る道</li>
      <li>時間の長さよりも「<strong>どんな練習</strong>をしているか」が重要</li>
      <li>「<strong>ルーティン</strong>（毎日同じ時間同じ場所）」として「意図的な練習」に取り組む
        <ul>
          <li>大変なことをするのにルーティンにまさる手段はない</li>
        </ul>
      </li>
    </ul>
  </li>
  <li><strong>目的</strong>（後期）
    <ul>
      <li>「他の人々にとって重要な意味を持つ」と思うこと</li>
      <li>社会のことも考えて行動する人のほうが、長い目で見て成功する確率が高い
        <ul>
          <li>ただし「興味」がないと、大きな努力に結びつくことはない</li>
        </ul>
      </li>
      <li>レンガ職人の寓話
        <ol>
          <li>レンガを積んでいる
            <ul>
              <li>仕事（生きるために必要なこと）</li>
            </ul>
          </li>
          <li>教会をつくっている
            <ul>
              <li>キャリア（もっといい仕事に移るためのステップ）</li>
            </ul>
          </li>
          <li>歴史に残る大聖堂を造っている
            <ul>
              <li>天職（人生でいちばん大切なもののひとつ）</li>
            </ul>
          </li>
        </ol>
      </li>
      <li>肩書よりも重要なのは、本人が自分の仕事をどう見なしているか</li>
    </ul>
  </li>
  <li><strong>希望</strong>
    <ul>
      <li>成長思考 → 楽観的に考える → 逆境でも粘り強くがんばれる</li>
      <li>楽観主義者と悲観主義者（鉄人は楽観的）
        <ul>
          <li><strong>楽観主義者</strong> … <strong>苦しみは一時的で特定の原因があると考える</strong></li>
          <li>悲観主義者 … 苦しみを変えようがない原因のせいにし、自分にはどうすることもできないと考える</li>
        </ul>
      </li>
      <li>成長思考と固定思考（鉄人は成長思考）
        <ul>
          <li><strong>成長思考</strong> … <strong>努力すればきっとうまくできると信じる</strong></li>
          <li>固定思考 … 挫折の経験を自分には能力がない証拠だと解釈する</li>
        </ul>
      </li>
      <li>身近な大人の成長志向を子どもはまねる</li>
      <li><strong>「逆境を乗り越えた経験（がんばればどうにかなった経験）」がレジリエンスを高める</strong>
        <ul>
          <li><strong>脳は「筋肉」のように鍛えられる</strong></li>
        </ul>
      </li>
    </ul>
  </li>
</ol>

<h3 id="外側">外側</h3>

<h4 id="賢明な育て方">賢明な育て方</h4>
<p>賢明な育て方とは、<strong>支援は惜しまない</strong>が、<strong>要求は厳しい</strong>育て方のこと。
賢明な教師など、親以外にも「支援」と「自信」を与えてくれる人との出会いが重要。</p>

<h4 id="親をまねる">親をまねる</h4>
<p><strong>子どもは親をお手本にし、やることをまねる</strong>。
親自身が「努力家で、なにかに挑戦するときは全力を尽くし、楽しみよりもやるべきことを優先させ、遠い目標に向かって努力する」姿を子どもに見せる。</p>

<h5 id="やり抜く力が身につく4つの家庭ルール">「やり抜く力」が身につく4つの家庭ルール</h5>

<ol>
  <li>ハードなことに挑戦しなければならない
    <ul>
      <li>「ハードなこと」とは、「意図的な練習」のこと</li>
    </ul>
  </li>
  <li>やめてもよい
    <ul>
      <li>ただし区切りの時期がくるまではやめてはならない</li>
      <li>無理に続けても機会損失の可能性がある</li>
    </ul>
  </li>
  <li>自分で選ぶ</li>
  <li>2年間は続けなければならない</li>
</ol>

<h4 id="適応の母">適応の母</h4>
<p>「やり抜く力」を強化するには、「やり抜く力」の強い文化を見つけ、その一員となる。
自分が属している文化の影響をあらゆる面で強く受ける。</p>

<p>「<strong>環境</strong>」が変わると、一瞬で自分が変わる。私たちは必要に迫られれば変化する。
慣れない状況のなかでがんばっていくうちに、やがて新しい考え方や行動が身について習慣となる。</p>

<h5 id="社会的相乗効果">社会的相乗効果</h5>
<p>バスケがうまくなるコツは、自分よりややスキルの高い仲間と一緒にプレーすること。
なにかを本当にうまくなりたいと思ったら、<strong>自分の能力以上に背伸びする</strong>必要がある。</p>

<h4 id="課外活動">課外活動</h4>
<p>学校の勉強以外に、楽しんで取り組めるような習いごとや活動を見つけて、かよわせる。
重要なのは、やろうと決めたことを、1年たってもやめずに翌年も続け、そのあいだに何らかの進捗を遂げること。
課外活動の継続年数は、大学の卒業率や就職率、収入の向上に影響を与える。</p>

<h2 id="その他">その他</h2>

<ul>
  <li>成熟の原則 … ほとんどの人は人生経験を重ねるにつれ、より誠実になり、自信や思いやりが増し、穏やかになる</li>
  <li>対応原則 … 人は自分の性格に適した状況に引き寄せられるが、その結果、さらにその特徴が強化される</li>
  <li>学習性勤勉性 … 勤勉さは練習によって身につけられる</li>
  <li>グリット・スケールが高いと、幸福感や健康状態も良い</li>
  <li>ベテランが目新しいと感じるのは微妙な差異（ニュアンス）なのだ</li>
</ul>
<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1" role="doc-endnote">
      <p>本ブログは「本を読み、理解した内容の備忘録（自分用）」を目的としている。重要なアイディアを昇華させ、自分の言葉でまとめるように努めている <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2" role="doc-endnote">
      <p>内容に不快を感じ、ブログの取り下げを希望される著作者の方は、個別にご連絡いただけると幸いに思う <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name></name></author><category term="life" /><category term="reading" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">営業</title><link href="https://blog.o3osatoshi.engr.work/biz/sales" rel="alternate" type="text/html" title="営業" /><published>2025-06-08T15:00:00+00:00</published><updated>2025-06-08T15:00:00+00:00</updated><id>https://blog.o3osatoshi.engr.work/biz/sales</id><content type="html" xml:base="https://blog.o3osatoshi.engr.work/biz/sales"><![CDATA[<p><img src="/assets/2025-06-09-sales/thumbnail.png" alt="thumbnail" /></p>

<p>※本ブログの目的と内容<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup>、著作者の方へ<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote" rel="footnote">2</a></sup></p>

<h2 id="序論">序論</h2>
<p>時代は「御用聞き営業」から「<strong>仮説営業</strong>（顧客に会う前にニーズの仮説を準備する）」へと変化している。
営業としての成長とは、能動的に「型」の数を増やすこと。</p>

<h4 id="セールス重視からマーケティング重視へ">「セールス重視」から「マーケティング重視」へ</h4>
<p>「顧客をどう説得するか」より、「<strong>どの顧客を説得するか</strong>」の方がインパクトが大きい。</p>

<ul>
  <li>内勤営業（インサイドセールス） … アポ前</li>
  <li>外勤営業（セールス） … アポ後</li>
</ul>

<h2 id="仮説営業に必要な力">仮説営業に必要な力</h2>

<ol>
  <li><strong>仮説思考力</strong>
    <ul>
      <li>仮説思考とは、課題の原因を推論し、それを検証するマインドセットのこと</li>
      <li>妄想で終わらせず、実行に移して検証し続けることが重要</li>
      <li>顧客の課題（ニーズ）の特定で本領を発揮する</li>
    </ul>
  </li>
  <li><strong>因数分解力</strong>
    <ul>
      <li>できるだけ細かく分解する</li>
      <li>大きな数値目標は必ず分解する
        <ul>
          <li>年間売上目標は、月単位などに分解する</li>
        </ul>
      </li>
      <li>コツ
        <ul>
          <li>プロセスで切る</li>
          <li>「量 x 質」で切る</li>
          <li>MECEを意識する</li>
          <li>やるべきことが明確になるまで分解を続ける</li>
          <li>課題を分解しても、解決策を分解してもいい</li>
          <li>分解できたと思ったら、さらに１段深堀りしてみる</li>
        </ul>
      </li>
    </ul>
  </li>
  <li><strong>確率論的思考法</strong>
    <ul>
      <li>営業は確率の世界</li>
    </ul>
  </li>
  <li><strong>PDCAを回し続ける力</strong>
    <ul>
      <li>PDCAにおける<strong>計画（＝課題に対する解決策）はすべて仮説</strong></li>
      <li>サイクルを回して仮説が定説になったものが、営業が増やすべき「型」</li>
      <li>PDCAでもっとも難しいことは、PDCAサイクル自体を続けること
        <ul>
          <li>習慣づけるコツは、同時に多くのPDCAサイクルを回さないことと、大きな課題に取り組まないこと</li>
        </ul>
      </li>
      <li>ステップ
        <ol>
          <li>ゴールを定量化する（KGIの設定）
            <ul>
              <li>あらゆるPDCAは、たどり着きたいゴールを決めることから始まる</li>
              <li>ポイントは、期日、定量化、具体性</li>
              <li>定性的な目標であっても、それを数値化し、具体的に把握しやすい状態に置き換える</li>
            </ul>
          </li>
          <li>現状とのギャップを洗い出す</li>
          <li>ギャップを埋める課題を考える</li>
          <li>課題を優先度づけして３つに絞る
            <ul>
              <li>タスクを同時に抱えすぎるとフォーカスポイントが曖昧になって成果が思うように出せなくなる</li>
            </ul>
          </li>
          <li>各課題をKPI化する
            <ul>
              <li>KPIは、ゴールに近づくための「サブゴール」</li>
            </ul>
          </li>
          <li>KPIを達成する解決案を考える</li>
          <li>解決案を優先度づけする</li>
        </ol>
      </li>
    </ul>
  </li>
</ol>

<h2 id="マーケティングプロセス">マーケティングプロセス</h2>

<ol>
  <li>リスト選定・顧客の絞り込み
    <ul>
      <li>リスト選定にもPDCAが効く
        <ul>
          <li><strong>仮説を立てたらまずは小さく試す</strong></li>
        </ul>
      </li>
      <li><strong>「もっといいリストはないか」と問い続ける</strong>
        <ul>
          <li>最重要顧客のペルソナをひたすら考える</li>
        </ul>
      </li>
      <li>「顧客は<strong>すでに課題への理解があるか否か</strong>」も重要な因子</li>
    </ul>
  </li>
  <li>情報収集とニーズの仮説構築
    <ul>
      <li>ファーストコンタクトで自分のことを「ただの営業」だと思われるのか「<strong>使えそうな営業</strong>」だと思ってもらえるのかで、
天と地の差が生まれることをもっと意識すべき</li>
      <li>経営課題の仮説を立てるのは決して簡単なことではない
        <ul>
          <li>企業の事業モデル、業界の動向等、自分が経営者になったつもりでありとあらゆる情報を持っていないといけない</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>アプローチ
    <ul>
      <li>流れ作業でアプローチしていると思われないか、下心（営業色）を消せるかが勝負</li>
      <li>営業をかけるなら決済者をダイレクトに攻める</li>
      <li><strong>受付突破率こそが営業プロセスの最大のボトルネック</strong></li>
      <li>受付突破の２大パターン
        <ol>
          <li><strong>自分と相手（経営者や決済者）との関係性</strong>を感じてもらう</li>
          <li><strong>提案と相手のニーズとの関係性</strong>を感じてもらう</li>
        </ol>
      </li>
    </ul>
  </li>
  <li>見込み顧客管理
    <ul>
      <li>見込み顧客管理の目的
        <ul>
          <li>時間効率の最大化</li>
          <li>適切なタイミングで機動的に提案しにいける</li>
        </ul>
      </li>
      <li>中期・長期の顧客は、自分の手間をかけないで関係性を維持する</li>
    </ul>
  </li>
  <li>面談
    <ul>
      <li>ニーズ喚起が重要</li>
      <li>相手の課題の遠からず近からずのところから始めて、いつの間にか本題に入る
流れを切らないことが重要
        <ul>
          <li>「相手が話したいことで、なおかつ普段話せないこと」を話題に選ぶ</li>
          <li>孤独な経営者のよき相談相手になれるように努力を続ける</li>
        </ul>
      </li>
      <li>信頼
        <ul>
          <li>人間的信頼 … 感情</li>
          <li>ビジネス的信頼 … 合理</li>
        </ul>
      </li>
      <li>人間的信頼関係で大切なこと
        <ul>
          <li><strong>信頼されないことをしない</strong>
            <ul>
              <li>お互いの信頼関係は比例する</li>
            </ul>
          </li>
          <li><strong>相手との共通の話題や体験を持つ</strong>
            <ul>
              <li>共通項を探す。共通項が多いほど人間的信頼関係は強くなる</li>
            </ul>
          </li>
          <li><strong>相手の価値観に共感する</strong>
            <ul>
              <li>究極系は、その人の哲学や生き様に共感すること</li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </li>
  <li>プレゼン・検討
    <ul>
      <li>あくまでも「相手の課題を解決するためのプレゼン」であるべき</li>
      <li>プレゼンの順番
        <ol>
          <li>Whyの明確化（課題）</li>
          <li>Whatの明確化（ゴール）</li>
          <li>How・When・Whereの明確化（実行策）</li>
        </ol>
      </li>
      <li>営業感のある言葉は使わない（相手が急速に冷める）</li>
    </ul>
  </li>
  <li>紹介
    <ul>
      <li>自分からわざわざ「紹介してください」と言わなくても、<strong>自分の強みを相手に印象づける</strong>ことさえできれば、向こうから声がかかることが多い
        <ul>
          <li>名刺交換のタイミングでは、自分は何ができるのか、何の専門家なのかということを１つや２つに絞って伝える</li>
        </ul>
      </li>
      <li>経営者や富裕層のコミュニティでは、基本的に<strong>２人紹介したら最低１人は紹介される</strong>というのが暗黙のルール</li>
      <li>優良顧客でなくても、「優良顧客の人脈を持っている人」なら、時間と手間をかける
<strong>業界に影響力を持っているような人をたった１人でも突破できれば、そこから横に広がっていく</strong></li>
    </ul>
  </li>
</ol>

<h2 id="その他">その他</h2>

<h3 id="成長のための思考と行動">成長のための思考と行動</h3>
<p><strong>小さなことを積み重ねることが、とんでもないところに行くただひとつの道</strong>。
インプットとアウトプットを繰り返す。</p>

<p>分解とは思考を深堀りすること。
深堀りするからこそ、いままで気づかなかった課題が見え、課題が見えるから解決策をひねり出そうとなる。
絶えず問い続ける。</p>

<p>成長に繋がらないことに時間を割かない。
<strong>日々の振り返りに時間を割く</strong>。</p>

<p>日々の業務が、自分が本当に叶えたいと思っている目標につながっているのだということを絶えず意識することが、継続的な努力のコツ。</p>

<h3 id="強い営業組織">強い営業組織</h3>
<p>「この目標を達成するためにはどう行動したらよいのか」と全員が考える。
本音を出しやすくする工夫としては、甘いものを持ち寄るなど、少しカジュアルな雰囲気を演出するといい。</p>

<p>ミッションやビジョンをどう社員に定着させればいいのかというと、基本はこれでおかというほどに言い続けて、言い続けて、言い続けること。</p>

<p>部下に「自走力」をつけてもらうことは育成の基本。</p>
<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1" role="doc-endnote">
      <p>本ブログは「本を読み、理解した内容の備忘録（自分用）」を目的としている。重要なアイディアを昇華させ、自分の言葉でまとめるように努めている <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2" role="doc-endnote">
      <p>内容に不快を感じ、ブログの取り下げを希望される著作者の方は、個別にご連絡いただけると幸いに思う <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name></name></author><category term="biz" /><category term="reading" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">賢い脳のつくりかた</title><link href="https://blog.o3osatoshi.engr.work/life/golden-brains" rel="alternate" type="text/html" title="賢い脳のつくりかた" /><published>2025-05-25T15:00:00+00:00</published><updated>2025-05-25T15:00:00+00:00</updated><id>https://blog.o3osatoshi.engr.work/life/golden-brains</id><content type="html" xml:base="https://blog.o3osatoshi.engr.work/life/golden-brains"><![CDATA[<p><img src="/assets/2025-05-26-golden-brains/thumbnail.png" alt="thumbnail" /></p>

<p>※本ブログの目的と内容<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup>、著作者の方へ<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote" rel="footnote">2</a></sup></p>

<h2 id="ゴールデンブレインを育てる６つのサイクル">ゴールデン・ブレインを育てる６つのサイクル</h2>

<ul>
  <li>土台をつくる３つのサイクル（健康に育つための土台）
    <ul>
      <li><strong>睡眠</strong></li>
      <li><strong>食事</strong></li>
      <li><strong>運動</strong></li>
    </ul>
  </li>
  <li>才能を育てる３つのサイクル（自ら考え判断して生きていく力）
    <ul>
      <li><strong>遊び</strong></li>
      <li><strong>読書</strong></li>
      <li><strong>デジタルメディア</strong></li>
    </ul>
  </li>
</ul>

<h4 id="脳の初期発達に影響を及ぼす要素">脳の初期発達に影響を及ぼす要素</h4>

<ul>
  <li>極度のストレスや感染</li>
  <li>安定した愛着と社会的支援</li>
  <li>十分な栄養</li>
</ul>

<h2 id="睡眠">睡眠</h2>
<p>眠りは自分の中で起きること。
親の役割は子どもを寝かしつけるというより、<strong>よく眠れる</strong>ための環境をつくること。</p>

<h4 id="睡眠の重要な２つの機能">睡眠の重要な２つの機能</h4>

<ol>
  <li><strong>老廃物</strong>をなくす</li>
  <li><strong>記憶</strong>の強化</li>
</ol>

<h4 id="健康的な睡眠パターンをつくる７つのテクニック">健康的な睡眠パターンをつくる７つのテクニック</h4>

<ol>
  <li>余裕を持って起きる</li>
  <li>日差しを浴びる</li>
  <li>お昼寝をする</li>
  <li>眠くなる環境をつくる
    <ul>
      <li>照明を落とし、テレビの音をなくす</li>
    </ul>
  </li>
  <li>１人になれる時間をつくる
    <ul>
      <li>涼しいほうが熟睡できる</li>
    </ul>
  </li>
  <li>規則的なリズムを守る</li>
  <li>睡眠リズムを見直す</li>
</ol>

<h2 id="食事">食事</h2>
<p>健康は食べ物で決まる。
どんな食べ物をどう食べるか、子どもがきちんと決められるようにすることも重要。
親が食べる量を決めたり、子どもの口に食べ物を入れてやったりするのではなく、
<strong>子ども自ら体の声を聞き、自分で食べ方を決められるように機会を与える</strong>。</p>

<h4 id="脳の発達に必要な栄養素">脳の発達に必要な栄養素</h4>

<ol>
  <li>タンパク質
    <ul>
      <li>人体の正常な成長や維持に必要</li>
    </ul>
  </li>
  <li>脂肪（長鎖多価不飽和脂肪酸）
    <ul>
      <li>認知機能の発達に影響</li>
    </ul>
  </li>
  <li>鉄分
    <ul>
      <li>器官の機能や成長に影響</li>
    </ul>
  </li>
  <li>亜鉛
    <ul>
      <li>細胞分裂に必須</li>
    </ul>
  </li>
  <li>ビタミンB群
    <ul>
      <li>認知機能を維持</li>
    </ul>
  </li>
</ol>

<h4 id="砂糖は猛毒">砂糖は猛毒</h4>
<p>砂糖は脳の機能を乱す。多動性のある子どもの食事には砂糖が多く含まれる。
<strong>シュガーハイ</strong>（砂糖で興奮する）で、子どもたちは集中できなくなる。
人工甘味料に注意する。</p>

<h4 id="小児肥満は脳に悪影響">小児肥満は脳に悪影響</h4>
<p>肥満は<strong>認知機能・学力を低下させる</strong>。
注意すべきは、テレビやスマホを見せながら子どもにごはんを食べさせること。
映像を見ながら食事をすると、満足のサインに鈍感になり、普段より多くのカロリーを接種してしまう。
体と脳が疎通しながら食事できるように、<strong>食事の時間には食事に集中できる環境</strong>をつくる。</p>

<h4 id="感情的摂食に注意">感情的摂食に注意</h4>
<p>感情的摂食（ネガティブな感情を解消するための食事）の原因は、退屈とストレス。
子どもの機嫌が悪いときに、親がなだめようとして食べ物を与える影響が大きい。
なだめるために食べ物（特に甘い食べ物）で気は引かず、親もストレス解消のために食べ物（特に甘い食べ物）に頼らない。</p>

<h4 id="水を飲む">水を飲む</h4>
<p>水分が不足すると、<strong>認知機能（記憶や集中力など）が低下し、疲労しやすくなる</strong>。
飲料よりも水を飲む習慣を育むべき。
家に水以外の飲料を買い置きせず、出かけるときには水筒を持つ。</p>

<h4 id="母乳と粉ミルク">母乳と粉ミルク</h4>
<p>母乳は脳の発達によく、粉ミルクは成長速度を加速させる。</p>

<h3 id="食事の悩み">食事の悩み</h3>
<p>大人には目に見えるものを口に入れて食べることが重要だが、<strong>子どもにとってはそうではない</strong>ことを忘れないようにする。
食事の時間には五感を使って、<strong>料理がくれる経験に子どもがどっぷり浸かれる</strong>ようにする。</p>

<h4 id="薬事の悩み原因３選">薬事の悩み原因３選</h4>

<ol>
  <li>食事のスタイルが変わる
    <ul>
      <li>液体を飲むだけだったのが、新たな質感の食べ物が口の中に入ってくる感覚的ショックを経験する</li>
    </ul>
  </li>
  <li>遊びの面白さを知ってしまった</li>
  <li>フードネオフォピア
    <ul>
      <li>慣れない食べ物を避ける行動</li>
    </ul>
  </li>
</ol>

<h4 id="偏食を受け入れる">偏食を受け入れる</h4>
<p>子どもの口におかずを無理やり入れる行動は、子どもの自立に干渉してしまうため、よくない。
親が食べ物の量や種類に干渉すると、子どもは自分の体を理解し、適切な意思決定をする機会を奪われることになる。</p>

<p>野菜を食べない、新しいものを拒否する、お箸やスプーンを使わない、食事の時間に歩き回るなどの問題は、<strong>大きくなれば改善</strong>する。
<strong>楽しくてリラックスした雰囲気で食事する環境</strong>をつくることが、子どもには何よりの応援。</p>

<h4 id="神経質になりすぎない">神経質になりすぎない</h4>
<p>無理に料理をつくって疲れた親とごはんを食べるよりも、リラックスして楽しそうな親と仲良くピザを食べるほうがいい。</p>

<h2 id="運動">運動</h2>

<h4 id="跳ね回る子どもは賢い">跳ね回る子どもは賢い</h4>
<p>子どもは動きながら学んでいる。
運動は<strong>脳の発達に大きな影響を及ぼし、学習や記憶になくてはならない</strong>。
運動している人は、老年期まで脳の健康を維持する。</p>

<h4 id="長時間じっとしていることの問題点">長時間じっとしていることの問題点</h4>
<p>肥満率が上昇し、体感（体を支える役割）が弱くなる。
未就学児童の場合、どれだけ運動したかではなく、<strong>どれだけ座っている時間を減らせたか</strong>が重要。</p>

<h4 id="効果的な運動">効果的な運動</h4>
<p><strong>歩くこと</strong>と<strong>走ること</strong>だけは省かない。<strong>多用な筋肉</strong>を複雑に使う運動にも多くの利点が期待できる。
<strong>素足</strong>で歩くことは感覚や運動能力を育てる。</p>

<h4 id="自然の中での運動が感覚を育む">自然の中での運動が感覚を育む</h4>
<p><strong>自然環境は感覚能力を発達させる</strong>。
脳の発達について語るとき、私たちは認知的な機能を中心に考えがち。
体を動かすことや感覚を育てることも脳の重要な機能。</p>

<p><strong>規則や制限なく自由に遊ぶ</strong>ことが子どもをいい子にする。
外に出て、自然の中で思いっきり走り回らせる。
間違いなく変化がある。</p>

<h2 id="遊び">遊び</h2>

<h4 id="遊びは脳を育てる">遊びは脳を育てる</h4>
<p>遊びは脳を大きく複雑にする(育てる）。また、遊びを通じて生存に必要な技術を習得する。
楽しさをくれる身体活動はすべて遊び。</p>

<h4 id="社会的な脳は遊びによってつくられる">社会的な脳は遊びによってつくられる</h4>
<p>１人で遊ぶときより誰かと一緒に遊ぶときのほうが、<strong>我慢すること（自己抑制）が多くなる</strong>。
友だちと遊ぶことは、<strong>してもいい行動としてはいけない行動を学ぶ</strong>最もいい機会。
親が追いかけながら「待ちなさい」「殴っちゃダメ」と叫ぶより、強力な力を持っている。</p>

<h4 id="同じ遊びの繰り返し">同じ遊びの繰り返し</h4>
<p>子どもが同じ遊びを繰り返す理由は、その中に新しい喜びを感じ続けているから。
大人の目には同じように見える遊びも、実は少しずつ変化している。</p>

<h3 id="遊びの４つの心得">遊びの４つの心得</h3>

<ol>
  <li>遊びの時間は奪わない
    <ul>
      <li>遊びのポイントは<strong>無目的性</strong></li>
      <li>遊びのために子どもに必要なのはおもちゃではなく、<strong>機会</strong></li>
    </ul>
  </li>
  <li><strong>自分で決めて</strong>行動させてあげる
    <ul>
      <li>重要なことは、遊びの自発性と自己主導性（自分が面白いと思う行動を選択する）</li>
      <li>自分で選択する行動が<strong>自分自身を理解</strong>することにつながる</li>
    </ul>
  </li>
  <li>おもちゃでは学べないことがある
    <ul>
      <li>子どもは、自分の環境を見て、遊び道具を見つけて遊びをつくっている</li>
      <li>子どもは退屈しても平気。子どもの退屈を恐れて、親が何とかしてあげなくてもいい</li>
      <li>退屈という問題を解決する能力を育てて、その能力を自由に発揮できるとき、子どもは本当の自分を発見する</li>
    </ul>
  </li>
  <li>ストレスに耐える力を育てる
    <ul>
      <li>遊びには、ポジティブな気分を高め、不安やストレスを克服する効果がある</li>
    </ul>
  </li>
</ol>

<h2 id="読書">読書</h2>

<h4 id="本を読むことの効果">本を読むことの効果</h4>
<p>本を読むことで、子どもの言語の発達を促し、表現力を優れさせ、共感能力を高める。
<strong>いいメッセージを込めた文章、世間に対して新設で、他の生命を尊重する気持ちのこもった文章を読むことで、私たちの視線は変化する</strong>。
いい本を読んで、他の人の立場を理解する能力が育った子どもは、世の中を愛するようになる。</p>

<h4 id="読解力を育てる３つのカギ">読解力を育てる３つのカギ</h4>
<p><strong>どんな能力も遺伝的要因と環境的要因の相互作用によって育つ</strong>。</p>

<ol>
  <li>手軽に本に出会えるようにする
    <ul>
      <li>定期的に家の本をチェックし、子どもが関心のある本や、楽しく読める本が用意されているか点検する</li>
    </ul>
  </li>
  <li>本を読む時間が必要
    <ul>
      <li>子どもに本を読むには、子どもの時間より<strong>親の時間</strong>が重要</li>
    </ul>
  </li>
  <li><strong>親の文章読解力</strong>も重要
    <ul>
      <li>「周囲の大人が『本を読むことを大事に考えている』と子どもが気がつくこと」が立派な環境をつくる重要な要素</li>
    </ul>
  </li>
</ol>

<h2 id="デジタルメディア">デジタルメディア</h2>

<h4 id="デジタルメディアは害悪">デジタルメディアは害悪</h4>
<p>デジタルメディアに触れる時間が増えるほど、子どもの<strong>言語の発達が遅延</strong>する。
<strong>親</strong>がデジタルメディアを利用しても、やはり子どもの言語の発達にはネガティブな影響がある。
デジタルメディアの利用により、子どもたちが<strong>失ったのは経験（親との会話）の機会</strong>。</p>
<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1" role="doc-endnote">
      <p>本ブログは「本を読み、理解した内容の備忘録（自分用）」を目的としている。重要なアイディアを昇華させ、自分の言葉でまとめるように努めている <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2" role="doc-endnote">
      <p>内容に不快を感じ、ブログの取り下げを希望される著作者の方は、個別にご連絡いただけると幸いに思う <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name></name></author><category term="life" /><category term="reading" /><summary type="html"><![CDATA[]]></summary></entry></feed>