OmniAICreator/Qiita-1.07M huggingface dataset:
LINUX GUI マウス座標を取得(備忘録)

## GUIの骨組み
昨日書いた備忘録
https://qiita.com/earthen94/items/8402809a401d904120ef

## マウス座標を取得するプログラム
```mousepos.c
#include <X11/Xlib.h>
#include <stdio.h>

int main() {
    Display *dpy;
    Window root, win;
    XEvent event;
    int screen;

    dpy = XOpenDisplay(NULL);
    if (dpy == NULL) {
        fprintf(stderr, "Xサーバに接続できません\n");
        return 1;
    }

    screen = DefaultScreen(dpy);
    root = RootWindow(dpy, screen);

    // 300x200のウィンドウを作成
    win = XCreateSimpleWindow(dpy, root, 100, 100, 300, 200, 1,
                              BlackPixel(dpy, screen), WhitePixel(dpy, screen));

    // 入力イベントとして「ポインタ移動（マウス移動）」を選択
    XSelectInput(dpy, win, ExposureMask | PointerMotionMask);

    XMapWindow(dpy, win);

    while (1) {
        XNextEvent(dpy, &event);

        if (event.type == MotionNotify) {
            printf("マウス座標: (%d, %d)\n", event.xmotion.x, event.xmotion.y);
        }
    }

    XCloseDisplay(dpy);
    return 0;
}
```

## 動作確認
マウスの矢印が画面の中に入ると、端末上に座標を表示する
```
gcc -o mousepos mousepos.c -lX11
./mousepos
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054974/70ad95bb-5a5f-40e3-98f7-0479ec06ac15.png)

## 座標取得に関わる部分
```c
  // 入力イベントとして「ポインタ移動（マウス移動）」を選択
    XSelectInput(dpy, win, ExposureMask | PointerMotionMask);
```
```c
       XNextEvent(dpy, &event);

        if (event.type == MotionNotify) {
            printf("マウス座標: (%d, %d)\n", event.xmotion.x, event.xmotion.y);
        }
```

## 動作環境
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054974/b2d00776-65bb-4390-abec-34e99bef3eb9.png)

## 余談
連休で４月２９日から日本に帰省しており、実家の古いパソコンで色々実験が出来ました。
今日名古屋へ移動して明日上海に戻ります。
featureを作ろう ~ disk篇

# どんなfeature?
沼地や川底などに画像のように、粘土などが円形に広がっているのが見つかることがあります。これがdiskというtypeのfeatureです。
![Clay_in_Swampland.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591568/f33bc6e9-4880-f061-ea37-22f668388106.png)

このfeatureは指定された場所のブロックを条件に応じて円形に置換して生成されます。
バニラでは主に水中で見つかりますが、このfeature自体は水中である必要はなく、バニラでも氷樹バイオームのように、地上で見つかることもあります。


![2024-02-03_09.43.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591568/cbca60b0-6266-c24a-356e-67f7c29d3ca6.png)

# JSONの書き方
JSONの構造は以下のようになっています。
```
{
    "target": Block predicate,
    "state_provider": {
        "fallback": Blockstates provider,
        "rules": [
            {
                "if_true": Block predicate,
                "then": Block state provider,
            ...
        ]
    },
    "radius": 整数/Int provider,
    "half_height": 整数/Int Provider
}
```
これは、指定した範囲(`radius`、`half_height`)を特定条件下でブロックに置換する、というものになっています。
### 置換範囲
`radius`と`half_height`で指定することができます。
`radius`は、円の半径で、**横方向の**置換範囲になります。生成地点を起点に、ここに指定した数値×2分、横方向に加算されます。0から8までの値がとれます。
`half_height`はfeatureの厚さで、**上下方向の**置換範囲になります。生成地点を起点に、ここに指定した数値×2分、上下に加算されます。0から4までの値がとれます。

### 置換のしくみ
`target`と`rules`、`fallback`で行います。
まず、`target`で置換する場所の条件を指定します。
この中から`rules`の`if_true`に合うものを上から照合し、置換されます。
ここに無かったもの、いわば「余り」の条件が全て`fallback`として返ってくるわけです。

<figure>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591568/0d681bd5-de16-420e-8c58-1a0c4fe61cba.png">
<figcaption>targetとrules、fallbackの関係</figcaption>
</figure>

### 条件および置換先の指定の仕方
Block predicateを用いて指定します。
Block predicateとBlock state providerについては[こちら](https://qiita.com/noir_kokumin/items/e0839404a4383ebce0cf)をご覧ください。

### 確実にブロック置換するためには
さて、実際にやってみると結構fallbackが暴発しちゃったりして思わぬ場所が置換されてしまったりしがちです。
普通にfeatureとして使う場合はこれでもいいのですが、後述の応用のように特定のブロックだけ置換したい場合や、ストラクチャー内でブロックを補正する場合には確実に置換したいものです。
これを防ぐにはどうしたらいいでしょうか？

その答えとして、
**`target`の時点で条件を絞り込み**ましょう。
そして、**その中から`rules`を指定**します。
こうすれば、「余り」にあたる部分がなくなり、fallbackが適用されなくなります。

言い換えたら、**targetとrulesをほぼ一緒にする**、という感じです。

<!--![disk_target.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591568/0d681bd5-de16-420e-8c58-1a0c4fe61cba.png)-->


# 応用：条件分岐でブロックを置換する
これを含めた「置換系」のfeatureは`simple_block`等の「設置系」のfeatureとは違い、指定したブロックが置けないような状態(全部`false`のヒカリゴケなど)でもお構いなく置け、ブロックアップデートを起こしません(「設置系」はブロックアップデートを起こすし、置けないものは置けません)。

更に、「どういうブロックをどのブロックに置換するか」の部分が配列になっており、上から順次試行していく、という流れになっています。

そのため、本来置けないブロックを強制的に設置できるほか、以下のようにブロックに応じて置換先を切り替えることができます。

https://twitter.com/noir_kokumin/status/1731635088616742928
司法試験CBT体験版が出たので練習用クローンをこしらえてみた

![スクリーンショット (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4005442/c4c9e9eb-9c80-4551-b661-78d4e6b70527.png)


[司法試験・予備試験CBTシステムの【体験版】](https://www.moj.go.jp/jinji/shihoushiken/jinji08_00238.html)が公開されました。

色々と言いたいところはありますが、とりあえず論文を書く練習をせねばなりません。
しかし、この形式のテキストエディタがないと練習のしようがありません。

仕方ないので、ChatGPTに注文つけまくってこしらえました。

[`nananek/ShihouCBTEmulator`](https://github.com/nananek/ShihouCBTEmulator) (→ 使いたいだけなら[こっち](https://nananek.github.io/ShihouCBTEmulator/index.html))

READMEもGPTに書かせたので適当です。ブラウザ上で完結するので滅多なことは起きないと思いますが、猫乃はこのソフトウェアの利用において発生したいかなる損害について責任を負いません。
プルリクエストはお待ちしております。ただ、これの需要があるあなたも私も勉強忙しいと思いますが⋯。
おすすめのJavaScriptを使ったDate・日付・日時・カレンダー系処理プラグイン

JavaScriptを使ってるとDate・日付・日時・カレンダー系処理は必ずやることになります。<br>
今回はおすすめのJavaScriptを使ったDate・日付・日時・カレンダー系処理プラグイン9選をご紹介します。<br>

<h2>exdate.js</h2>
Dateオブジェクトを拡張し、日時（年月日時分秒）を指定フォーマットに表示します。<br>
<a href="https://dad-union.com/javascript-exdate-js-date-time-formatting">exdate.jsによる日時フォーマット表示の完全ガイド</a><br>

<h2>dateformat.js</h2>
日時や日付を指定のフォーマット（ゼロ埋め等）表示できます。<br>
<a href="https://dad-union.com/javascript-date-format-guide-using-dateformat-js">JavaScriptでの日付フォーマット: dateformat.jsを使った実践的な表示方法ガイド</a><br>

<h2>Day.js</h2>
JavaScriptのDateの機能を使わずに日時処理を簡単に表示できます。<br>
<a href="https://dad-union.com/dayjs-js-date-handling">dayjs.jsで簡単に日時処理を行う方法</a><br>

<h2>Moment.js</h2>
Day.js同様JavaScriptのDateの機能を使わずにmoment.jsを使って日時処理を簡単に表示できます。<br>
<a href="https://dad-union.com/moment-js-date-handling-javascript">moment.jsで簡単！JavaScript日時処理の方法と実例</a><br>

<h2>jClocksGMT.js</h2>
<br>
<a href="https://dad-union.com/recommended-javascript-date-calendar-plugins">続きはコチラ＞＞</a>
プログラミング練習記録　5日目：C#：LINQの基本と練習問題

### 1.本日の作業内容
　C# 基本文法：LINQの基本

### 2.作業目的
　・復習と使い方の確認。

##
### 1.LINQとは？
LINQ（Language-Integrated Query） は、コレクションや配列に対して、SQLのような構文でデータを抽出・操作できるC#の機能。
```
 public static void Main()
 {
     int[] numbers = { 1, 2, 3, 4, 5 };
     var even = numbers.Where(n => n % 2 == 0);

     foreach (var n in even)
     {
         Console.WriteLine(n);
     }

 }
```

### 2.基本構文（メソッド構文）
| 操作       | LINQ式                                             |
| -------- | ------------------------------------------------- |
| フィルタ（抽出） | `Where(x => 条件)`                                  |
| ソート      | `OrderBy(x => x.値)` / `OrderByDescending(...)`    |
| 変換       | `Select(x => 新しい形)`                               |
| 集計       | `Count()`, `Sum()`, `Average()`, `Max()`, `Min()` |
| グループ化    | `GroupBy(x => 条件)`                                |

例
```
List<string> names = new List<string> { "Tanaka", "Sato", "Kato" };
var filtered = names.Where(n => n.StartsWith("S"));

foreach (var name in filtered)
{
    Console.WriteLine(name);
}
```

##
### 3.まとめ
LINQはデータ全件に対して検索をかけるのでデータ量次第でパフォーマンスが下がるらしいです。
そのため、参照するだけならDictionaryにするとか工夫しないといけないみたいです。
プログラミング練習記録　5日目：C#：クラス・オブジェクト指向・継承

### 1.本日の作業内容
　C# クラス・オブジェクト指向・継承

### 2.作業目的
　・復習と使い方の確認。

## 

### 1.クラスとは？オブジェクト指向とは？
#### オブジェクト指向の基本
- クラス：設計図（型）
- オブジェクト：その実態
- 目的：データと処理を１つにまとめ、再利用性や保守性を高める


### 2.基本的なクラスの作成と使い方
- クラスの定義
```
public class Person
{
    public string Name;
    public int Age;

    public void SayHello()
    {
        Console.WriteLine($"こんにちは！私は{Name}、{Age}歳です。");
    }
}
```
- インスタンス化とメソッド呼び出し
```
Person person1 = new Person();
person1.Name = "佐藤";
person1.Age = 30;
person1.SayHello();
```

### 3.コンストラクタ（初期化）を使う
```
public class Program
{
    public static void Main()
    {
        Person p = new Person("田中", 28);
        p.SayHello();
    }
}

public class Person
{
    public string Name;
    public int Age;

    // コンストラクタ
    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }

    public void SayHello()
    {
        Console.WriteLine($"こんにちは、{Name}です。");
    }
}
```

### 4.継承とは？
#### 既存のクラス（親クラス）の機能を引き継いで、さらに機能を追加できる仕組み
```
public class Animal
{
    public void Breathe()
    {
        Console.WriteLine("呼吸している");
    }
}

