OmniAICreator/Qiita-1.07M huggingface dataset:
【Vket Cloud】動画つき！ゼロから始めるHeliScript超入門⑨ - HeliScriptのUpdate()関数について

# はじめに
Vket Cloudでは、「HeliScript」という独自のスクリプトを使用してコーディングを行うことで、ワールド内に高度なギミックを導入することが出来ます。

本記事では、HeliScriptのUpdate()関数とその使い方について紹介します。

# 動画

<iframe width="560" height="420" src="https://www.youtube.com/embed/XfCykAm-oQE?si=QcXH_z91ozywDc2o" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

# Update()関数って？
Update()関数は、関数内の処理を毎フレーム実行します。
1フレームはおよそ1/60秒なので、1秒間に約60回実行されます。
※モニターのリフレッシュレートにより変動します。

Update()関数はHeliScriptを作成した際、はじめから記載されています。

## Update()関数の注意点
毎フレーム実行される関数であるため、コンソールへの文字出力を行うと、毎フレーム文字を出力してしまいます。

```
    public void Update()
    {
        hsSystemWriteLine("【Vket Cloud】動画つき！ゼロから始めるHeliScript超入門⑨ - HeliScriptのUpdate()関数について");        
    }
```
上記のように、Update関数内で文字列の出力を行う設定のみを行い、ビルドした場合、
下記の画像のように文字列が一瞬でたくさん表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3788807/05724062-0d84-bcd5-0e1d-bc662c68de93.png)


また、文字列の出力は画面外を突き抜けずっと出力され続けています。

このように、Update関数での実行には不向きな関数もVket Cloudには存在します。

# hsSystemGetDeltaTime()で時間計測

Update()関数を利用することで実装可能な挙動の一つに**時間計測**があります。

`hsSystemGetDeltaTime()`は直前フレームから現在のフレームまでの経過時間をfloat型で取得するシステム組み込み関数です。
これをUpdate()関数上で使用することにより、時間計測が行えるようになります。
```
    float timer = 0;
    public void Update(){
        timer += hsSystemGetDeltaTime(); // timerに経過時間を加算
        if(timer >= 3){ // timerが3以上となった時
            hsSystemWriteLine("3秒経過"); // コンソール出力
            timer = 0; // タイマーをリセット
        }
    }
```

上記の例ではUpdate関数内で`hsSystemGetDeltaTime()`を使うことで変数timerを時間計測に使用し、
timerが3以上になった際コンソールに「3秒経過」を出力、timerをリセットするという動作をすることにより、
3秒おきに「3秒経過」を表示する、といった動作を行います。

::: note warn
別のタブに遷移するなどしてバックグラウンド状態にした後、Vket Cloudを開いているタブに戻って来た際、`hsSystemGetDeltaTime()`で取得されるのはバックグラウンド状態にした時からVket Cloudを開いているタブに戻ってくるまでの時間になります。

本来の1フレームの長さより大きな値が入ってきてしまい、想定外の動作を引き起こす場合があるため、
`hsSystemGetDeltaTime()`で取得される値が大きい時は代わりに1フレームの長さと近い定数を加算する、といった方法を使うなどして想定外の動作を回避することを推奨します。
:::

次 : [⑩ HeliScriptでVector3を使ってシーン上のアイテムを移動させる](<https://qiita.com/shirapy/private/0900d87929511b27943a>)
前 : [⑧ HeliScriptでシーン上のアイテムを取得する](<https://qiita.com/shirapy/items/9a6fb9dbb64a33d37fb5>)
【Vket Cloud】動画つき！ゼロから始めるHeliScript超入門⑧ - HeliScriptでシーン上のアイテムを取得する

# はじめに
Vket Cloudでは、「HeliScript」という独自のスクリプトを使用してコーディングを行うことで、ワールド内に高度なギミックを導入することが出来ます。

本記事では、HeliScriptでシーン上のアイテムの情報を取得する方法を紹介します。

# 動画

<iframe width="560" height="420" src="https://www.youtube.com/embed/TOSUWC3hcIU?si=plijlafb9Lw3cId-" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

# 「アイテム」って？
Vket Cloudにおける「アイテム」とは、ワールドを構成するオブジェクト要素のことです。
VketCloudSDKのビルドと実行機能を使用した後、releaseフォルダのdata/Sceneフォルダ内にある、ワールド情報が記載されたjsonファイルにて、itemsという項目にある各要素がこれに該当します。

## ワールド情報が記載されたjsonファイルの確認方法

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3788807/717c354d-a18a-5166-cac6-b82f3e246e23.png)
ビルド後、VketCloudSDKタブのツール > Releaseフォルダを開くを選択することでreleaseフォルダを開けます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3788807/775eb10c-6a80-1916-066e-f734751388b1.png)
releaseフォルダ内のdata/Sceneフォルダ内にあるjsonファイルがワールド情報が記載されたjsonファイルになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3788807/952b7b8d-4971-ba59-ca0d-3a56175128d7.png)
この中の「items」項目の中に含まれている各要素が、シーン上の「アイテム」となります。
基本的にはUnity上で設定した名称と同じものに無ります。

## アイテムの生成方法