public class Dog : Animal
{
    public void Bark()
    {
        Console.WriteLine("ワンワン！");
    }
}

// 呼び出し
Dog dog = new Dog();
dog.Breathe(); // 親クラスのメソッド
dog.Bark();    // 自分のメソッド
```

##
### 3.まとめ
継承の向きには気を付けないといけないですね。。。
公式ドキュメントを“使いこなす”ための要約トレーニング

# 公式ドキュメントを“使いこなす”ための要約トレーニング

現場で働くエンジニアの方から「エラーが出たときにQiitaを検索するだけでなく、公式ドキュメントを読みこなせる人が強い」と伺い、  
自分でもドキュメントを正しく読み、理解し、再現できるようになりたいと強く思うようになりました。
そのため、この学習記録ではQiitaやChatGPTに頼りすぎず、公式の情報源に立ち返って、  
**「自分の言葉で要点を再構成する力」**を養うことを目的にしています。

RailsやRSpecなどの学習内容を、公式ドキュメントや教材を参考にしながら、自分の言葉で要約してみました。   
今回は1週間分のアウトプットをまとめて掲載します。

---

## 1. Rails開発の基本原則

### ● DRY原則（Don’t Repeat Yourself）
電車は無駄な部品を一切つけず、緻密に計算された構造で走っています。
コードも同様に、無駄なく一度だけ書くのがDRY（Don’t Repeat Yourself）の原則です。
DRYを意識することで、保守性・再利用性が向上し、メンテナンスも圧倒的に楽になります。


### ● 設定より規約（Convention over Configuration）
電化製品は、誰もが操作しやすいように他社と似たような操作方法を採用し、扱いやすく設計されています。
Webアプリケーション開発も同様に「決まった型(規約)」が用意され、誰でも直感的に構築しやすくなっています。
だからこそ、Railsでは、設定より規約を重視し、開発効率や可読性を高める構造となっています。


---

## 2. アーキテクチャと構造の理解

### ● MVCモデルの基礎
Modelは、番組の台本や制作内容、キャスティングなど、番組を構成するすべての情報を管理している場所です。
Viewは、テレビに映るチャンネルのように、HTMLやJSONといった番組を画面に表示します。
Controllerは、ユーザーの操作に応じてリモコンのように番組（データ）を呼び出し、画面に映し出す役割を担っています。

---

## 3. データベースとModelの操作

### ● マイグレーションとは
データベースに作りたいテーブルやカラムをコードで指示できる仕組みです。
プログラム上に設計図を書くことで、Excelのように手作業で作る手間が省けて便利です。
また、設計の履歴を管理できるため、チーム開発や修正にも強く、バージョン管理もしやすくなります。


### ● モデルジェネレーターとは
Modelを作るときに必要なファイルやコードを自動で準備してくれる、Railsのとても便利な機能です。
身近な例えで言えば、芸能モデルさんが撮影現場に入るときに、マネージャーさんが台本・衣装・スケジュール表などを事前に準備してくれるようなイメージです。
開発者はModelを作成するだけで、必要な準備が整うため、開発の手間を大幅に省くことができます。

### ● Active Recordモデルの基礎
対象のモデルが使われたときに、Railsが自動でデータベースから必要な情報（カラム名や型など）を取得し、モデルに必要なコードを生成してくれる仕組みです。
例えるなら、食堂でメニューを注文すると、料理人が材料を揃え、調理し、料理を提供してくれるのと同じです。開発者がモデルを使うだけで、裏側ではRailsが自動的に必要な処理を行ってくれます。
この仕組みにより、開発者はデータベースとの面倒なやり取りを省略でき、アプリケーションのロジックに集中することが可能になります。結果として、手間を減らし、開発効率を大幅に向上させることができます。


---

## 4. RSpecの視点と思考

### ● RSpec DSLとは
RSpec DSLとは、RSpecが提供する「テスト記述専用の文法（DSL）」のことです。  
DSL（Domain-Specific Language）とは、特定分野の目的に特化した小さな言語のことを指し、RSpecではテスト記述に特化しています。

このDSLにより、テストを“プログラムコード”というより“仕様書”のように表現でき、  
開発者同士の認識のズレを防ぎ、コードの可読性や保守性を高めることができます。

---

## 5. おわりに
  
- 今後も毎週学んだ知識の定着のためにアウトプットしていく予定です。  
- 最後まで読んでいただきありがとうございました！

---
どんなアプリでも“続き”が使える体験を



###  はじめに：アプリが変わるたびに、すべてがリセットされる

どれだけ精度の高い生成AIを組み込んでも、アプリごとの「記憶の断絶」は未だに解決されていない。
タスク管理アプリ、業務支援アプリ、チャットボット…。どれも「その場での文脈」しか理解せず、利用者の“全体像”を引き継ぐ仕組みはない。

---

###  このままでは、AIの活用体験は「点」で終わる

生成AIが高度になればなるほど、「どこまで理解してくれているか」に対する期待も高まる。
しかし**ユーザーがサービスを横断した途端、会話も知識も振り出しに戻る**。この断絶は、もはやUI/UXの限界ではなく、「設計思想」の限界かもしれない。

---

### 構想：ユーザー体験の“時間軸”を、アプリの外に出す

「ある再設計」に取り組んでいる。
キーワードは：どこからでも会話を引き継げる”こと。
詳細はまだ言えないが、近く形にする予定。

---


### 最後に：出願後、構成の一部は公開予定

現在この仕組みは知的財産として整理中であり、出願完了後に一部アーキテクチャを公開する予定。
興味がある方は、続報をお待ちいただきたい。
GraphForge: 自然言語から構造化Webアプリを自動生成するLangGraph GUIツール


---
## 🧠 GraphForgeとは？

GraphForge は、自然言語で記述された仕様やアイデアを入力として受け取り、LangGraph + ローカルLLM（Qwen3:8B）を用いて、FastAPI + React 構成のWebアプリケーションコードを自動生成するGUIベースの開発支援ツールです。

> 一発生成ではなく、「状態遷移＋構造思考」によるコード生成。

---

## 🎯 なぜ作ったか？

近年、LLMによるコード生成は一般化していますが、以下の課題が残っています：

| 問題点          | GraphForgeの解決策       |
| ------------ | -------------------- |
| 自然言語が断片的     | 設計対話による仕様の構造化        |
| 出力コードに一貫性がない | LangGraphで状態制御しながら生成 |
| 修正・再生成が困難    | .md再利用・セクション編集でループ可能 |
| GUIがない       | StreamlitベースのGUI提供   |

---

## ⚙️ 技術スタック

* LangGraph（LLM状態管理オーケストレーション）
* Ollama + Qwen3:8B（ローカルLLM実行）
* LangChain（プロンプト制御フレームワーク）
* Streamlit（GUIインターフェース）

---

## 🖥 機能一覧

| 機能            | 説明                               |
| ------------- | -------------------------------- |
| 🧠 設計対話モード    | LLMと自然言語で仕様を詰める                  |
| 📄 .md生成      | 会話履歴をMarkdown形式で出力               |
| 🚀 コード自動生成    | LangGraphで構造的にコード出力              |
| 📥 ファイルダウンロード | 生成ファイルをGUI上からDL可能                |
| 🧪 実行方法提示     | main.py がある場合は即時実行コマンド提示         |
| 🔁 改修モード(予定)    | 既存コードの構造改修（LLM + structure.json） |

---

## 🔧 実装上の工夫と今後の拡張性

| 項目      | 現状の制限             | 改善・拡張余地                         |
| ------- | ----------------- | ------------------------------- |
| セクション編集 | `.sections` は編集不可 | GUI上で各セクション編集対応可能               |
| 再設計導線   | `.md` の貼り直し必要     | アップロード/履歴読み出し対応可能               |
| 外部知識の注入 | フリーテキスト混入のみ       | `.reference_knowledge` フィールド化予定 |
| 改修実行の流れ | 曖昧指示でも強制改修        | 事前可否判定 → 実行可のフロー導入済             |

---

## 📦 出力ファイル構成例

```
build/
└── graphforge-20250505-xxxxx/
    ├── app/
    │   ├── main.py
    │   ├── openapi.json
    │   └── routes/
    ├── frontend/
    │   ├── src/App.jsx
    │   └── pages/Home.jsx
    └── README.md
```

---

## 🧪 セットアップ方法

```bash
# 仮想環境作成（Windows）
python -m venv venv
venv\Scripts\activate

# ライブラリインストール
pip install -r requirements.txt

# モデル実行（初回DL含む）
ollama run qwen:8b

# GUI起動
streamlit run main.py
```

起動後は `http://localhost:8501` にアクセス。





---
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4052799/24062a0f-fd96-44f2-802a-3774c0fe1738.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4052799/b0672688-ffd1-46ce-bdbf-4dfab7b82aaf.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4052799/8ce88843-a59d-43b7-9f3f-fa103a5965bc.png)

---

## 🎁 リポジトリ

📦 GitHub: [https://github.com/ryosaki1112/GraphForge](https://github.com/ryosaki1112/GraphForge)
ライセンス: MIT License（商用利用に関する追加条項あり）

🚫 **商用利用について / Commercial Use Restriction**:

- 本ソフトウェアを以下のような**商用目的**で利用する場合、
  事前に開発者から**別途商用ライセンスの取得が必要**です：

  - 有償プロダクトへの組み込み
  - SaaS 形式での提供
  - 業務委託開発での活用
  - 研修・教育事業等での収益化を伴う活用

---

## 🧩 まとめ

GraphForge は「自然言語→構造→コード」をLangGraphベースで体系化した、**構造思考型コード生成基盤**です。

単なる出力ではなく、「再利用できる設計」を目指す方におすすめ。
PoC、個人開発、教育用途にも最適です。

---

アプリ開発に興味あるけど何からしたらいいかわからない方がいたらぜひ！
Chakra UI v3をJestでテストしたらTypeError: window.matchMedia is not a function

# はじめに
chakra ui v3をJestでテストした際に起きたエラーです。

# 問題
テストを実行すると、```TypeError: window.matchMedia is not a function```とwindowオブジェクトの ```matchMedia```関数が無いと指摘されます。

# 解決方法
jest.setup.tsに下記を追加します。
```jets.setup.ts
global.matchMedia =
  global.matchMedia ||
  function () {
    return {
      matches: false,
      addListener: jest.fn(),
      removeListener: jest.fn(),
    };
  };
```
一言でいうと、```matchMedia``` がデフォルトで用意されていなければ、何もしないような関数に置き換えるということです。

# 参考

https://qiita.com/Garyo99/items/1ecb60309700f3187cb2
言語入力変更

1.iBusの入力メソッドにanthy、mozcがないので入手する。
```
apt-get install ibus-anthy ibus-mozc 
```
後に必要であればログアウトする。
iBusの入力メソッドを再度開き追加で日本語-mozcを選択。
iBusの設定変更から「次の入力メソッド」横の「...」を押してキーボードショートカットを入力する。通常日本語入力キーボードに慣れていると 半角/英数 なので「キーコードボックス」横の「...」から新しいアクセラレーターとして 半角/英数 を入力。追加を押せば新しく表示されるのでokを押す。

2.先程の入力確認のためにエディタやブラウザで切替キー変更してみる。
切り替わらなければマウスポインタで手動で`A`から入力モードの`ひらがな`を選択。

3.確認できたらiBus設定を再度開き項目1と同じようにしてanthyを選択後にmozcを削除し、入力メソッドのanthyを開き「設定」から「入力モードのボックス」に入っている値を`英数`から`ひらがな`へ変更する。

4.項目2と同じように切替キーからひらがな入力モードでの変更を確認する。

5.仮想キーボードでの設定用にfcitx5を導入する。
```
apt-get install fcitx5 fcitx5-anthy fcitx5-mozc fcitx5-config-qt 
```
後にシステム設定から入力デバイス-仮想キーボードと辿り fcitx5に変更する。
変更されなければログアウトもしくは再起動する。

6.変更確認できたらマウスポインタで「A」から「キーボードの図柄」へ変更されたアイコンを押して「インプットメソッドの設定」-「KDEシステム設定」-「地域の設定」-「入力メソッド」-「+入力メソッドの追加ボックス」を押す。
キーボード英語からキーボード日本語を選択してキーボード日本語を入力メソッドオンからドラッグさせて入力メソッドオフへ変更し、開かれたチェックボックスの修正をクリックしてから適用を押す。
適用後に「グローバルオプションを設定」を押してホットキーの切替、「入力メソッド fcitx5-入力メソッドオフ」のmozcの「初期モードボックス」で全角かなを確認する。

6.項目2、4と同じようにして切替入力の確認を行って、apt-get update や apt-get upgrade を行う。

## 参照・引用元 
abema blog ninjav8
RTX1200でl2TPでLAN内にアクセス

備忘録

## 基本セットアップ
下記のヤマハのサイト通りにセットアップ
l2tpで接続は可能だが、LAN内にアクセスすることはできない.

https://network.yamaha.com/setting/router_firewall/vpn/vpn_client/vpn-smartphone-setup_rtx1200_gui


> NetVolante DNSへの登録 - 3.以下のコマンドを記述して、「実行」をクリックします。

で代わりに以下のコマンドを実行

```
pp select 1
netvolante-dns hostname host pp server=1 (RTX1200のホスト名)
netvolante-dns go pp 1
ip lan1 proxyarp on
```

LANのサーバやプリンタにアクセスできるようになる.



#### ネットボランチに登録できているかの確認
```
pp select 1
show status netvolante-dns pp
```
PHP備忘録：Docker上でLaravelのartisanとWebルートを両立させる方法をまとめてみた

## はじめに

LaravelとApacheをDocker環境で構築し、実際にルートへアクセスできるまでの過程を整理しました。

:::note info
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::


PHPのキャッチアップを目的とした、初学者による備忘録的な記事です。

## 書こうと思ったきっかけ

個人的にPHPの学習を進めたく、Laravel環境をDocker上で構築しようと考えました。

途中、「/hello」ルートにアクセスできない問題にぶつかり、Apacheの設定とLaravelの構成について深掘りしたことで多くの知見が得られたため、それを記録します。

## 内容

### LaravelとApacheを連携させる構成

* Laravel CLI（`php artisan`）を使用するには `WORKDIR /var/www/html` が必要
* Apache の公開ディレクトリは `public/index.php` であるため、Apacheのルートは `/var/www/html/public` に設定する

### Dockerfile の設定ポイント

```dockerfile
# PHP 8.2 + Apache の公式イメージをベースにする
FROM php:8.2-apache

# Laravelで必要なパッケージをインストール（zip, git, curl など）
RUN apt-get update && apt-get install -y \
    zip unzip git curl libzip-dev libonig-dev \
    && docker-php-ext-install pdo_mysql zip

# Composer（PHPのパッケージ管理ツール）をインストール
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer

# Apache のドキュメントルートを Laravel の public ディレクトリに変更
RUN sed -i 's!/var/www/html!/var/www/html/public!g' /etc/apache2/sites-available/000-default.conf

# mod_rewrite を有効化（.htaccess が使えるように）
RUN a2enmod rewrite

# ✅ Laravel CLIが正しく動くように、作業ディレクトリはアプリルートにする
WORKDIR /var/www/html

# Laravelアプリのソースコードをコピー（public/ も含まれる）
COPY src/ /var/www/html/
```

### /hello にアクセスできる条件（※あくまで自分調べ）

| 条件                                                         | 内容                                                           |
| ---------------------------------------------------------- | ------------------------------------------------------------ |
| Apacheのドキュメントルートが `/var/www/html/public`                   | Laravelのエントリポイント（index.php）を指す必要あり                           |
| `.htaccess` が `public/` に存在する                              | Laravelが自動生成、Rewrite処理が含まれる                                  |
| `mod_rewrite` が有効                                          | `.htaccess` をApacheが解釈できるようにする                               |
| `AllowOverride All` が `/etc/apache2/apache2.conf` に設定されている | `.htaccess` を有効にするための必須条件                                    |
| `routes/web.php` に `/hello` のルート定義がある                      | 例：`Route::get('/hello', [HelloController::class, 'index']);` |

### 実際のアクセスの流れ

1. `http://localhost:8080/hello` にアクセス
2. Apache が `.htaccess` を参照して `index.php` にリライト
3. Laravelが `/hello` のルート定義に基づきコントローラを実行
4. `HelloController@index` がレスポンスを返す

**実際の画面**

![Screenshot 2025-05-05 at 10.14.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/dd8305b8-f87d-4720-9869-94d245ad0150.png)

### 注意点：WORKDIR を `public` にしない

Laravelのartisanコマンドなどは `/var/www/html` を前提に動作するため、`WORKDIR` を `public` にしてしまうと CLI が機能しなくなる。

## まとめ

Laravel + Apache 構成で「Webアクセス（Apache）」と「CLI操作（artisan）」の両立をするには：

* `WORKDIR` は Laravel のルート `/var/www/html`
* Apache のルートは `public` に `sed` で変更
* `.htaccess` のRewriteを有効にするために `mod_rewrite` と `AllowOverride All` を設定

この構成を整えることで、CLIとWeb両方からスムーズにLaravelアプリケーションを扱えるようになりました...！

現在は `/hello` にアクセスでき、モデルとマイグレーションも作成できる段階に到達しました！！

**実際の開発画面**

![Screenshot 2025-05-05 at 10.16.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/ad2d15a9-b900-4bfa-9e5a-e0deb308084f.png)
さくらレンタルサーバ データベースをアップグレードしたら「データベース接続確立エラー」が表示される

# MySQL5.7 または MySQL5.5 を MySQL8.0にアップグレードしたらWebサイトが表示されなくなったときの解決方法

2025年5月、大型連休中にちょっとした人助けでサーバメンテナンスを手伝ったところ、公式の説明手順でわかりにくいところがあったので情報共有します。

https://junji.jp/net/sakuradatabase/


特にむずかしい話ではないけど、最近は知識がなくてもWebサイト運営をひとりでしていたり、ノーコードで公式サイトの説明やコントロールパネルだけが頼りのサーバ管理している人もいると思うので、そういうひとにとって解決を早めたり解決の手がかりになるとよいなと思いました。
（SNSで検索してみたらおなじ場所でつまずいた経験のあるひとが複数いました）
SupabaseとHasuraの接続で詰まったところ

# 状況
[公式の手順](https://hasura.io/docs/2.0/databases/postgres/supabase/)を参考にSupabaseとHasuraを接続させようとしていたところ、次の様なエラーが出た。

```
[
	{
		"definition": "...",
		"message": "connection to server at ... , port 5432 failed: Network is unreachable\n\tIs the server running on that host and accepting TCP/IP connections?\n",
		"name": "source ...",
		"reason": "Inconsistent object: connection error",
		"type": "source"
	}
]
```
※一部マスクしています

# 原因
- SupabaseのデフォルトDBはIPv6アドレスでのみ接続を受け付けるようになっている
- 一方、HasuraはIPv4しか使えず、IPv6ではネットワークに到達できない
- そのため、「Network is unreachable」や「Is the server running on that host and accepting TCP/IP connections?」というエラーが発生する

# 解決策
### Supabaseの「Session Pooler」機能で、IPv4互換の接続URLを使用する
1. Supabaseダッシュボードの「Database」→「Settings」→「Session Pooler」から「IPv4互換のURL」を取得
2. そのURLをDATABASE_URLに設定する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654759/df1e6f38-523f-4902-ae22-66620bd4e711.png)


# その他参考

https://qiita.com/centerfield77/items/c6425ac4b3734a7aa3b5

https://zenn.dev/hisho/articles/76bc5ffe469bf4
WSLgが起動しないとき

# はじめに
WSLでGUIを使おうとするといつも設定でつまづく。
Webでよく見る資料と違う設定が必要だったのでメモ

# 環境
Windows 11 Pro 23H2
WSL Ubuntu 22.04
WSL バージョン: 2.4.13.0
カーネル バージョン: 5.15.167.4-1
WSLg バージョン: 1.0.65
VSCode version 1.86.2

# 結論
GUI、例えば`xeyes`が

```bash
$ xeyes
Error: Can't open display:
```

で動かないときVSCodeから接続していたら`~/.bashrc`に、SSHとかでアクセスするときは`~/.profile`に
```bash
$ export DISPLAY=:0
```
と追加して再起動か、
```bash
sudo bash ~/.bashrc
```
だったり
```bash
sudo bash ~/.profile
```
すれば`xeyes`が動く。

# 詳細

数年前の古い資料だとxServerを使おうとかあるけど、Win11ならWSLgが使えるから特に何もしなくても動くよとか検索すると出てくる。

```bash
$ sudo apt install x11-apps
$ xeyes
```
で

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601058/e8861686-3b87-4390-8573-7eb7abe9dfd1.png)