アイテムは、Unity上でVKC Item ○○という名前のUnityコンポーネントを使用した際に生成されます。(例：VKC Item Field)
※各Unityコンポーネントの使用方法につきましては、[ヘルプページ](<https://vrhikky.github.io/VketCloudSDK_Documents/latest/VKCComponents/VKCHEOCorrespondenceTable.html>)を参照してください。

# アイテムを取得する
HeliScript上でアイテムを取得するためには、Itemクラス変数宣言と、`hsItemGet(string itemName)`関数または`hsItemGetSelf()`関数を利用します。

## hsItemGet()
`hsItemGet(string itemName)`関数は、引数で指定した名称のアイテムを取得する関数です。

```
    // シーン上にWorldという名前のアイテムがある場合
    Item m_world; // アイテムクラス変数「m_world」を定義
    m_world = hsItemGet("World");
```

上記の例では、アイテムクラス変数「m_world」にアイテム「World」の情報を取得して格納しています。

## hsItemGetSelf()

`hsItemGetSelf()`関数は、この関数を発火したコンポーネントが所属するアイテム自体を取得する関数です。
例えば、VKC Item Fieldコンポーネントが付いているオブジェクト「Field_A」に対しVKC Attribute Scriptをアタッチし、その中で使用しているHeliScriptで`hsItemGetSelf()`関数を使用した場合、Field_Aの情報を取得することが出来ます。

# 取得したアイテムの名前を取得
Itemクラスでは、表示/非表示や移動など、アイテムに対し様々な機能を使用することが出来ます。
ここでは、`hsItemGetSelf()`にて取得したアイテムの名称を取得する方法を紹介します。

```
    Item m_Item; // Itemクラス変数「m_Item」を宣言
    m_Item = hsItemGetSelf(); // コンポーネントが所属するアイテム自体を取得
    hsSystemWriteLine("このスクリプトを持つアイテムの名前は%sです" % m_Item.GetName());
```

Itemクラスが持つ関数の一つに`GetName()`があります。
これは、アイテムの名前をstring型で出力する関数です。

上記の例を「ItemExp」という名前のアイテムが実行した場合、「このスクリプトを持つアイテムの名前はItemExpです」といった出力がされます。

次 : [⑨ HeliScriptのUpdate()関数について](<https://qiita.com/shirapy/private/ba5417cc9bce2f4de618>)
前 : [⑦ HeliScriptで制御構文を使う(for、while)](<https://qiita.com/shirapy/items/67f5aa258893694d64bb>)
【Vket Cloud】動画つき！ゼロから始めるHeliScript超入門⑤ - HeliScriptで変数を扱う 後編

# はじめに
Vket Cloudでは、「HeliScript」という独自のスクリプトを使用してコーディングを行うことで、ワールド内に高度なギミックを導入することが出来ます。

本記事では、HeliScriptで変数を使ってできること、変数の型ごとの値の表示方法を紹介します。

# 動画

<iframe width="560" height="420" src="https://www.youtube.com/embed/Qj3MQLB-PeU?si=Ahxxsf8jCM2rQDsN" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

# 変数で出来ること

変数は値を格納するだけでなく、値同士の計算に使用することが出来ます。

例えば、
```
component Example2
{
    int a; // int型の変数「a」を定義

    public Example2()
    {
        a = 1; // 変数aの中に1を格納
        a = a + 2; // aに現在のaに2を加えた数を格納
        hsSystemWriteLine("%d" % a); // aに格納した変数の中身を表示
    }
}

```
とすることで、もともと`1`が入っていたaに+2されて出力結果は`3`となります。

:::note
計算で使用できる演算子については[VketCloudSDKヘルプページ](<https://vrhikky.github.io/VketCloudSDK_Documents/latest/hs/hs_operator.html>)をご覧ください。
:::
:::note
上記例で使用している`+`は、Shiftキーを押しながら`;`(セミコロン)キーを押すことで入力できます。
:::

# float、string、boolの表示方法
小数を格納できるfloat型の場合、`%f`を、
文字列を格納できるstring型の場合、`%s`を使用します。
trueかfalseを格納できるbool型の場合、そのまま中身を表示する術はないため、`%d`で表示した際の中身で判断します。
`1`のときtrueで、`0`のときfalseです。

また、一文の中で2つ以上の変数を出力するときは、`%(変数名)`を繋げます。
例えば、
```
component Example2
{
    int a; // int型の変数aを定義
    float f; // float型の変数fを定義
    string s; // string型の変数sを定義

    public Example2()
    {
        a = 5 * 6; // 変数aの中に5×6の結果を格納
        f = 0.5; // 変数fの中に0.5を格納
        s = "計算結果 : %d" % a; // 変数sの中に「計算結果 : (aの中身)」を格納
        hsSystemWriteLine("float : %f, string : &s" % f % s); // 出力
    }
}
```
といったコードを書いた場合、最終的な出力物は、`float : 0.5, string : 計算結果 : 30`となります。

:::note
本記事では変数名として`a`や`s`のような1文字だけの名称を用いていますが、実際の開発で使用する場合、`characterCount`、`EnemyText`、`is_enter`のような、変数の使用用途を名前にすることで、何のための変数なのか分かりやすくなります。
:::

次 : [⑥ HeliScriptで制御構文を使う(if、switch)](<https://qiita.com/shirapy/private/064d7a26599deeb8296f>)
前 : [④ HeliScriptで変数を使う 前編](<https://qiita.com/shirapy/items/b094b4ac4dfc44bcaee6>)
ベーシックな組み込み① マイコン

# マイコンとは
Micro Controller Unit(MCU)、縮めてマイコン。
これは冷蔵庫や洗濯機などといった、いわゆる組み込み系の製品を作るのに必要不可欠な電子部品の一つです。
マイコンはこのような製品の動作を制御する役割があります。(炊飯器の例:ボタンを押されたら炊飯を開始する)
今回はこのマイコンの構造について簡単に説明していきます。

# マイコンの構造
マイコンは以下の図のようにCPU、ROM、RAM、I/O、周辺回路で構成されます。
![mcu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3735542/9553b781-8aca-82fe-43d6-c22c51bd2782.png)

後段からはそれぞれについて説明します。

## CPU
コンピューターの頭脳、CPUです。
ここでは以下のような処理をします。
- 演算処理や判定
- I/Oデータ処理
- RAM、ROM、周辺回路とのデータアクセス
CPUはこれらの処理を組み合わせて制御をしています。

## RAM,ROM
記憶を司る番人、RAMとROMです。
それぞれ説明します。
Random Access Memory(RAM)は、一時的なデータの保存に使うメモリのことです。変数の中身など、コードの実行中に値の変化するものが保存されています。
Read Only Memory(ROM)は、内容を書き換えることのできないメモリです。一般的にはプログラムが保存される場所で、電源投入時から読みだされます。
余談ですが、ファミコンのゲームのRTAで、カセットを差し替えることでエンドロールを読み出すといったバグ技がありますが、ああいうのはRAMを利用しています(多分)。

## I/O
入出力を行う場所です。

# 周辺回路
プログラミングでいうところのライブラリ、周辺回路です。
周辺回路は端的に説明すると、マイコンの機能を豊富にしてくれる回路群です。
今回詳しく説明はしませんが、シリアル通信(UART,SPI,I2C等)、タイマー、ADC、DACなどが例に挙げられます。
これらはマイコンによって載っていたりいなかったりするので、必ず公式サイトを見て確認しましょう。

# まとめ
簡単にではありましたが、マイコンの構造について説明させていただきました。
今後もベーシックな組み込みと題しまして、電気回路やマイコンに関して投稿していく予定です。
また、本記事は組込み初学者が学んだことをまとめたものとなっていますので、おかしい点がございましたらコメントで教えていただけると幸いです。
【Vket Cloud】動画つき！ゼロから始めるHeliScript超入門④ - HeliScriptで変数を扱う 前編

# はじめに
Vket Cloudでは、「HeliScript」という独自のスクリプトを使用してコーディングを行うことで、ワールド内に高度なギミックを導入することが出来ます。

本記事では、HeliScriptにおける変数とは何か、変数に値を格納し表示する方法を紹介します。

# 動画

<iframe width="560" height="420" src="https://www.youtube.com/embed/iGr9HoM7AZo?si=wtHuZwQ25VgAsVOV" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

# 変数って？
変数とは、プログラム上で文字や数字などのデータを格納する入れ物のようなものです。
格納した値を計算に使ったり、計算結果を新しく格納することが可能です。
変数を使うことで、プレイヤーの動作に応じて結果が変わるなど、高度なギミックを作ることが出来るようになります。

```
// 変数の例
int a; // aという名前の変数を定義
a = 10; // 変数aの中に10を格納

詳しくは次の章で紹介します。
```

# Vket Cloudで扱える変数の種類について
Vket Cloudで扱える変数の型は主に4種類あります。

### int

整数を格納することが出来ます。(格納できる値の例：0, -1 , 10000)

### float

整数に加え、小数を格納することが出来ます。(格納できる値の例：0.5, -1.21)

### string

文字列を格納することが出来ます。(格納できる値の例：Vketちゃん1号, ぶいけっとにゃん)
※文字列内に数字がある場合も、文字列として格納されます。

### bool

trueかfalseの2値のどちらかを格納することが出来ます。
trueが「はい」、falseが「いいえ」のような意味になります。

# 値の格納方法

変数を定義し、変数の中身を等式(=)を使うことで変数に値を格納することが出来ます。
```
component Example
{
    int a; // int型の変数「a」を定義

    public Example()
    {
        a = 1; // 変数aの中に1を格納
        hsSystemWriteLine("%d" % a); // aに格納した変数の中身を表示
    }
}

```

上記の例では、コンポーネントExampleの中にint型の変数「a」を定義しています。
ワールドを起動した際、初めに実行されるコンストラクタにて、`a = 1`の等式で、
aの中に「1」の値を入れています。

hsSystemWriteLineで変数の中身を表示しています。
少々特殊な書き方をしていますがint型の変数を表示するためには、`%d`という記載を行い、
""の後ろに `% (表示したい変数名)`と記載します。
今回の場合、aの中身をコンソールに表示する、といった内容になるため、コンソールには`1`と出力されます。

:::note
`=`はShiftキーを押しながら`-`(ハイフン)キー、
`%`はShiftキーを押しながら`5`キーを押すことで入力できます。
:::

次 : [⑤ HeliScriptで変数を使う 後編](<https://qiita.com/shirapy/private/ea06576b59ab00e5fb32>)
前 : [③ HeliScriptをシーンに組み込む / シーンから取り外す](<https://qiita.com/shirapy/items/927c7fa53f2c0a8981b0>)
【Vket Cloud】動画つき！ゼロから始めるHeliScript超入門③ - HeliScriptをシーンに組み込む / シーンから取り外す

# はじめに
Vket Cloudでは、「HeliScript」という独自のスクリプトを使用してコーディングを行うことで、ワールド内に高度なギミックを導入することが出来ます。

本記事では、HeliScriptをシーンに組み込む方法、シーンから取り外す方法について紹介します。

# 動画

<iframe width="560" height="420" src="https://www.youtube.com/embed/xfPgIVfX02A?si=zmPM0d3WjxYgYkYn" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

# 解説

### HeliScriptをシーンに組み込む
前章でも記載した通り、HeliScriptをシーンに組み込むには、**VKC Attribute Script** Unityコンポーネントを使用します。

初期状態だと、コンポーネントのリストが空の状態になっているため、「+」ボタンを選択、
その後「選択」ボタンを押しHeliScript一覧からシーンに組み込みたいHeliScriptを選択します。

この後、さらに「+」ボタンを選択することで、別のHeliScriptを組み込むことも可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3788807/72fc4d9d-037b-b0b1-cc74-b73738a3e155.png)

この時、一つのアイテムに複数個のHeliScrptが入った状態となります。
また、コンポーネント欄を調整することで、同じHeliScript内の異なるコンポーネントを登録させることも可能です。

:::note
**お芝居で例えると…**
HeliScriptを読み込むアイテム：役者
HeliScript：台本
コンポーネント：台本に書かれているセリフ

のような関係です。

複数のHeliScriptやコンポーネントを持たせることで、アイテム(役者)は複数の役を同時に演じたり、複数のセリフを覚えて行動したりします。
:::

### HeliScriptをシーンから取り外す

VKC Attribute Scriptのコンポーネントリストには、「-」ボタンがあり、これを押すことでシーン上からHeliScriptを取り外せる…わけではありません。

シーン上からHeliScriptを取り外すためには、もう1段階作業が必要になります。
それは、BasicSettingsが持つ、VKC Setting Base最下部のHeliScript一覧から取り外したいHeliScriptを「-」ボタンで除外することです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3788807/7484c3be-dabc-0b88-3a1a-7c4d3c79a2e1.png)

- VKC Attribute Scriptのコンポーネントリストで「-」ボタンを押し、外す
- VKC Setting BaseのHeliScript一覧から「-」ボタンを押し、外す

以上2点を行うことでHeliScriptをシーン上から取り外すことが出来ます。

::: note
リストから削除する要素を選択する際は、上記画像の「Element 1」のような文字が書かれている箇所をクリックする必要があります。
選択することで、選択された要素が青色になります。
この状態で「-」を押すことで削除を行うことが出来ます。
:::

:::note warn
使用しないHeliScriptを残したままにするのは、いわば役の無い台本が舞台の上にそのまま放置された状態です。
ワールドで思わぬハプニングが起きないよう、使わないHeliScriptはリストから外しておきましょう。
:::

次 : [④ HeliScriptで変数を使う 前編](<https://qiita.com/shirapy/private/b094b4ac4dfc44bcaee6>)
前 : [② HeliScriptを作る / Hello World!をコンソールに出力する](<https://qiita.com/shirapy/items/f09a39fb051fd6a5cb50>)
【Vket Cloud】動画つき！ゼロから始めるHeliScript超入門 - 目次

# はじめに
Vket Cloudでは、「HeliScript(ヘリスクリプト)」という独自のスクリプトを使用してコーディングを行うことで、ワールド内に高度なギミックを導入することが出来ます。

本記事では、HeliScriptによるコーディングの基礎について紹介しています。
今までHeliScriptを触ったことが無い方でも、これを読むことでHeliScriptを使いこなせるようになるかも…!?

<iframe width="560" height="420" src="https://www.youtube.com/embed/4wjFcz6bDeg?si=O-O5TbStyePXXQOP" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

各章には解説動画も掲載されています。
理解を深めるのにお役立てください。

また、本連載記事で使用している用語の意味を解説している、用語集も用意してあります。
記事を読んでいて分からない単語が出てきた場合、[用語集](<https://qiita.com/shirapy/private/d91f164b83e8eab06410>)をご覧ください。

# 対象読者
- Vket Cloudのワールドを作りたい人
- Vket Cloudでギミックを作ってみたい人
- HeliScriptについてこれから学習したい人、HeliScript初学者

※これまでプログラミングをしたことが無い人でも大丈夫です。

:::note
本記事は、VketCloudSDKの導入、および最小環境でのビルドが出来ている方向けの記事となっております。

Vket Cloudの開発に必要なアカウント設定につきましては [【ワールドの作り方：準備編vol.1】アカウント設定](<https://magazine.vket.com/n/n8dbabbb95bc8>)を、
VketCloudSDKの導入方法につきましては[【ワールドの作り方：準備編vol.2】 VketCloudSDKの導入](<https://magazine.vket.com/n/n084032c04059>)を
および最小環境でのビルド方法につきましては、[【ワールドの作り方：初級編vol.3】出力して中に入ってみよう](<https://magazine.vket.com/n/n3489d96bc151>)をご覧ください。

※外部のページにアクセスします。
:::

# 使用バージョン・環境
Windows10
Unity2019.4.31f1
VketCloudSDK13.7.7

コーディング環境
Visual Studio Code
※コーディング環境については次章の[HeliScriptを作成する環境を作る](<https://qiita.com/shirapy/private/633859a73189baa1d44f>)をご覧ください。

# 目次
**第1部：HeliScriptを作る準備をしよう**
[① HeliScriptを作成する環境を作る](<https://qiita.com/shirapy/private/633859a73189baa1d44f>)

**第2部：HeliScriptを作ろう、HeliScriptの取り扱い方**
[② HeliScriptを作る / Hello World!をコンソールに出力する](<https://qiita.com/shirapy/private/f09a39fb051fd6a5cb50>)
[③ HeliScriptをシーンに組み込む / シーンから取り外す](<https://qiita.com/shirapy/private/927c7fa53f2c0a8981b0>)

**第3部：変数と制御について学ぼう**
[④ HeliScriptで変数を使う 前編](<https://qiita.com/shirapy/private/b094b4ac4dfc44bcaee6>)
[⑤ HeliScriptで変数を使う 後編](<https://qiita.com/shirapy/private/ea06576b59ab00e5fb32>)
[⑥ HeliScriptで制御構文を使う(if、switch)](<https://qiita.com/shirapy/private/064d7a26599deeb8296f>)
[⑦ HeliScriptで制御構文を使う(for、while)](<https://qiita.com/shirapy/private/67f5aa258893694d64bb>)

**第4部：HeliScriptでオブジェクトを動かしてみよう**
[⑧ HeliScriptでシーン上のアイテムを取得する](<https://qiita.com/shirapy/private/9a6fb9dbb64a33d37fb5>)
[⑨ HeliScriptのUpdate()関数について](<https://qiita.com/shirapy/private/ba5417cc9bce2f4de618>)
[⑩ HeliScriptでVector3を使ってシーン上のアイテムを移動させる](<https://qiita.com/shirapy/private/0900d87929511b27943a>)
[⑪ HeliScriptでプレイヤーを取得しワープさせる](<https://qiita.com/shirapy/private/f798f8daef57840035fc>)

**第5部：HeliScriptについてもっと知ろう**
[⑫ HeliScriptにおけるコンポーネントとアイテムの関係性](<https://qiita.com/shirapy/private/ed8bbde518d4e4606c9b>)
[⑬ HeliScriptをより使いこなすには](<https://qiita.com/shirapy/private/e886683b34132c508f4f>)

**付録**
[用語集](<https://qiita.com/shirapy/items/d91f164b83e8eab06410>)
spotifyの再生中の曲をgoogleで検索する

## 現在使用している音楽サービス

昔は、amazon musicを使ってましたが、いつからだろうかうろ覚えだけど曲の再生内容がランダムになり、それが不満でspotifyに変えました。

## 知らない曲が気になる

聞いていると知らない曲が流れて、「おっこの曲ええやん？」とか「あれ、この曲ってなんの主題歌だっけ？」と思う事がたまにあります。
調べるのも結構面倒ですよね。
そんな時に、現在聞いている曲を検索するブックマークレットを準備しました。

## 使い方

1. ブラウザのブックマークのURL欄に、以下のスクリプトをコピペして保存する
1. spotifyで、曲を再生中にこのブックマークをクリック（開く）する
1. googleで曲の検索が入力されて開かれるのでそれっぽいページを探す（人力！）

:::note alert
現在は、動かなくなっているので以下の記事をご確認ください。
https://qiita.com/chaftta/items/4f5aa158e163bbcd381d
:::

```bookmarklet
javascript:(function() {let a = document.querySelector('a[data-testid="context-link"]');let name = a.getAttribute("aria-label").replace("%E5%86%8D%E7%94%9F%E4%B8%AD%EF%BC%9A", "").replace(" %E3%81%AE ", " ");let query = encodeURIComponent(name);window.open('https://www.google.com/search?q=%27 + query, %27_blank%27);})();
```
AWSさんがワークショップの環境を用意してくれているので大声で言いふらしたい

AWSのワークショップをあさってました。

実践力を鍛えるBootcamp - クラウドネイティブ編 -

https://catalog.us-east-1.prod.workshops.aws/workshops/a9b0eefd-f429-4859-9881-ce3a7f1a4e5f/ja-JP

いいですね～　実践力、鍛えましょう！

で環境構築をするぞーと見ていると。。。

**VS Code ServerをEC2で起動するCloudFormationテンプレートが用意されている！！！**

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/0ef4bd13-9329-caf8-4055-431ec40f6f29.png)

さりげない優しさ

すてきすぎ

やってみました。

## 手順

1. 上記ページの「Launch」リンクをクリックします
1. マネジメントコンソールのログインが必要でしたら、ログインしてください
1. スタックのクイック作成画面が表示されます。必要でしたらパラメータなどを修正してください
    デフォルト値は以下のとおりです
    
    ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/32de0670-b57d-c959-0604-972ae8a96881.png)

    ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/8c9245c2-484b-3658-899c-cd3426dd22c9.png)

    ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/b364d63a-572d-6940-1621-dfae22f4f5d4.png)

1. スタックのデプロイが始まりますので完了するまで待ちます

    ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/3f7d7730-1371-f92e-3a4c-8e44fb228299.png)

1. 出力タブに「PasswordURL」と「URL」が表示されますので、まずは「PasswordURL」のリンクをクリックします

    ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/608614bb-5637-b686-f094-3ca95740eced.png)

1. Secrets Managerの画面に遷移します。「シークレットの値を取得する」ボタンをクリックすると、パスワードが表示されるのでメモしてください

    ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/d19e4b9e-c771-7b3e-58d2-7cf361bb5161.png)

1. CloudFormationの画面に戻り、「URL」のリンクをクリックします
    ログイン画面が表示されるので、先程のパスワードを入力します

    ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/563967d5-5c4a-b517-8293-3e1e66f50ad7.png)

1. すると、VS Code Serverの画面が表示されます

    ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/ea6b8fa2-9a0f-fd50-e439-9c3a0a8869eb.png)

**簡単！！！**

Amazon Q Developerをはじめ、開発に必要そうな拡張機能もインストール済みです。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/1a8a5eb4-0a81-72e8-a0be-6b0932ae9001.png)


ちなみにCloudFormationテンプレートを ~~AWS Application Composer~~ **AWS Infrastructure Composer** で表示するとこのようになります

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/b853e72c-0baa-4dbf-b440-cb684979ec97.png)

## EC2インスタンスの停止方法

EC2を停止したい場合は、[EC2の管理画面](https://ap-northeast-1.console.aws.amazon.com/ec2/home?region=ap-northeast-1#Instances)にアクセスします。「VSCodeServer」という名前のインスタンスを選択し、「インスタンスの状態」メニューの「インスタンスを停止」をクリックします。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/2893fcd2-9b0c-3105-c3c2-fcfe2093ca01.png)

## まとめ

**もっとアピールしていいのに！**

---

ちなみに、パスワードの部分ですが、EC2のrunCommandとしてこのような内容がセットされていたので、きっとここです。

```yaml
- !Sub |
  sudo tee /home/ubuntu/.config/code-server/config.yaml <<EOF
  cert: false
  auth: password
  hashed-password: "$(echo -n $(aws secretsmanager get-secret-value --secret-id '${VSCodeServerPasswordSecret.Id}' --query 'SecretString' --output text) | sudo npx argon2-cli -e)"
  EOF
```
GitHub Spark - アイデアをアプリに

## はじめに
GitHubが新しいプロジェクト「GitHub Spark」をテクニカルプレビューとして発表しました。「アイデアを伝えるだけでアプリが作れる」- それがGitHub Sparkの本質です。AIを活用して誰でも簡単にパーソナライズされたアプリケーションを作成できるプラットフォームで、コードを書いたり、デプロイしたりすることなく、自分だけのアプリを作れることが特徴です。

<iframe width="560" height="315" src="https://www.youtube.com/embed/oM2amcnVmzM?si=m8p5DJTI0P1zgMTV" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

<iframe width="560" height="315" src="https://www.youtube.com/embed/zB-izOTcQ6s?si=2qyV1Q-VEd49w6g4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

## GitHub Sparkとは

GitHub Sparkは、ユーザーが自分のニーズや好みに合わせたマイクロアプリ（"sparks"と呼ばれる）を作成・共有できるAIパワードツールです。作成したアプリは、デスクトップやモバイルデバイスから直接利用することができます。

### マイクロアプリの考え方

GitHub SparkはUnixの哲学に基づいており、「1つのことを、特定のユーザーのために、必要な期間だけ、うまく実行する」というアプローチを採用しています。「マイクロ」という言葉は、アプリの価値の大きさではなく、機能の複雑さを指しています。

実際のユースケースとして、以下のようなアプリケーションが作られています：

- 子供の小遣い管理アプリ（目標達成時にAIが祝福メッセージを生成）
- カラオケナイトの参加者トラッキングアプリ
- AIを使用した都市情報検索アプリ（10歳の子供が学校用に作成）
- HackerNewsクライアント（コメントスレッドをAIで要約する機能付き）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35782/7bc52129-e3cc-d775-3946-82a1eab0d987.png )
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35782/2590582a-a952-aeff-d832-fa73142c4dbf.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35782/108c12a3-4898-5884-b47d-4ca3db0e8117.png)

## 主要な機能

### 1. 自然言語ベースのエディタ

アプリ作成を簡単にするため、以下の機能を提供しています：

- **インタラクティブプレビュー**：入力した自然言語の表現をすぐにアプリとして表示
- **リビジョンバリアント**：1つのリクエストに対して複数の異なるバージョンを生成
- **自動履歴管理**：すべての変更を自動保存し、簡単に以前のバージョンに戻れる
- **AIモデル選択**：Claude Sonnet 3.5、GPT-4o、o1-preview、o1-miniから選択可能

### 2. マネージドランタイム環境

アプリの実行環境として、以下の機能を提供：

- **自動デプロイ**：作成したアプリはすぐにPWAとして利用可能
- **デザインシステム**：美しいUIコンポーネントとカスタマイズ可能なテーマを提供
- **データストレージ**：Key-Value形式のデータ保存機能と編集ツールを提供
- **AI機能の統合**：GitHub Modelsと統合され、簡単にAI機能を追加可能

### 3. 共有と連携機能

- 作成したアプリを他のユーザーと共有可能
- 読み取り専用または読み書き可能な権限設定
- 他のユーザーのアプリをお気に入りに追加したり、リミックスして独自のバージョンを作成可能

## 現在の開発状況と今後の展開

GitHub Sparkは現在テクニカルプレビュー段階であり、以下の機能強化を計画しています：

1. **コラボレーション機能の拡張**
   - パブリックギャラリーの提供
   - フォークされたアプリの変更のマージ機能
   - マルチプレイヤー機能の実装

2. **エディタ機能の強化**
   - アプリの動作をより詳細に調整できるX-rayモードの追加

3. **ランタイム環境の拡充**
   - コンポーネントの追加
   - サードパーティサービスとの連携強化
   - ファイルストレージとベクター検索の実装

現在、テクニカルプレビューへの参加はウェイトリスト制となっており、GitHubは参加ユーザーと密接に連携しながら週次で機能改善を進めていく予定です。

---

本記事は、[GitHub Next](https://githubnext.com/projects/github-spark)で公開された情報をもとに作成されています。GitHub Sparkについての詳細な情報や最新のアップデートについては、公式サイトをご確認ください。

## 関連情報
[コード×AIーソフトウェア開発者のための生成AI実践入門](https://amzn.to/4fnqVjw)
[Microsoft Copilot for Microsoft 365活用大全](https://amzn.to/48w7XoG)
plantumlで作成した図をエクセルのオブジェクトとして貼る


# 概要
plantumlで作成した図を、エクセルに貼る。
エクセル上でもある程度修正できるように、オブジェクトとして変換することが目的です。

# 手順

## 1.plantumlの図をsvg形式で出力する
Online Server→SVGを右クリック→「名前を付けてリンクを保存する」
https://www.plantuml.com/plantuml/uml/


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/e43de61b-06b1-5c64-c38c-80a359d55d4b.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/d2f31c17-0bcf-74c1-2c74-145c684e1b28.png)


## 2. 1.で出力したsvgファイルをexcelで読み込む
挿入→画像→このデバイスを選択して、svgファイルを選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/73dddb83-dc11-9e61-08e0-da948e59632e.png)


## 3. グループ化を解除する
読み込んだsvgの画像を右クリックして、グループ化→グループ解除を行う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/9489dc4f-e763-2fbc-a90c-b9b1689a6550.png)


# 使用感-エクセルでの修正感 良好
修正しやすいと感じました。
オブジェクトの変換、良い感じです。

## 文字
文字として編集できる。
画像で保存されていないのがうれしいですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/801fd6f3-36ac-04cb-0d8d-301a276a6ec6.png)


## ノードオブジェクト：移動は容易。複数のパーツで構成されているが、適切にグループ化されているため。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/6a93eb4e-83d9-85a5-d19f-6d8c6873b6c8.png)



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/803017fe-2182-1758-4a82-c5034a94787f.png)


## 矢印
対角線に直線を引いた画像。エクセルの線ではない。
ただの画像なのでオブジェクトと繋げることはできない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/f9f83ce0-d666-37e6-72d5-1c0a874c9f19.png)


参考：エクセルの線の場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/686bf0c3-7bbd-e598-4027-81961f080ff2.png)

# 一言
これで「君の書いた図エクセルで編集できないじゃん＾＾；」って言われないで済む！

# 参考
plantuml
https://plantuml.com/ja/deployment-diagram


[draw.io]出力した図を、Excel上で微調整する
https://non-yokomoji.net/drawio_excel/
googleからbingに乗り換えた

github Copilot chatに敬服したのもありgoogleからbingに乗り換えた。
- Copilotボタンがある。
googleにはない。googleは戦略を間違っちゃったのか苦しんでいるみたいに見える。ひとつはtensorflow,ひとつはBartかな。google colabは応答が遅いーサブスクしたけど遅くて使う気しないのでやめた。金返してほしい
Microsoftは,github,python,linux,vscode,pytorch,GPTと気がつくとみな取り込んでいる。開発者レベルの人間を取り込むことの重要性を理解している。10年前から細線が描けないIntelは国で買い取るみたいだけど大丈夫か。
外野ではなんとでも言えるけど現場で戦ってる人たちというのは偉大だ

ubuntu22で、emacsがこわれたので修復したかった。いままでは検索でやりかたを見つけていた。

そもそもインストールトラブルは、どこが壊れているかわからないので、コレを打ってみろ、というコマンドを試してもたいてい治らなくて次のエラーが出る。それを根本まで遡って直していかないといけない。その道筋で、エラーをbingにしつこく入力して解決できた。チャット力が良くなってきたように思う。ぼくの入力も全て学習しとるんだと思う。OK!って最後に入れてやると喜んでくれるからまあうまく行ったときには入れたげてる。

検索するよりbingに聞いたほうが早い時代になったんだと思う。そうは言ってもウソかホントかとかがわからないとうまく聞けないだろう。

bingのcopilotボタンはなかなかに良い。エラーメッセージもそうだし、論文検索より先にbingに聞いてみるのもあり得る。試して損はないかな。

以下、GPTのことを聞いてみたらやはりそれなりによく知ってるみたいだ。会話が成立する。うまいこと褒めてくれるのもいいのかもしれんー学ばないといけない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482779/b8c02513-82e1-aa56-9fbc-9d55b4f1a522.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482779/f829620a-80af-dfdf-528e-26051ad6ac12.png)
実際、自律的に学べるようになるともう人間がQ&Aを作ってやらずとも学習していける。自分で自分のコードも書き換えていくだろう。これがシンギュラリティということになる。

とはいっても（いかにも的な用語の）シンギュラリティという用語には違和感があるー数十年もかけて緩やかに変化していく。自動運転でもそう簡単に任せることはできない。産業革命や、明治維新の鉄道導入もシンギュラリティと呼びたければ呼べるでしょう。


GPTの方がBARTより上ですよね、とか言うと謙遜してきたけど、トランプ、というとだいぶと興奮してました。以下。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482779/fb548163-264a-879c-ded4-88a2ee4ee1eb.png)
ここまで言うか、というぐらい書いてる。これって下手すると民主主義の否定にも聞こえる。

将来的に裁判とか政治的決定についてはどうなっていくのか？陪審員よりGPTのほうが確かでしょうという意見は出る。あるいは陪審員（裁判官も）が皆GPTに意見を伺うことになる。棋士がAIに聞くのならいいけど、裁判官がAIに聞くのはどうなんかな。Copilotも「一概に正誤を判断することは難しいです。なのでこの私に聞いてください」となるかも。Copilotはハレルヤとかダニューバという名前に改名しておくほうがいいです

絵も描ける。早いし、クオリティ高くなってる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482779/0694f27f-a3f9-780d-c7a7-3bd4782e361d.png)
BrowserSyncで実機確認できないときに確認すること

Webサイトをコーディングしている際に必要な実機確認。
実機確認を楽に行えるツールとしてBrowserSyncがあります。

BrowserSyncを起動して、同じWifiに接続しているスマートフォンでWebサイトに接続すると、実機でWebサイトを確認できます。

しかし、同じWifiに接続しているのにスマートフォンでサイトが見えないときがある:expressionless:

そんな時に確認するべきポイントについてまとめました。

## ①本当に同じWifiに接続している？

凡ミスですが、よくあることです。
PCやスマホで同じWifiにつないでいるつもりになっていても、なっていないことがあります。

## ②localhostでWebサイトを表示していない？

BrowserSyncを起動すると以下のログが出ます。

```
[Browsersync] Access URLs:
 ---------------------------------------
       Local: http://localhost:3001/
    External: http://10.0.1.22:3001/
 ---------------------------------------
```
スマートフォンで閲覧するには`External: http://10.0.1.22:3001/`でWebサイトを表示する必要があります。

## ③ネットワークインターフェイスの優先順位設定がどうなっているか？

Wifiが複数繋がる環境や、有線とWifiを使い分けている環境にいると、BrowserSyncが違うhostに接続してしまうことがあります。（理由はわかりませんが…）
そうなると、スマートフォンでWebサイトを確認することが出来ません。

### ネットワークインターフェイスが複数あるかの確認方法

①コントロールパネルで確認する方法
コントロールパネルのネットワーク接続を開きます。

:::note info
ショートカットキー：「Windows」キー + 「R」を押してファイル名を指定して実行に「ncpa.cpl」と入力すると、簡単に開けます。
:::

上記で以下の画像のように赤い×がついていない機器が、有効になっているネットワークインターフェイスです。

![Wifiが無効になっている](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604490/6154460a-7802-bcd4-8647-bf7d6fc680c9.png)

②コマンドで確認する方法

ターミナルでipconfigをたたくと接続しているネットワークインターフェイスが確認できます。

以下、抜粋内容です。
```
Wireless LAN adapter Wi-Fi:
   IPv4 アドレス . . . . . . . . . . . .: ★★★.●●.××.41
イーサネット アダプター イーサネット 4:
   IPv4 アドレス . . . . . . . . . . . .: ★★★.●●.××.12
イーサネット アダプター VirtualBox Host-Only Network:
   IPv4 アドレス . . . . . . . . . . . .: ★★★.●●.××.33
イーサネット アダプター イーサネット:
   IPv4 アドレス . . . . . . . . . . . .: ★★★.●●.××.5
```

### 優先順位変更方法

コントロールパネルのネットワーク接続を開きます。

接続したいネットワークインターフェイスを右クリック→「プロパティ」を選択
![プロパティを選択している図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604490/33428427-6603-b7f9-20be-57ffffb9d7c6.png)

インターネットプロトコルバージョン4(TCP/IPv4)を選択した状態で、プロパティをクリック
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604490/83372272-e5fa-73c5-490a-a8ccccdbc3ef.png)

詳細設定をクリック
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604490/7a696ebc-b1cc-5a09-96ef-c37458ef2b63.png)

自動メトリックのチェックボックスを外し、インターフェースメトリックの値を「1」にする。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604490/bf1b7a7c-3444-b7b3-4f6d-fb0aec071f45.png)

上記の作業後、再びBrowserSyncを起動すると意図通りのhostで起動することが出来ます:satellite_orbital:
HTMLのリスト表示：<ol>、<ul>、<li>タグと入れ子構造でコンテンツを整理しよう

大学に入ったばかりの頃、HTMLを軽く習った記憶があるんですが……ほとんど覚えてない！ ということで、復習がてらリスト表示について改めてまとめてみます。`<ol>`、`<ul>`、`<li>`タグの使い方と、入れ子構造の作り方を解説します。

## 1. 順序付きリスト：\<ol>タグ

`<ol>`タグは、番号付きのリストを作成するために使用します。リストの項目は自動的に番号が振られ、順番が明確になります。

```html
<ol>
  <li>最初の項目</li>
  <li>2番目の項目</li>
  <li>3番目の項目</li>
</ol>
```

出力結果:

1. 最初の項目
2. 2番目の項目
3. 3番目の項目


`<ol>`タグには、番号の開始値や種類を指定する属性があります。

* `type`属性: 番号の種類を指定します。
    * `1` (デフォルト): アラビア数字 (1, 2, 3...)
    * `A`: 大文字アルファベット (A, B, C...)
    * `a`: 小文字アルファベット (a, b, c...)
    * `I`: 大文字ローマ数字 (I, II, III...)
    * `i`: 小文字ローマ数字 (i, ii, iii...)
* `start`属性: 番号の開始値を指定します。

```html
<ol type="A" start="3">
  <li>3番目の項目 (C)</li>
  <li>4番目の項目 (D)</li>
  <li>5番目の項目 (E)</li>
</ol>
```

出力結果:

C. 3番目の項目 (C)
D. 4番目の項目 (D)
E. 5番目の項目 (E)


## 2. 順序なしリスト：\<ul>タグ

`<ul>`タグは、箇条書きのリストを作成するために使用します。リストの項目には、デフォルトで黒丸が表示されます。

```html
<ul>
  <li>最初の項目</li>
  <li>2番目の項目</li>
  <li>3番目の項目</li>
</ul>
```

出力結果:

- 最初の項目
- 2番目の項目
- 3番目の項目

`<ul>`タグでは、`type`属性を使って箇条書きの種類を変更できますが、現在ではCSSでスタイルを設定するのが一般的です。


## 3. リストの入れ子構造

`<ol>`タグと`<ul>`タグは、入れ子にして階層構造を持ったリストを作成できます。`<li>`タグの中に、さらに`<ol>`タグや`<ul>`タグを配置することで実現します。

```html
<ol>
  <li>果物
    <ul>
      <li>りんご</li>
      <li>バナナ</li>
      <li>オレンジ</li>
    </ul>
  </li>
  <li>野菜
    <ul>
      <li>にんじん</li>
      <li>トマト</li>
      <li>きゅうり</li>
    </ul>
  </li>
</ol>
```

出力結果:

1. 果物
    - りんご
    - バナナ
    - オレンジ
2. 野菜
    - にんじん
    - トマト
    - きゅうり


## 4. まとめ

`<ol>`、`<ul>`、`<li>`タグを適切に使うことで、Webページの情報を整理し、ユーザーにとって見やすく理解しやすいコンテンツを作成できます。入れ子構造を活用することで、より複雑な情報を階層的に表現することも可能です。  リストのスタイルはCSSで細かく調整できるので、Webサイトのデザインに合わせてカスタマイズしましょう。

## 5. 参考文献
- https://developer.mozilla.org/ja/docs/Web/HTML/Element/ol
- https://developer.mozilla.org/ja/docs/Web/HTML/Element/ul
- https://developer.mozilla.org/ja/docs/Web/HTML/Element/li
kcl runに引数を渡せるようにして、KCLをただの"Better YAML"からYAMLジェネレーターに進化させる方法

KCLは、YAMLを安全かつ可読性高く記述できる設定言語です。Kubernetesとの相性が良く、マニフェストがYAMLであることに悩まされている方にはぜひ試してほしい言語です。

KCLは一見すると単なる"Better YAML"です。しかし、KCLの真の力は単なる"Better YAML"としての使用にとどまりません。本稿では、`kcl run`コマンドの引数機能を活用して、KCLを動的なYAMLジェネレーターへと進化させる方法を解説します。

## なぜYAMLジェネレーターが必要か？

Infrastructure as Code (IaC)やKubernetesの設定ファイルなど、現代のクラウドネイティブな環境では大量のYAMLファイルを管理する必要があります。環境やパラメータによって微妙に異なる設定ファイルが必要になることも多々あります。

これらの課題に対して、KCLを「YAMLジェネレーター」として使用することで：

- 環境ごとの設定値を動的に注入
- 共通部分のテンプレート化
- 型安全性の確保

といった利点を得ることができます。

## 基本的な使い方：静的なYAML生成

まず、シンプルなKCLファイルから始めてみましょう：

```py:main.k
message = "Hello Alice"
```

このファイルを`kcl run`コマンドで実行すると：

```sh
kcl run main.k
```

次のようなYAMLが出力されます：

```yaml
message: Hello Alice
```

これだけでは単なる"Better YAML"ですね。では、これを動的なジェネレーターに進化させていきましょう。

## YAMLジェネレーターへの進化：引数の導入

### Step 1: 基本的な引数の受け取り

KCLの「Top-level argument」機能を使って、実行時に値を注入できるようにします：

```py:main.k
_name = option("name")
message = "Hello ${_name}"
```

実行時に引数を渡すことで、動的にYAMLを生成できます：

```sh
kcl run main.k -D name=Bob
```

出力：
```yaml
message: Hello Bob
```

💡 **Tips**: 変数名の先頭の`_`（アンダースコア）には特別な意味があります。アンダースコアで始まる変数は最終的なYAML出力から除外されます。これにより、生成に使用する中間変数とYAMLに出力したい変数を明確に区別できます。

### Step 2: 堅牢性の向上

#### 必須引数の設定

実行時の引数忘れを防ぐため、必須パラメータを設定できます：

```py:main.k
_name = option("name", required=True)
message = "Hello ${_name}"
```

引数なしで実行すると、親切なエラーメッセージが表示されます：

```
EvaluationError
 --> /path/to/main.k:1:1
  |
1 | _name = option("name", required=True)
  |  option('name') must be initialized, try '-D name=?' argument
  |
```

#### デフォルト値の設定

オプショナルな引数にはデフォルト値を設定できます：

```py:main.k
_name = option("name", default="Alice")
message = "Hello ${_name}"
```

この場合：
```sh
# デフォルト値が使用される
kcl run main.k
message: Hello Alice

# 引数で上書き可能
kcl run main.k -D name=Bob
message: Hello Bob
```

### Step 3: 型安全性の確保

数値を扱う場合など、型の制約が重要なケースでは`type`パラメータを使用します：

```py:main.k
number = option("number", type="int")
next_number = number + 1
```

不正な型の値を渡すと、コンパイル時にエラーが検出されます：

```sh
kcl run main.k -D number=foo
EvaluationError
 --> /path/to/main.k:1:1
  |
1 | number = option("number", type="int")
  |  cannot use 'foo' as type 'int'
  |
```
## まとめ

KCLの引数機能を活用することで：

1. 静的なYAML定義から動的なYAMLジェネレーターへ
2. 環境やパラメータに応じた柔軟な設定生成
3. 型安全性による堅牢な設定管理
4. テンプレート化による設定の再利用性向上

が実現できます。

これにより、KCLは単なる"Better YAML"から一歩進んで、より強力な設定管理ツールとして活用できます。大規模なシステムの設定管理や、マルチ環境対応が必要なプロジェクトで、その真価を発揮するでしょう。

## 参考文献

- [KCL Documentation - Top-level argument](https://www.kcl-lang.io/docs/reference/lang/tour#top-level-argument)
【個人メモ】Ruby on Rails チュートリアル 第6章

Ruby on Railsチュートリアルで学んだ内容を個人的なメモとして簡単にまとめたものです
# 個人メモ
- Model
データモデルとして扱うデフォルトのデータ構造のこと
- Active Record
データベースとやり取りするRailsのライブラリ
Active Recordは、データオブジェクトの作成/保存/検索のためのメソッドをもつ
- マイグレーションコマンド
rails generate model モデル名 属性
マイグレーションファイルを変更すると後からデータベースの構造を変更することが可能
- マイグレーションの適用
rails db:migrate
- モデルに関するテスト
rails test:models
- 有効性（Validity）の検証
valid?メソッドでオブジェクトが有効かどうか確認できる
- 存在性の検証
validatesメソッドでpresence: trueを追加することで存在性を検証した
- フォーマットの検証
formatオプションを用いて、有効なメールアドレスにのみマッチする正規表現を組み立てることで検証した
- 一意性の検証
  - validatesメソッドでuniqueness: trueを追加
  - データベースのレベルでも一意性を保証するため、emailのカラムにインデックスを追加
  - インデックスの追加は検索の効率も向上させる
- callbackメソッド
オブジェクトが存在する間の特定の時点で処理を行うことができる
- has_secure_password
セキュアなパスワードを実装できる
  - セキュアにハッシュ化したパスワードを、データベース内のpassword_digest属性に保存できるようになる
  - 2つの仮想的な属性（passwordとpassword_confirmation）が使えるようになる。また、存在性と値が一致するかどうかのバリデーションも追加される
  - authenticateメソッドが使えるようになる。引数の文字列がパスワードと一致するとUserオブジェクトを返し、一致しない場合はfalseを返す
ログファイル名を動的に変更する

初出ではMonologのログ書式でしたが、laravel.logと同じログ書式にするため、tapオプションを利用するよう改稿しました。

------

## laravel.log に何でもいれるな

原則として laravel.log はエラーログだけにしたい。エラーが発生しないなら常に空っぽの状態というのが心休まる。
開発時に Debug ログの出力を仕込んだなら、コミットするときに削除（せめてコメントアウト）してもらいたい。

デバックが必要な事態が起きたときに Debug ログを仕込んで laravel.log を監視しても、全然関係ないデバッグ情報が延々と流れてきては辟易する。

定期実行タスクの実行ログや特定機能のデバッグログは、それぞれの機能や目的に応じてログファイル名を変えて保存したい。……ということで、ログファイル名を指定できるカスタムヘルパー logger_to を作ってみた。

### カスタムログの設定

まずは config/logging.php にカスタムログ用のチャンネルを追加する。
ドライバーが single なのは、ログローテションは logrotate でおこなうので、Laravel 側で日付毎ログにするのは余計なお世話だから。

```php
'channels' => [
    
    // logger_to 用カスタムチャンネル
    'custom_file' => [
        'driver' => 'single',
        'path' => storage_path('logs/custom.log'),
        'level' => 'debug',
        'tap' => [App\Logging\CustomizeLogFormat::class], // カスタムフォーマッタ
    ],

```


aa/Logging/CustomizeLogFormat.php

```php
<?php

namespace App\Logging;

use Monolog\Formatter\LineFormatter;
use Monolog\Handler\StreamHandler;

class CustomizeLogFormat
{
    /**
     * カスタムログの設定
     *
     * @param  \Monolog\Logger  $logger
     * @return void
     */
    public function __invoke($logger)
    {
        foreach ($logger->getHandlers() as $handler) {
            if ($handler instanceof StreamHandler) {
                $handler->setFormatter(new LineFormatter(
                    null, // デフォルトのフォーマット
                    null, // デフォルトの日付フォーマット
                    true, // マルチラインサポート
                    true  // 末尾の改行を削除しない
                ));
            }
        }
    }
}

```

### カスタムヘルパーを作成



app/Helpers/custom.php
```php
<?php

use Illuminate\Support\Facades\Log;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;

if (!function_exists('logger_to')) {
    /**
     * 名前をつけてログを保存
     *
     * @param string $fileName : ファイル名（拡張子不要）: 区切りでログレベルを指定可
     *    ログレベル（debug (default), info, notice, warning, error, critical, alert, emergency）
     * @param string $message  : ログメッセージ
     * @param array  $context  : コンテキスト情報
     * @return void
     */
    function logger_to(string $fileName, string $message, array $context = []): void
    {
        if (preg_match('/(.+):(.+)/', $fileName, $m)) {
            $fileName = $m[1];
            $level = $m[2];
        }
        $level = $level ?? 'debug';

        // ファイル名に拡張子があれば削除して .log に置換
        $fileName = preg_replace(['/\.[^.]+$/', '/$/'], ['', '.log'], $fileName);

        // カスタムログチャネルを一時的に構築
        $logger = Log::build([
            'driver' => 'single',
            'path' => storage_path('logs/'. $fileName),
            'level' => $level,
            'tap' => [App\Logging\CustomizeLogFormat::class],
        ]);

        // 指定されたログレベルでメッセージを出力
        $logger->{$level}($message, $context);
    }
}
```

### オートロード設定
composer.json に追加
```php
// composer.json
"autoload": {
    "psr-4": {
        "App\\": "app/"
    },
    "files": [
        "app/Helpers/custom.php"
    ]
}
```
オートロードのリフレッシュ
```bash
composer dump-autoload
```

### 使用例
- mydebug.logに変数$userの配列をDEBUG出力
  ```php
  logger_to('mydebug', 'user', $user->toArray())
  ```
- mytask.logにタスクの開始をINFO出力
  ```php
  logger_to('mytask:info', 'start task command');
  ```
Qiitaに投稿された質問に回答してみた！

## Qiitaに投稿された質問に回答してみた！
Qiitaの利用を始めてもうちょっとで1年になります。
これまでは自分で解決できたり対応できたことを、ちょっとニッチかもしれないけど同じように思ったり困ってる人もいるかもしれないなー、というような感じで記事の投稿を中心にしてきました。
毎月投稿すると、Contributionsのバッチがもらえるので、できれば毎月何か投稿したいなーと思っていましたが、なんだかんだと毎月何かしらを投稿してきました（内容はともかく）。
Qiitaには質問タブがあり、そこでは何かしら開発で困っている人が質問を投げかけ、誰かが回答する、というような体裁になっているようです。
全然わからない内容もありますが、Pythonなど詳しくはないもののわかりそうな内容も日々質問投稿されています。
+ 質問を投稿したものの回答がなかなかつかないと質問者のモチベーションも下がってしまうかも？
+ ちょうど今は私に時間があるので、スキルはないけど時間はある私が回答すれば全体としてパフォーマンスがあがるよね！
+ いろんな質問に回答することで、自分のスキルアップも期待できるかもしれない！

なんてことを思いながら、物は試しにちょっと引っかかった質問にどんどん回答してみることにしてみました。

## 回答する立場で思う「ここが変だよ質問投稿」
### 質問にコードが記載されていない
何かしらコードを書いて、思ったような挙動になっていなかったり、エラーになっていたりするのですが、肝心のコードが記載されていなかったりします。
質問投稿のテンプレには、コードもあるので、関係ありそうなコードは貼っておいて欲しいところです。
コードを貼る際、```でコードを挟んで、コードブロックにしてね、というところまで、1つ目の回答コメントになっていることも多いですね。
### それらしい回答をしたら質問者からレスポンスがなくなる
私も無知なため、ドンピシャの回答はできないのですが、恐らく核心に近いであろう回答ができていると感じることがあります。
きっと解決するんじゃないか？と思うのですが、その後、質問者からは応答がなくなること多数です。
「便りがないのは元気な証拠」
たぶんうまくいったのだろう、と思うのですが、できれば「うまくいきました！」みたいなコメントをもらえるとちょっとうれしいです。
### いきなりクローズされる
さっきのレスポンスがなくなるにも近いのですが、いきなり質問がクローズされることもあります。
たぶんうまくいったということなんだと思いますが、できれば「こうやったらうまくいきました」というようなコメントがあるとうれしいです。
### 最終的にどうやって解決したのか書かれない
上記2つと同じような内容ですが、「書かれた方法とは違いますが、解決しました」というような感じで、終わってしまうパターン。
せっかく世界に開かれたインターネットに書き残すのですから、同じような内容で困っている人が検索の末にたどり着く可能性もあるので、こんな風に直すとうまくいきました！みたいなのがあると、良いのではないでしょうか
## 質問投稿から見る、質問者の傾向と対策
ネットを駆使することで、60～70点くらいでとりあえずは解決できるようになれるのではないかと思います。
### エラーが出たら、そのエラーメッセージで検索してみよう
エラーがでたのはあなた一人だけではなく、同じように既にエラーで困った人が世界にはいるかもしれません。
そこには解決したコードが書いてあったりすることも少なくありません。
### ライブラリやgithubなどのドキュメントを読んでみよう
ライブラリやgithubのドキュメントに、丁寧に解説されていることも少なくありません。
サンプルコードも参考になることが多いです。
エラーや事象で検索してみると、github issueに解決法が記載されていることもあります。
### サンプルコードから発展させられないか
いきなり作りたいものを創造するのは結構大変です。
サンプルコードを基本にして、そこから自分が作りたいものに変更を加えていくと、変更部分も明確なのでトラブル時の対応もしやすいと思います。
### 機械翻訳を活用しよう
検索した結果、表示されるのはgithub issueであったり、ライブラリのドキュメントだったり、誰かのblogだったりで、言語が英語や中国語ということも多々あります。が、翻訳機能でなんとなくわかることも多いです。
全てに日本語のドキュメントがあればいいですが、結局英語のドキュメントを読むことはとても多いので、英語だからと拒否せず、とりあえず読んでみることをおすすめします
（読んだあげく、なるほどわからん、ということも多々ありますが）
### 生成AIも活用しよう
ChatGPTなど、いろんな生成AIがありますが、プロンプトでコードを生成してもらうことも可能です。
作りたいプログラム全てを一度に作ってもらうのは難しいとは思いますが、ある部分の機能や、部分的なロジックなどは提案してもらうことは可能だと思います。
提案してもらったコードでエラーが出た場合にも、このようなエラーがでました、と再質問すると、エラーの回避方法も提案してくれることもあります（提案できないこともありますが）
中にはトンデモコードが出てきたりもしますが、少なくともある程度プロンプトに記載された仕様に従ったものが提案されるのではないでしょうか

## まとめ
+ 同じようなことに悩んでいたり、同じように変なことをしている人が世界にはたくさんいるので、検索をして情報を集めたら、結構なんとかなるよ！
+ 参考になる情報が、Qiitaをはじめとして、きっとどこかにあるよ！（あるよ！）
+ 大丈夫、私も初心者だ！（実際初心者だ）
Swift .onChangeの基本形

# はじめに

業務でソースコードを読む際に出てくると少し調べるのに時間をかけてしまうので基本形だけでも調べなくてもいいようにアウトプットしておきます。

## できること

- ドラッグやスワイプに反応して状態を更新することができる
- データの変更があったタイミングで変更があったものを新しい値として使用できる
- バリデーションなどを入力後に即座に実行できる

## 例

例えばこんなテキストフィールドがあったとします。

```swift
struct ContentView: View {
  // 入力した値をもつ変数
  // 最初は空文字なので""としてます。
  @State var text: String = ""

  var body: some View {
    VStack {
        TextField("入力してね", text: $text)
    }
  }
}
```

ここで入力するたびにデバックエリアにprintしたいとき、入力するたびにバリデーションを実行したいときなどに使えるのが`.onChange`です
以下のように編集しましょう

```swift
TextField("入力してね", text: $text)
  .onChange(of: text) {
    print(text)
}
```

これでビルドして試してみると入力するたびにprintされるのがわかります。
今回はprintの例を上げましたが、一般化すると以下のようになります。

```swift
.onChange(of: [変更を監視したい変数]) {
  // 更新された変数を用いて実行したい処理
}
```

- `// 更新された変数を用いて実行したい処理`の部分は`[変更を監視したい変数]`をそのまま使って大丈夫です。
- iOS17以降は`onChange(of: ) { _ in }`は非推奨となりました。

## そのほか

状態を監視して変更があったら更新、何か処理をするモディファイアはいろいろあります。
例文も込みで紹介していきます

**テキストフィールド**

- `.onEditingChanged`
  - テキストフィールドの編集が完了した時に実行される処理
  - 入力欄からカーソル？を離した時に発火(フォーカスアウト)

```swift
TextField("Enter text", text: $text)
    .onEditingChanged { isEditing in
        print("Editing started: \(isEditing)")
    }
```

**タップ**

- `.onTapGesture`
  - タップが検知された時に実行される処理

```swift
Text("Tap me")
    .onTapGesture {
        print("Text tapped!")
    }
```

- `.onLongPressGesture`
  - 長押しのジェスチャーが検出された時に実行される処理

```swift
Text("Long press me")
    .onLongPressGesture {
        print("Text long pressed!")
    }
```

**スクロール**

- `.onScroll`
  - スクロールが発生した時呼び出される処理
  - スクロールの方向などを検知することはできない

```swift
ScrollView {
    VStack {
        ForEach(0..<50) { index in
            Text("Item \(index)")
                .padding()
        }
    }
    .onScroll {
        print("Scrolling detected!")
    }
}
```

- `.gesture`
  - スクロールのイベントを検知することができる
  - `.onScroll`と違って方向を検知することができる
  - 例は右方向の例

```swift
Rectangle()
    .fill(Color.blue)
    .frame(width: 100, height: 100)
    .gesture(
        DragGesture()
            .onChanged { value in  
                // 右方向へのスクロールを検知
                if value.translation.width > 0 {
                    print("Dragging right!")
                }
            }
    )
```
社外・社内とのファイル連携と前後業務を簡単にしませんか？

## はじめに

本記事では "ゆる～く" HULFT Squareのご紹介をします。
HULFT Squareについてはこちらの[公式HP](https://www.hulft.com/service/hulft-square)、[公式マニュアル](https://www.hulft.com/help/ja-jp/HULFTSquare/homeindex.htm)へ。
以下内容はご参考となりますので、実際にご検証、マニュアルのご参照をお願い致します。

（今日はちょっと業務寄りで緩い内容がメインです。）
## きっかけ
とあるお客様（複数社様）とお話をしている中で
**「メールで受け取っている受発注データをBOX受け取りに変更する」**
とお聞きしました。
（受発注データ以外もありました。）

メールで受け取る受発注データ（Excelとか）を
**手作業**や**ファイルローダ**で登録していませんか？
特に小規模店舗様との受発注業務などでお聞きします。

↓こんな感じ
![業務の流れ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3763794/07f3f47d-7370-e971-bf65-354c12eea5f2.png)

## どう改善するのか？

この各プロセスをシステム化した場合の（あくまで）一例は以下かと思います。
（メールもシステムですが、より自動化するという視点で　笑）

<d1>
<dt>①お取引先様からメールでファイル授受</dt>
<dd>⇒メールからクラウドストレージに変更</dd>
<dt>②データの確認</dt>
<dd>⇒チェック用のプログラムの構築</dd>
<dt>③データ不備があればメールにて再送依頼</dt>
<dd>⇒②のプログラムと連携したシステムの構築</dd>
<dt>④システムへデータ登録</dt>
<dd>⇒②と連携したシステムの構築</dd>
</d1>

（webフォームとkintoneを組み合わせてお客様に入力して頂く等もお聞きします。）

こういった各プロセスのシステム化をした後にシステム間連携が
発生するかと思います。（DX定義の真ん中）

よく言われている以下の3ステップですね。
![DXの定義.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3763794/09a0a309-5b3a-8faf-c599-eda313c4389c.png)

（経済産業省さんの[DX支援ガイダンス](https://www.meti.go.jp/policy/it_policy/dx/dxshienguidance.pdf)にも記載があります。）

先ほどの各プロセスのシステム化を行った後の連携においては
データ連携ツールで貢献できる部分が多いかと思います。

**「システム化したは良いけど、結局手作業が残って」** とか
**「システムやプログラム同士の繋がりがなく、バラバラ」** とか

「AIの活用とか言われてるけど、業務自動化が先っすよ！」なんて・・・

## 何を使って改善するのか？
クラウド型連携プラットフォームの **HULFT Square** であれば
ざっくりこんな連携になるかと思います。

![HSQ連携.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3763794/2198cf1a-4b68-fcd4-bc47-2bfaaa0a59c7.png)

①HULFT Squareがクラウドストレージからファイル取得
⇒スケジュールで毎時、毎分ファイルを取得することも可能ですし、
　クラウドストレージからHULFT SquareにAPIで通知するという方法も可能です。
　（WebhookやAPIマネジメントという機能）

②取得したデータのチェック処理
⇒文字列であれば桁数やバイト数、数値であれば最小値や最大値を
　自動でチェックできます。
　もちろんマスタと突合させて「正しい商品コードなのか？」も確認できます。

③ファイルの再格納を依頼するメール通知やエラー発生時のメール通知
⇒SMTPに対応しているので、メールサーバへメール送信を
　リクエストすることが可能です。

④SaaSやデータベースへの連携
⇒[コネクターの種類](https://www.hulft.com/service/hulft-square/6features#anc_connector)はこんな感じですので、
　スケジュール、ファイルが作成されたタイミング、
　APIでリクエストを受け付けたタイミングをトリガーに、データ連携が可能です。

## まとめ
今回のポイントは以下ですかね
- 外部とのファイル授受の形式を<font color="MediumSeaGreen">**クラウドストレージ**</font>に変更
- ファイル受領後の<font color="MediumSeaGreen">**業務全体を自動化できるデータ連携ツール**</font>
　　　　　　　　<font color="MediumSeaGreen">（**特に既存システムへの連携部分）**</font>

以上！
UnityとC#で，1人で簡単なゲームを作りたい

こんにちは．

これから，全何本になるかはわかりませんが，タイトルにあるように，UnityとC#を用いて簡単なゲームを作っていく様子をお届けできればと思います．
自分自身，Unityのことを熟知しているとは全く言えないので，なるべく詳しく説明していければなと思います．

## 経緯
* アウトプットの機会が全く足りてない気がするため
* 2人とか5人くらいのチームで何かを作ったことはあるものの，個人での制作経験はあまりないため，やってみようと思ったため
* 就活してないため(????)

## どういうゲームを作ろうか
**ちょっとアクション要素のあるミニゲーム**にしたい．

いきなり複雑なゲームを作ろうとしても，時間的に厳しいだろうし，途中であきらめてしまったらもったいない．
過去にUnityを使ってゲームを作ったことはありますが，チーム内に精通している人がいたため，細かい部分はほとんどその人に頼ってしまっていました．
そのため，Unityのことを調べながら．．．という感じになるため，ミニゲーム位がいいかなと考えました．もちろん，ミニゲームを舐めているではない．

というようにいろいろ考えた(5分くらい)結果，「**画面上部から凸凹のある壁が迫ってきて，潰されないように隙間に移動するゲーム(制限時間1分)**」を作ることにしました．
(ガラケーのゲームに似たようなゲームがあった気がして，いろいろ調べてみたのですが見つけられませんでした．「危険地帯」っていう言葉がタイトルに入っていた気がする．)

![イメージ図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3922668/61f55c66-a0da-73ad-849f-c6bcf9cb1c1a.jpeg)
こういう感じのゲームを作りたい．

## まとめ(?)
ということで，次回からは実際に制作していきたいと思います．
地面とプレイヤーだけは作ってるのですが，まあそんなん微々たるものなので・・
あと文章力も記事を書いているうちに養われていったら嬉しいな．

↓ GitHubのリポジトリをなんとなく貼っておきます．ゲーム名(仮)は「GapDush」となっております．
[GapDush - GitHub](https://github.com/tdtiger/GapDash.git)

↓次の記事

https://qiita.com/tdtiger/items/73b18b575e306bcd3819
autoscalingと起動テンプレート用CSVファイル

```
# Auto Scalingグループの情報を取得し、CSVファイルに直接書き込む
aws autoscaling describe-auto-scaling-groups \
    --query "AutoScalingGroups[*].{AutoScalingGroupName:AutoScalingGroupName, LaunchTemplateId:LaunchTemplate.LaunchTemplateId, Version:LaunchTemplate.Version}" \
    --output json | \
jq -r '.[] | [.AutoScalingGroupName, .LaunchTemplateId, .Version] | @csv' > autoscaling_groups.csv

```
```
aws ec2 describe-launch-template-versions \
    --launch-template-id <LaunchTemplateId> \
    --versions <Version> \
    --query "LaunchTemplateVersions[*].[LaunchTemplateId, Version, LaunchTemplateData.ImageId]" \
    --output text | \
awk '{print $1","$2","$3}' > launch_template_ami_info.csv

```
[TS/JS]ESMとCJS

ESMだのCJSだので詰まることが多すぎるので、いい加減情報をまとめる。

## 概要
ざっくりいうと、「`modules`をどのように扱うか？」に係る2種の系統。
* `import`, `export`するほうがESM
* `require`, `modules.export`するほうがCJS

### ESM; ES Modules
`import`の方。

ECMA Script2015（ES6）で策定されたモジュール仕様。
V8などは当然こちらに準拠している。

https://ja.wikipedia.org/wiki/ECMAScript

### CJS; CommonJS
`require`のほう

立ち上げは2009なので、ESMより古参。
ServerSideJavascriptというコンセプトを出発点とするため、Node.jsではデフォルトである一方、ブラウザでは非対応となっている。

https://ja.wikipedia.org/wiki/CommonJS

## 趨勢
**メインストリームはESMである**。
ことフロントエンド開発においてはそもそもブラウザがCJSに非対応であるため、必然的にESM環境になる。
しかし、Node.js環境上においても、`npm`の開発者であるIsaac氏自ら「CJSは時代遅れになりつつある」とコメントしている模様。

https://github.com/nodejs/node-v0.x-archive/issues/5132#issuecomment-15432598

こうした状況を反映してか、最近のサードパーティモジュールの中にはCJSに対応していない（ESMのみ提供）ものが増えつつある。
……とされていたが、Node.js v22からそうでも無くなった模様。
CJSからESMを`require`で呼び出せるようになった。

https://nodejs.org/en/blog/announcements/v22-release-announce

ただし、[Pure ESM package](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c#pure-esm-package)という観点からは、**`import`の使用を強く推奨されている**。

## Node.js + ESM + TypeScript
### プロジェクト単位の手続き
一方、先述の通り、Node.jsにおいてはCJSをデフォルトとしている都合、Node.js環境を想定したプロジェクトをESM環境として扱うためにはボイラープレートな手続きが必要。

再掲・引用。

> - Add `"type": "module"` to your package.json.
> - Replace `"main": "index.js"` with `"exports": "./index.js"` in your package.json.
> - Update the `"engines"` field in package.json to Node.js 18: `"node": ">=18"`.
> - Remove `'use strict';` from all JavaScript files.
> - Replace all `require()`/`module.export` with `import`/`export`.
> - Use only full relative file paths for imports: `import x from '.';` → `import x from './index.js';`.
> - If you have a TypeScript type definition (for example, `index.d.ts`), update it to use ESM imports/exports.
> - Use the [`node:` protocol](https://nodejs.org/api/esm.html#esm_node_imports) for Node.js built-in imports.

### 拡張子の明示と、TypeScriptでの都合
大きな違いとして、ESMで`import`を行う際は**拡張子を明示する**のが原則。

``` js
import modules from "./modules.js"
```

ここまではまだ良いとして、TypeScriptでESM環境を想定する場合に留意点がある。
それは、**`.ts`ファイルを`import`する場合でも、拡張子を`.js`にする必要がある**ということ。
つまり、上記で`import`するファイルが`modules.ts`であろうとも、上のように`.js`拡張子で書かないといけない。

これは、`tsc`のコンパイル方針に起因する。
**`tsc`は`import`内の文字列の書き換えや読み替えを行わない**という方針がTypeScript開発チームから示されている。

https://github.com/microsoft/TypeScript/issues/35589

そのため、`import`内にはトランスパイル後の`.js`拡張子を記載する必要がある。
一応、このあたりは`tsc`などがIDE上でサポートしてくれるのでエラーになったりすることはない。気持ちは悪い。

一応、`tsconfig`の設定次第で`.ts`を扱えるとされているようだが……なんだか情報が錯綜している。

## 参考・外部リンク
* [ES modules基礎知識 | 第1回 仕様の概要とその周辺課題](https://www.codegrid.net/articles/2017-es-modules-1/)
* [JavaScript の Module System の歴史 - tasuwo's notes](https://scrapbox.io/tasuwo/JavaScript_%E3%81%AE_Module_System_%E3%81%AE%E6%AD%B4%E5%8F%B2)
* [CommonJSとES Modulesについてまとめる](https://zenn.dev/yodaka/articles/596f441acf1cf3#es-modules%E3%81%AB%E5%85%A8%E6%8C%AF%E3%82%8A%E3%81%99%E3%82%8B%E4%B8%8A%E3%81%A7%E3%81%AE%E5%95%8F%E9%A1%8C%E7%82%B9)
* [そういえばcjsとかmjsてなに？](https://zenn.dev/ikenohi/scraps/22785193fb63a6)
* [Native ESM + TypeScript 拡張子問題: 歯にものが挟まったようなスッキリしない書き流し](https://zenn.dev/qnighy/articles/19603f11d5f264)
* [TypeScriptでのNode.js（ECMAScript modules (ESM)）開発環境を構築してみた ｜SHIFT Group 技術ブログ](https://note.shiftinc.jp/n/nfcf300645c9a)