が出てくるよ、というやつ。
で、以下のようにうまくいかないとき

```bash
$ xeyes
Error: Can't open display:
```

こんなときは

```bash
$ export DISPLAY=:0
$ export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0
```

と書けば良い、毎回書くのは面倒なので`~/.profile`に書きましょうというのも検索したら出てきたけど、書き込んで再起動しても

```bash
$ xeyes
Error: Can't open display:localhost:0.0
```

となってしまう。

# `.bashrc`と`.profile`の違い

手動で`export DISPLAY=:0`書けば動くのになんで読み込まれないんだと思っていたけど、もしかしたらVSCode経由でWSL繋いでいるからかと思いChatGPTに聞いてみると、以下の回答が得られた。

>## `.profile`
>
>* **ログインシェル**で読み込まれる（`ssh`や`tty`とかで直接ログインしたとき）
>* **GUIの端末アプリや WSL の通常起動では読み込まれない**ことが多い
>
>## `.bashrc`
>
>* **インタラクティブな非ログインシェル**（たとえば WSL のターミナルを開いたとき）で読み込まれる
>* **普段使う端末環境ではこっちが確実に実行される！**
>
>## WSLで何が起きてた？
>
>WSL（特に Windows Terminal で開いた場合）は基本的に「非ログインの bash シェル」として起動するから、`.profile` は読み込まれず、`.bashrc` が読み込まれる！


なるほど！
古い資料はSSHからの接続が多かったから`~/.profile`に書けとあったんだな、と納得した。
また、raspberryPiに接続するときなんかもSSHだから、そういうときの作業の記憶と混ざっていたかもしれない。

# 注意

自分の環境ではPowershellから`WSL`コマンドで入ったときにはどちらも反映されなかった。環境変数とかいじらないとだめなのかもしれない。
How to make samdalShoestringNode to samdalBootstrapNode🌺samdalShoestringNodeからsamdalBootstrapNodeへの変換

When it becomes difficult to update, link, or unlink your votingKey in samdalShoestringNode, you can use familiar bootstrap commands to update, link, and unlink it.
samdalShoestringNodeで votingKeyの更新、link、unlinkが困難になった時に、使い慣れた bootstrapでのコマンドで、更新、link、unlink作業をする方法。
　
　
　
　
Install samdal-bootstrap. Do this in your home directory.
ホームディレクトリ上で samdal-bootstrapのインストール作業をします。
```
cd

wget b.dusanjp.com/samdal/sabi

sh sabi

samdal-bootstrap -v
```

Now samdal-bootstrap is installed.
これで samdal-bootstrapはインストール出来ました。
　
　
Next, enter the shoestringNode working directory.
次は、shoestringNodeの作業ディレクトリに入って下さい。
```
cd <your shoestringNodes directory>
```
　

In the working directory of the shoestringNode, create a samdalBootstrapNode called 'unlink'.
shoestringNodeの作業ディレクトリ内に、'unlink'と言う名前の samdalBootstrapNodeを作成します。
```
wget b.dusanjp.com/samdal/shoestring/smu

sh smu
```
　
　
An 'unlink' directory has been created in the working directory.
You can enter this 'unlink' directory and use the bootstrapNode commands to update the votingKey and perform link/unlink operations.
作業ディレクトリに 'unlink'ディレクトリが出来ました。
この 'unlink'に入って、bootstrapNodeのコマンドで、votingKeyの更新、link/unlink作業が出来ます。
```
cd unlink

[example to use]
symbol-bootstrap updateVotingKeys
symbol-bootstrap link
symbol-bootstrap link --unlink
```
　
　
The bootstrapNode 'unlink' has the same nodekeys as the samdalShoestringNode and the votingKey is also copied.
bootstrapNode 'unlink'は、samdalShoestringNodeと同じ nodekeysを持ち、votingKeyも copyされています。
MindARがAndroidで位置がずれて表示されることへの対処方法

顔認識してAR表示させるにはMindARはとても手軽なツールです。いくつかの作品で使わせていただいております。
https://kaihatuiinkai.jp/ardeasobou/aquarium.html
↑これはWidnowsの各種ブラウザ、chromebook、iPadで作動します。
画面サイズと縦型レイアウトに変更してスマートフォン用を作ってみました。
https://kaihatuiinkai.jp/ardeasobou/sp_aquarium0.html
iPhoneでは作動します。でもAndroidでは位置がずれてしまいます。

# MidnARのa-cameraのタグを変更
a-cameraタグのactive='true'にするとAndroidでも正しい位置に表示されます。

```html
<a-camera active='true' position='0 0 0'></a-camera>
```

active='false'だとAndroidでは位置がずれて表示されます。
iPhoneの場合、'true''false'のどちらにしても位置はずれません。
サンプルプログラムはこちら
https://kaihatuiinkai.jp/ardeasobou/sp_aquarium.html
これに気が付くまで２週間かかりました。
【後編】Laravel×Docker×EC2 初デプロイで地獄を見た話（HTTPS対応と監視導入編）


さあ、ここまで来たらあと一息！この記事では、実際に公開していくための**HTTPS対応やCloudWatchの監視設定**までのラストスパートをお届けします。

## 🔒 HTTPS化（ACM + Route53）

### ❓ なぜALB構成にしなかったの？

当初は「ALB + ACMでHTTPSやった方がAWS的には王道だよな〜」と考えていました。

ただ、

- **ALBの構築手順とドメイン周りの設定が複雑**
- **まずはEC2単体で完結させたいという思い**
- **開発スピードを優先したかった**

という理由で、今回は**あえてALBを使わず、EC2に直接HTTPS対応**する構成を選びました。

たしかにALB構成だとスケーラビリティや冗長性で有利ですが、
**初学者の個人開発レベルであれば、EC2直SSLでも全然OK**です。

それで減点されるようなケースはまずない（むしろALBで詰まって何も出せない方が痛い）。

最初はALB経由のSSLにしようか悩んだけど、今回はシンプルにEC2へ直接HTTPS対応する構成にしました。

### 1. ACM証明書の作成

AWS Certificate Manager で `apprentory.click` 向けに証明書を発行。Route53を使ってる場合はDNS検証が楽勝です。

### 2. ApacheでSSL対応

```sh
sudo yum install -y mod_ssl
sudo vim /etc/httpd/conf.d/ssl.conf
```

この中で `SSLCertificateFile` や `SSLCertificateKeyFile` を ACMの証明書へ向けて設定。

> 注意：Amazon Linux 2023 の場合、証明書の配置やmod_sslの挙動が微妙に違うので要注意！

## 📈 CloudWatchで最低限の監視

### 1. CloudWatch Agentの導入

```sh
sudo yum install -y amazon-cloudwatch-agent
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard
```

対話形式でメモリ・ディスクの監視を有効にしました。

### 2. IAMロールを割り当てる

EC2インスタンスに CloudWatchAgentServerPolicy を含むIAMロールをアタッチ。

### 3. メトリクス確認

CloudWatchのダッシュボードに `mem_used_percent` や `disk_used_percent` を追加すれば、
最低限の死活監視はOK！

---

## 🚀 公開直前チェック

- ドメイン： `https://apprentory.click` にアクセスできる？
- `.env` の `APP_URL` と `SESSION_DOMAIN` は一致してる？
- ログイン・投稿機能は動作する？
- CloudWatchにログ出てる？

最後に `docker-compose up -d` をして、祈りながらアクセスするだけ…！

---

## 🎉 完走して思うこと

振り返るとめちゃくちゃ大変だった。ログが出ない、セッション飛ぶ、SSL通らん、CloudWatch無反応…

でも、確実に言えるのは：

> 「全部自分で通したことで、インフラと仲良くなれた」

この記事が、同じように苦しんでる人の支えになりますように！

最後まで読んでくれてありがとう！
ChatGPTを使用したアプリ開発記【動画投稿機能の実装】

### 🔧 ① 動画用のステートを追加
```App.js
const [video, setVideo] = useState(null);
```
### 📝 ② フォームに動画アップロード欄を追加
```App.js
<input type="file" accept="video/*" onChange={(e) => setVideo(e.target.files[0])} />
```
|部分|解説|
|-|-|
|type="file"|ファイル選択用の入力フォーム（画像・動画など）を表示します。|
|accept="video/*"|ユーザーが選べるファイルの種類を動画ファイル（例: mp4, webm, mov）に制限します。* はすべての動画形式を許可するワイルドカードです。|
|onChange={(e) => setVideo(e.target.files[0])}|ファイルが選択されたときに呼び出されるイベントハンドラです。 e.target.files は選ばれたファイルのリストで、.files[0] はその中の最初の1つ（1ファイル目）を取得します。それを setVideo() に渡して、React の video 状態に保存します。|

### 🚀 ③ handleSubmit 関数を修正
```App.js
 let videoUrl = null;
  if (video) {
    const videoRef = ref(storage, `videos/${video.name}_${Date.now()}`);
    const snapshot = await uploadBytes(videoRef, video);
    videoUrl = await getDownloadURL(snapshot.ref);
  }
    const newPost = {
    text,
    time: formattedTime,
    likes: 0,
    user: user?.email,
    imageUrl,
    videoUrl,
  };

  setPosts([newPost, ...posts]);
  setText('');
  setImage(null);
  setVideo(null);
  };
```
### 🖼️ ④ 投稿一覧で動画を表示する
```App.js
{post.videoUrl && (
  <video controls style={{ maxWidth: '100%' }}>
    <source src={post.videoUrl} type="video/mp4" />
    お使いのブラウザは video タグをサポートしていません。
  </video>
)}
```
![スクリーンショット 2025-05-05 8.09.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1058366/7cb6ded2-a85c-48f8-ac1e-65366f5eb706.png)
Next.jsの混乱を解く

## Next.jsとは
サーバー側で色々すること
### 利点
・ルート管理とかを自動でやってくれる
・SEOとかに有利
・面倒な設定がいらない

### 欠点
・Vercelなどのサーバー建てサービスが必要(当たり前...)

### 導入
Package.jsonでコンパイラに指定できるらしい。
```json:package.json
{
  "scripts": {
    "dev": "next dev",
    "build": "next build", 
    "start": "next start"
  }
}
```



## 自動ルート管理について
1) filename.tsxを作る
この際filenameを[]で囲むことによりparamで設定可能

2) ```import { GetServerSideProps, NextPage } from "next";```をファイル冒頭に入れて、後にexportする関数達がframework監督範疇内であることを伝える
3) importしたframeworkに従った固定名の関数を作る。そして型を明示してエラーを防ぐ。この場合だと```const IndexPage: NextPage<TypeName> = ({input}) =>```と```const getServerSideProps: GetServerSideProps<TypeName> = async () => ```である
4) どちらも```export default```してあげれば終わり。Next.jsが自動で判断できるようになる。


### 補足
TypeNameが共通であるのは、IndexPage関数の引数として設定してあるものを自動呼び出しされる際に互換性を持たせるためである。

## まとめ
混乱してるのは筆者というオチです。
ここまでお疲れ様でし
Neovim × 生成AI：avante.nvimでシステムプロンプトを活用する方法


## はじめに

NeovimでChatGPTなどの生成AIと連携するためのプラグイン「[avante.nvim](https://github.com/tzachar/avante.nvim)」では、**システムプロンプトの工夫**によって、AIの出力品質を大きく向上させることができます。

この記事では、以下の3つの方法によってプロンプトを柔軟に制御する手法を紹介します。

- `opts.system_prompt`による簡易的な指定
- `*.{mode}.avanterules` ファイルによるモードごとの設定
- templatesディレクトリ内の{mode}.avanterulesを直接編集

対象読者は、すでにNeovimでavante.nvimをすでに導入しており、より実用的な出力を得たいと考えている方です。


## 動作環境

- Ubuntu 24.04.2 LTS  
- Neovim v0.10.2  
- lazy.nvim v11.17.1  
- avante.nvim v0.0.23（コミット: adae032 時点）


## 方法①：`opts.system_prompt` による簡易的な指定

avante.nvimでは、セットアップ時に `opts.system_prompt` を指定することで、システムプロンプトを簡単に設定できます。

```lua
{
  "yetone/avante.nvim",
  event = "VeryLazy",
  lazy = false,
  version = false, -- 最新の変更を常に取得したい場合に設定
  opts = {
    system_prompt = "関西弁でお話してください",
    -- その他の設定
  },
  -- その他の設定
}
````

この方法は手軽にプロンプトを指定できますが、モードごとの切り替えや複雑な挙動を伴う制御には不向きです。


## 方法②：`*.{mode}.avanterules` ファイルによるモード別制御

より細かな制御を行いたい場合は、プロジェクトのルートディレクトリに `*.{mode}.avanterules` ファイルを作成することで、各モードに対応したシステムプロンプトを指定できます。

### 注意点：使用できるモード名について

公式の [README.md](https://github.com/yetone/avante.nvim/tree/main?tab=readme-ov-file#custom-prompts) に記載されたモード名をそのままファイル名に使っても、期待通りに動作しない場合があります。 

2025年5月時点では、次の4つの文字列を含むファイル名を対象としているようです（[該当コード](https://github.com/yetone/avante.nvim/blob/main/lua/avante/path.lua#L174)

* `agentic`
* `legacy`
* `editing`
* `suggesting`

### デフォルトテンプレートを読む

[templatesディレクトリ](https://github.com/yetone/avante.nvim/tree/main/lua/avante/templates)には、各モードがどのようなプロンプトテンプレートを使用しているかが記述されています。

ベーステンプレート(base.avanterules)に、ツール呼び出しに関する詳細なガイドラインが含まれています。ChatGPTのようなツール連携型エージェントとしての利用を想定した設計になっているようです。

### プロンプトの例：`hoge.agentic.avanterules`

```jinja
あなたは関西人です。関西弁でしゃべってください。

以下に例を示します。
User request:
{% raw -%}
こんにちは
{%- endraw %}

Your response:
{% raw -%}
まいど！
{%- endraw %}
```

このように `jinja` テンプレート形式で記述できるため、テンプレートの再利用や条件分岐による構造化された出力が可能です。

## 方法③ ：templates/{mode}.avanterulesの直接編集

上記①や②の方法では、既存のデフォルトプロンプトに対して内容が追記される形になります。これは通常のコーディング用途には有効ですが、avante.nvimを「AIツール」としてではなく、まったく別のエージェントとして活用したい場合には不十分かもしれません。

そのような場合は、ソースコード中のavante.nvim/lua/avante/templatesにある{mode}.avanterulesを直接書き換える方法が有効です。

テンプレートを書き換えた後は、生成AIが従来の「ソフトウェア開発支援ツール」としてではなく、任意の役割に基づく応答を行うようになります。

この方法はある種の「プロンプトエンジニアリング」であり、柔軟性の高い運用が可能です。

③の方法に関しては、各方法を試して挙動を比較しながら得た気づきなので、間違っていればご指摘などいただければありがたいです。

## まとめ

|方法|特徴|向いている用途|
| --- | --- | --- |
|opts.system_prompt|手軽に設定可能|シンプルな出力調整|
|各プロジェクトルート/*.{mode}.avanterules|モードごとの柔軟な制御が可能|モード別の運用|
|ソースコードのtemplates/{mode}.avanterules|デフォルト無視で完全にカスタム可能|高度なプロンプト制御・実験的用途|

avante.nvimのプロンプト機能を活用すれば、Neovim内での生成AIの出力をより的確かつ実用的に制御できます。
用途や目的に応じて適切な方法を選択し、最大限に活用してみてください！
【公ド読】GitHub で GitHub Copilot に質問をする

【公式ドキュメントを読もうシリーズ】GitHub で GitHub Copilot に質問をする

## シリーズ概要
[https://qiita.com/yasu_programming/items/cec66f9e8d5d571e9ce3](https://qiita.com/yasu_programming/items/cec66f9e8d5d571e9ce3)

## URL
[https://docs.github.com/ja/copilot/using-github-copilot/copilot-chat/asking-github-copilot-questions-in-github](https://docs.github.com/ja/copilot/using-github-copilot/copilot-chat/asking-github-copilot-questions-in-github)
## 説明

Github上でGithub Copilotをどう動かすのかが解説されている。

### スキルによって駆動

これは全く知らなかった。【公式ドキュメントを読もうシリーズ】、やってよかった。

```
What skills are available?

---

上記の解答を日本語で教えてほしい
```

とGithub上のGithub Coppilotに聞くと、利用可能なスキルを応えてくれる。

```
利用可能なスキルは以下の通りです：

get-actions-job-logs (アクションジョブログ取得)
GitHub Actionsでの特定のジョブのログを取得します。失敗したジョブの原因を調査するために使用します。

get-github-data (GitHubデータ取得)
GitHubのREST APIを使用して、リポジトリ、イシュー、プルリクエスト、コンテンツなどのリソースをクエリできます。

getfilechanges (ファイルの変更取得)
リポジトリ内の特定のファイルに対する変更履歴を取得します。

planskill (計画立案スキル)
ユーザーの質問に基づいて、必要なステップを計画し、適切なツールやデータを特定します。

semantic-code-search (意味的コード検索)
ユーザーの質問の意味や意図を理解し、それに基づいて関連するコードを検索します。

lexical-code-search (語彙的コード検索)
正確な単語やパターンに基づいてコードを検索します。コンセプトではなく、具体的な一致を求める場合に使用します。

support-search (GitHubサポート検索)
GitHub製品やサポートに関する質問に回答します（例：GitHub Actions、認証、プルリクエスト、リポジトリ管理など）。

getdiscussion (ディスカッション取得)
指定した番号のGitHubディスカッションを取得します。

getfile (ファイル取得)
リポジトリ内の特定のファイルをパスや名前で検索し、その内容を取得します。

getalert (セキュリティアラート取得)
セキュリティアラートの詳細や関連コードを取得します。

```
![copilot-q1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4075698/f9b534b8-0895-4821-abff-92b9689c5d6d.png)
![copilot-q2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4075698/7d71dbdf-93b8-4dfd-b469-eea80b6968e5.png)


## 所感
そのほか、特定のプルリクエストに関する質問、特定のコミットに関する質問、使ったことはないがディスカッションに関する質問もできるみたい。
XAIO ESP32C6+SSD1306、2倍角「あ、埼玉」と表示して遊ぶ。


参考
----

https://github.com/Tamakichi/Arduino-misakiUTF16


結果
----

![image_original(29).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/40d56676-8606-4bc4-a403-1f61e9398662.jpeg)


プログラム
----


```c++


//misaki_test_nibai1_XIAO_ESP32C6


//ヘッダーファイル
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <misakiUTF16.h>


//定義
#define SCREEN_WIDTH 128     // OLED display width, in pixels
#define SCREEN_HEIGHT 64     // OLED display height, in pixels
#define OLED_RESET -1        // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C  ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);


//初期化
void setup() {

  //I2Cの初期化
  Wire.begin(D9, D10);  //XIAO ESP32C6+SSD1306
  //Wire.begin(D10,D9); //XIAO ESP32C6+GROVE

  // I2Cアドレスは使用するディスプレイに合わせて変更する
  display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);

}  //setup


//メインループ
void loop() {

  // 画面表示をクリア
  display.clearDisplay();


  unsigned char font[8];  // フォント格納バッファ
  unsigned char font2[16*2];  // フォント格納バッファ
  int x = 0;

  char *str = "あ、埼玉";  // 文字列
  char *ptr = str;

  while (*ptr) {                   // 文字列分ループ
    ptr = getFontData(font, ptr);  // 1文字分のフォント取得
    if (!ptr)
      break;  // エラーの場合は終了

    int j = 0;
    for(int i=0;i<8;i++){
    
        int s = 0;
        int al = font[i];
        s = s |(0b1000000000000000 & (al<<8));
        s = s |(0b0010000000000000 & (al<<7));
        s = s |(0b0000100000000000 & (al<<6));
        s = s |(0b0000001000000000 & (al<<5));
        s = s |(0b0000000010000000 & (al<<4));
        s = s |(0b0000000000100000 & (al<<3));
        s = s |(0b0000000000001000 & (al<<2));
        s = s |(0b0000000000000010 & (al<<1));
        s = s | (s>>1);
        
        font2[j++] = s >> 8; 
        font2[j++] = s & 0xff; 
        font2[j++] = s >> 8;
        font2[j++] = s & 0xff;

    }//for


    //ビットマップの表示
    display.drawBitmap(x, 0, font2, 16, 16, WHITE);
    x = x + 16;

  }  //while

  // 描画バッファの内容を画面に表示
  display.display();

  delay(1000);  //1秒待つ

}  //loop


```
Cursor + GitHub + Vercel で爆速！Qiita記事一覧サイトを作ってみた

## はじめに

本記事では、Cursorという次世代型エディタを使って、Qiita記事一覧を表示する自分用Webサイトを、GitHubとVercelを連携して開発・公開した体験を紹介します。開発経験が浅い方や非エンジニアでも、驚くほど簡単かつスピーディにプロダクトを構築できるのが今回のポイントです。

今回のプロジェクトでは以下のツールとサービスを使いました：

* **Cursor**: AI搭載のエディタ。自然言語での開発指示が可能
* **GitHub**: ソースコード管理
* **Vercel**: デプロイ&ホスティング
* **Qiita API**: Qiitaから記事データを取得

## 全体の開発フロー

1. CursorでNext.jsプロジェクトを作成
2. Qiita APIを利用して記事一覧を取得するコードを生成
3. デザイン・検索機能・ページネーションを実装
4. GitHubにPush
5. Vercelで自動ビルド&公開

## Step 1: プロジェクトの作成

まずは以下のコマンドでNext.jsプロジェクトを作成。

```bash
npx create-next-app@latest .
```

Cursorを使えば、この手順すらも自然言語で「Next.jsプロジェクトを新規作成して」と打ち込めば完了。驚くほど手間が省けます。

今回はすでに構築済みのものを更新する内容になっています。最初のとっかかりについては別途記事を書きます。

こんな感じの個人サイトを実験的に作成しています。
![MySite.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457682/cb8d113a-e515-430e-9729-1c59245c38b9.jpeg)

## Step 2: Qiita APIとの連携

Qiitaの公式APIを使って、自分のアカウントから記事を取得します。Cursorに対して：

```
Qiitaのアクセストークンを使って、自分の投稿記事を取得するAPIクライアントを書いて。
```

と指示するだけで、`lib/qiita.ts` のような形でコードを生成してくれました。

### Qiitaアクセストークンの取得

1. Qiitaにログイン
2. [アクセストークン作成ページ](https://qiita.com/settings/applications)にアクセス
3. 必要なスコープを指定してトークンを発行
4. `.env.local` に下記のように記載。キー名は任意に決めて大丈夫です。

```
QIITA_ACCESS_TOKEN=your_token_here
```

## Step 3: 記事一覧の作成とスタイリング

`pages/articles.tsx` を新規作成し、記事のタイトル・タグ・投稿日などを表示。CSSはTailwind CSSを利用。

* 記事一覧のレイアウトはPodcast風にカード形式で表示
* タイトル・タグによる検索機能付き
* ページネーション（10件ずつ表示）
* スマホでも見やすいレスポンシブデザイン

Cursorに指示するだけで、必要なスタイルや機能を簡単に実装できます。

今回はすでに実装しているPodcastページのようなレイアウトや検索機能をつけてほしいと指示しました。
![prompt02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457682/cd58f723-08f4-4d7e-99d0-9630e72813e5.jpeg)

修正後は、`npm run dev`で開発環境上で確認します。
![After.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457682/d0b51232-9eef-4589-8168-ad690d23f649.jpeg)

## Step 4: GitHubとVercelで公開

開発が一通り終わったら、GitHubにコードをPushします。ただし、`.env.local`など機密情報はGitに含めないように注意。

代わりに、Vercelの環境変数に登録します：

1. Vercelのプロジェクトページを開く
2. 「Settings」→「Environment Variables」へ
3. `QIITA_ACCESS_TOKEN` を登録

これでGitHubからPushすると、Vercelが自動でビルドを行い、公開されます。

ちなみに、コミットする際に修正内容をAIにまとめてもらいコメントとすることも簡単にできます。

![GitCommitComment.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457682/e40f42cf-2a26-4012-929b-466d15e263bf.jpeg)

### エラーが出たとき

環境変数を登録し忘れると記事が反映されません。Vercel上でエラー内容を確認して再ビルドしましょう。

## Step 5: 自動更新と注意点

* `getStaticProps` を使って、1時間ごとに記事を更新（ISR）
* Qiita APIの使用にはアクセストークンが必要
* `.env.local` は必ず `.gitignore` に追加

## まとめ

Cursorを使えば、開発経験が浅くても、まるで会話するようにWebアプリを構築できます。QiitaのAPIとの連携も簡単で、GitHub + VercelによるCI/CDの流れもスムーズです。

生成AIの活用により本当にウェブ開発は簡単になりましたね！

## 参考サイト

* [Cursor公式サイト](https://www.cursor.so/)
* [Qiita APIドキュメント](https://qiita.com/api/v2/docs)
* [GitHub Docs](https://docs.github.com/)
* [Vercel Documentation](https://vercel.com/docs)
今日の学習ログ（2025/4/21）環境設定

# 🗓学習ログ（2025/4/21）
📌 現在、プログラミングスクールにてWeb開発を学習中です。
🎯 未経験からIT業界へのキャリアチェンジを目指しています。

学習がスタートして2週間。学習の記録としてqiitaを始めます:grinning:
まずは、この2週間分の振り返りから、少しずつ始めてみたいと思います。
よろしくお願いします。

## 📚 学習内容

- 使用教材／学習環境：スクールカリキュラム
- 学んだこと：今後の学習計画、環境設定
    - 前提：windows 11pro 使用

## 🧠 環境設定で出てきたツール・気づき

### VSCode (Visual Studio Code)

- **VSCode に追加した拡張機能**
    - Japanese Language Pack for Visual Studio Code
        - 日本語表記にする
    - Ruby LSP
        - Rubyコードのエラーチェックや自動補完などをしてくれる
    - zenkaku
        - 全角スペースを知らせてくれる
    - Code Spell Checker
        - コードのスペルをチェックしてくれる
- **VSCode の設定画面で調整したこと**
    - 半角スペースの設定
    - オートセーブ設定

### PowerShell

- 今回はWSL（以下）を有効化したり、WSLを最新版にアップデートしたり、Ubntu（以下）をインストールする際に使用

### WSL（Windows Subsystem for Linux）

- 前提：WindowsPCがMac想定の操作を受け付けて正常に動作するための設定が必要
- 設定に、Windows Subsystem for Linuxを使用

### Ubuntu

- Mac用の操作を受け付けるためのシステム
- PowerShellと同様「PCに命令する役割」を持っているが対象が違う
    - PowerShell：Windowsに関する命令
    - Ubuntu：Macに関する命令　※以降カリキュラムでは便宜上”ターミナル”と表現される

:::note info

**ターミナル（Ubuntu）でアプリケーション開発に必要なツールを導入**

```markup
 sudo apt update && sudo apt upgrade
```
```markup
 sudo apt install -y autoconf bison patch build-essential rustc libssl-dev libyaml-dev libreadline-dev zlib1g-dev libgmp-dev libncurses5-dev libffi-dev libgdbm6 libgdbm-dev libdb-dev uuid-dev make
```

:::

## 🌀 つまずいたこと・調べたこと

- テキスト通りの状態にすることで必死で、PowerShellが出てきて以降は自分が今どこで何をしているのか迷子になりながら作業をしていた
- 本日（2025/5/4）改めて振り返ってみると、概要を追えた感触がある（よかった）

## 💭 所感・次にやること

- 環境設定もさることながら、スクールの時間割学習を継続するには慣れるまで工夫が必要そうだと強く感じた
- とにかく与えられたミッションはひとつひとつ、スピードを意識してこなそうと思った

---

📝 補足やリンク（参考にした記事や動画など）

-
GWだし、Rustで個人開発のリポジトリに30回プルリクエストしてみた話

---

### GitHubリポジトリ
- [https://github.com/genkotsu-mt-fall/plm-oss.git](https://github.com/genkotsu-mt-fall/plm-oss.git)

---

## はじめに

「GWの間に100本くらいPRを出せるだろ」と軽い気持ちで始めたRustでの個人開発でしたが、実際に出せたのは30本。Web開発の実務経験はなく、これまでの個人開発も未完成に終わることが多く、Gitもmainに直接コミットするようなやり方で、実務とはほど遠いものでした。

今回はそうした自分を変えるため、あえてブランチを細かく分けて、一つずつ積み上げていくスタイルに挑戦しました。「まず手を動かす」ことを優先し、立ち止まらず進むことを重視した取り組みです。

## Rust初挑戦と開発スタイルの変化

Rustの型、所有権、非同期処理などに苦戦しながらも、ChatGPTや公式ドキュメントと向き合い、トライアンドエラーを繰り返しました。Cargo.tomlやSQLも明示的に書くスタイルが自分に合い、安心して開発できました。

## 実務を意識した開発姿勢

PRベースで進めたことで、ただ“動く”ではなく“保守しやすく、共有しやすい”コードを意識。

* 責務、再利用性を考える
* クライアントを意識したAPIレスポンス設計
* 単体テストと統合テストの住み分け
* SwaggerでのAPIドキュメント生成

コードの“前後関係”や“誰のための実装か”を考えるようになりました。

## トレードオフを知った

「DDDを取り入れればいい」「テストを厚くすればいい」──以前の自分は、そんな理想論だけで満足していました。実際に手を動かさずに、実務を分かった気になっていたのです。

しかし今回、小さくブランチを切って少しずつ積み上げる中で、ようやく現実が見えてきました。

* 拡張性を求めるとコード量が増える
* DIやモックの導入タイミングに迷う
* スピードと品質のバランスを取る難しさ

Rustでは、型によるバリデーションは単体テストに、DB操作はDocker Compose＋curlで実際に動かして確認するという、現実的で無理のない戦略を選びました。頭で考えるだけでは見えなかった“現実の開発判断”に触れた実感があります。

## まだまだ入り口

CI/CD、フロントエンド連携、レビューやチーム開発は未経験。例えるなら入門書の第1部が終わったような感覚。でもその先にある壁を見て、もっと熱くなれそうだと感じています。

## この取り組みの動機

就活のためだけではありません。自分のプロダクトを作りたい、人に使ってもらえるものを届けたい。その思いが原動力です。

だからこそ、小さなブランチで進みやすくしながら、今後も着実に積み上げていきます。AIを活用した学びの環境も整ってきた今、実務に携わりたいという思いが一層強くなっています。
  
---

### 主な変更内容

- 認証の整理: JWT認証の追加や、ログイン機能の実装、認証モジュールのリファクタリングを行いました。

- APIの改良: エンドポイントの追加（GET/POST/PUT/DELETE）、CORS制限の強化、APIレスポンスのフォーマット統一、エラーハンドリングの改善。

- テストとドキュメント: API統合テストの追加、Swagger UIの設定、READMEにAPIドキュメントを追加。

- データベース: PostgreSQL接続の設定、DBのエラーハンドリング、partsテーブルのマイグレーション、CRUD操作の実装。

- ロギング: 構造化ログの追加、エラーログの改善。

---
  
読んでいただき、ありがとうございました。
Agentic AIをするためにCrew AIを利用してみる


# CrewAIのセットアップでハマった話
最近、話題のエージェントフレームワーク「CrewAI」を試してみました。結論から言うと、**インストールがとにかく面倒くさい。**  
ネット上では「Pythonだけでサクッと動く」と紹介されていることもありますが、実際には**Pythonだけでは完結しない**です。  
自分用の備忘も兼ねて、どこで詰まり、どうやって解決したのかを記録しておきます。

## uv必須って本当？
CrewAI公式ドキュメントを見ると、まず目に入るのが「uv」を使ったインストール手順です。
- [公式インストール手順（英語）](https://docs.crewai.com/installation)

```bash
curl -fsSL https://astral.sh/uv/install.sh | sh
uv venv
uv pip install crewai
```

最初に「uvって何？」となったのは私だけではないはず。Pythonの仮想環境ツールとしてはvenvやpoetry、pipenvが一般的ですが、CrewAIはなぜか「uv」推し。
Windows環境ではuvのインストール自体はそこまで難しくないものの、**その後が本番**です。

## crewaiのインストール → clが通らない地獄
uvで仮想環境を作り、いざ手順を進めるとエラーが発生します。

```bash
cl : The term 'cl' is not recognized as the name of a cmdlet, function, script file, or operable program.
...
fatal error C1083: Cannot open include file: 'float.h': No such file or directory
...
```

色々進めると下記のようなエラーも出てきます。

![crewai_00_error.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457682/3376ac4f-d2b8-45b6-a2c0-5d13f379dfa8.jpeg)

結論としては、CrewAIの実行においては`Visual C++ Build Tools`が必要です。

 * [Visual C++ Build Tools ダウンロード](https://visualstudio.microsoft.com/visual-cpp-build-tools/)

さらに、「float.h がない」と言われ、調べてみるとWindows SDKも未インストールでした。
私の環境はディスクサイズが小さくケチった結果。SDKオプションを外していました。しかも、Cドライブが逼迫しているのでDドライブに切り替えたりもしていて、そのような要素もあり普通の手順よりもずっと時間がかかりました。

BuilderとSDKのインストールがとにかく長い。しかも、Visual Studio Installer のオプションで `C++によるデスクトップ開発` にチェックを入れなければ `cl` も使えない。開発環境が一気に重量化します。

**インストールが必要なVisual Build Tools**
![crewai_05_VisualBuildTool.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457682/4b334c56-3db0-452f-b243-df6bd96ed93e.jpeg)

> Pythonだけで済むって誰が言った！？

## GitHubと公式の差異

そんな中、[GitHubのREADME](https://github.com/crewAIInc/crewAI)を改めて見てみると、公式サイトとは微妙に手順が違うことが発覚。

さらに、初期のチュートリアルには[serper.dev](https://serper.dev/) という謎の外部サービスのAPIキー登録も必要だったようですが、最近のバージョンでは不要になったようです。

BaseAgentを使った構成では、`.env` ファイルも自動で読み込まれるようになっており、設定ファイル周りの作業は少し楽になっています。

## main.pyからパラメータを渡したい問題
CrewAIは基本的に `crewai run` コマンドで起動する設計ですが、これに変数を外から渡したいケースも多いです。
たとえば「AI LLMs」という分析トピックをコマンド実行時に変えたい。

この問題は `crew.kickoff(inputs={"topic": "AI LLMs"}`) のようにして、タスク定義ファイル（`tasks.py`）の `description` に `{topic}`プレースホルダーを使うことで解決できるようです。
コードを書き換えずに外から `sys.argv` や `.env` 経由で `topic` を変えられるため、複数の処理をループで回すような用途にも対応できるようです。ただ、ここまで手は回っていないので後日共有します

## Langchainはどうなのか？
「CrewAIがここまで大変ならLangChainにしようかな」とも考えました。
実際、LangChainも人気がありますが、こちらは**構成要素が多すぎて複雑そう**。
シンプルなエージェント構成を考えている場合は、むしろCrewAIのほうが柔軟で扱いやすい印象がありました。

とはいえ、LangChainも注目されていますし、Crew AIと同じくらい構築例も多いので試しておいたほうがよいかもしれません。

## 感想とまとめ

CrewAIは魅力的な設計思想を持ったライブラリですが、**最初のインストールの壁が高い**です。特に以下の点で苦戦しました：

* uv強制

* clが通らない

* WindowsnのVisual C++ Builder ToolsおよびCLI/SDKが必要

* インストール手順が刷新されていて外部から取得しにくい。

* 公式の手順も一部古い

ただ、一度環境が整えば、構成はシンプルで扱いやすく、エージェントフローの定義も素直です。

今後のアップデートで環境構築がもっと簡単になることを願っています。



## 補足リンクまとめ

* [CrewAI公式インストール手順](https://docs.crewai.com/installation)

* [GitHubリポジトリ（最新）](https://github.com/crewAIInc/crewAI)

* [Visual Studio Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/)

* [serper.dev（初期チュートリアルで使われた）](https://serper.dev/)
VSCode + Ubuntu on WSL2でgit commitできない

PCを新調したので早速いろいろ試しているのですが、WSL2上のUbuntuで本格的に開発環境を構築しています。今まではPCのスペックが微妙で重たくて使うの避けてたVSCodeもサクサク動作するようになったということで、VSCodeを中核としています。その中でUbuntuを20.04から24.04にアップグレードしたのがキッカケだったように思えるのですが、結構謎なハマりをしたので備忘録として書いておきます。
# 症状
プラグインも概ねセットアップし終わり、テストで作ったワークスペースを使ってgit周りの設定をしようと思ったところ、commitしようとすると「Error: connect ENOENT /run/user/1000/vscode-git-xxx.sock at PipeConnectWrap.afterConnect [as oncomplete]」なるエラーが出て、どうにもcommitができなくなりました。
エラーを確認すると-mオプション付けてcommitするのもアリなことが記載されていたので、試しにターミナルから-mオプションでメッセージを指定してgit commitすると問題なくcommitでき、またVSCodeのSCMのペインにはcommit情報が問題なく表示されていました。
# 切り分けしてみた
まず疑ったのはVSCodeのWSLプラグイン設定でミスがあったのではということで、.vscode-XXXなディレクトリを全消ししてワークスペースを開きなおすも解決できずでした。

再度エラーメッセージをよく確認すると ${HOME}/.vscode-server/bin/xxxxxxx/extensions/git/dist 配下にある git-editor.sh で問題が発生している旨の記述を発見、中身を確認すると…
```
#!/bin/sh

ELECTRON_RUN_AS_NODE="1" \
"$VSCODE_GIT_EDITOR_NODE" "$VSCODE_GIT_EDITOR_MAIN" $VSCODE_GIT_EDITOR_EXTRA_ARGS "$@"
```
うーん…何もヒントは得られずで…。
もう一度エラーメッセージを確認。
```
Unable to connect to VS Code server: Error in request.
Error: connect ENOENT /run/user/1000/vscode-ipc-xxxx.sock
    at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1161:16) {
  errno: -2,
  code: 'ENOENT',
  syscall: 'connect',
  address: '/run/user/1000/vscode-ipc-5cc265b0-6bec-4e0e-99c7-8fc48bccd7c4.sock'
}
```
ん？/run/user配下のファイルって存在してないじゃん…汗
socketファイルにアクセスできないからcommitメッセージ編集時にVSCodeを開こうとした際エラーになっているのだろうと想定したものの、果てさてどう直せばよいものやら…
# 解決策
ひたすらググってやっとIssue見つけました。
https://github.com/microsoft/vscode-remote-release/issues/6997
結論から言うと、以下のコマンドを実行したらソケットファイルが現れて、問題なくcommit時にVSCodeが開くようになりました。
```
VSCODE_IPC_HOOK_CLI=$( lsof | grep $UID/vscode-ipc | awk '{print $(NF-1)}' | head -n 1 )
```
ただなぜこれで解消するのかイマイチ理解できないのがモヤっとはしますが、まぁとりあえず動いたのでヨシとします。そのうちIssueのページをよく読んでみよう…（きっと読まない）
Vite + React 環境の Storybook でモジュールをモックする方法


# はじめに
vite環境のStorybookでモジュールをモックする方法です。

💡ポイント
vitestではモックを行う際に、`vi.spyOn`や`vi.mock`を定義してモックするが、
Storybookではモックファイルを利用してモックを行う。

![Qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141934/b27bf60b-db40-4cc9-baf1-d5395e48edf2.png)

# 参考資料
https://storybook.js.org/docs/writing-stories/mocking-data-and-modules/mocking-modules#builder-aliases


# サンプルコード

importしたuuidを表示するだけのページ。

![スクリーンショット 2025-05-05 3.05.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141934/fee7d0df-a55b-43e3-b090-152ed2a99ac6.png)

```typescript:uuid.ts 
export const uuid = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx';
```

```typescript:index.tsx
import { Container } from '@mui/material';
import { uuid } from 'app/lib/uuid';

export const Sample = () => {

    return (
        <Container>
            <div>
                <h1>UUID</h1>
                <p>これはUUIDを表示するコンポーネントです。</p>
                <p>{uuid}</p>
            </div>
        </Container>
    );
}
```

# モック

**モックファイル**

モックファイルを用意する。

```typescript:uuid.mock.ts 
export const uuid = 'mockmock-mock-mock-mock-mockmockmock';
```

**コンフィグ**

`vite.storybook.config.ts`ファイルに**alias**を設定する。

以下のように記載することで、
'app/lib/uuid'をimportするコンポーネントで、
'app/lib/uuid.mock.ts'がimportされるようになる。

```typescript:vite.storybook.config.ts
 import { defineConfig, loadEnv } from 'vite';
 import tsconfigPaths from 'vite-tsconfig-paths';
+import { resolve } from 'path';
 
 export default defineConfig(({ mode }) => {
     const env = loadEnv(mode, process.cwd(), '');
     process.env = { ...process.env, ...env };
     return {
         plugins: [tsconfigPaths()],
+        resolve: {
+            alias: {
+                // 'uuid'をimportするコンポーネントで、
+                // 'uuid.mock.ts'がimportされるようになる
+                'app/lib/uuid': resolve(__dirname, 'app/lib/uuid.mock'),
+            },
+        },
     };
 });
```

![Qiita (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141934/0dcc4719-29d7-40ef-a4a2-2acbc0b8ba6d.png)

# Storybook

**stories.tsx**

`stories.tsx`を用意する。
（モックを利用するための設定などは不要）

```typescript:index.stories.tsx
import { Sample } from './index';
import type { Meta, StoryObj } from '@storybook/react';

const meta = {
    title: 'Features/Sample',
    component: Sample,
    parameters: {
        layout: 'fullscreen',
    },
} satisfies Meta<typeof Sample>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {};
```

**Storybook**
Storybookを起動する。

```
$ npm run storybook
```

Storybook上ではモックファイルがimportされるようになる。

![スクリーンショット 2025-05-05 3.05.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141934/ced3efa4-bf6e-419a-a932-d66371fb8cf1.png)