OmniAICreator/Qiita-1.07M huggingface dataset:
git-completionとgit-prompt導入用スニペット（Bash向け）

有名な次のGit便利ツールの導入方法。

- Git系コマンドなどをタブキーで補完してくれる `git-completion`
- Gitのリポジトリのステータスをプロンプトに表してくれる `git-prompt`
- ソースコード： https://github.com/git/git/tree/master/contrib/completion

Qiitaにも解説記事がすでに何個もありますが、本稿はほぼ一発コピペで導入するためのコードスニペットという位置付けです。

## How To セットアップ

### ダウンロード

git-completion と git-prompt のシェルスクリプトをホームディレクトリにダウンロードしてくる。

なお git-completion については、zsh用やtcsh用のもあるので、適宜URLを変更することでこれらシェル用のものに変更できる。[リポジトリ内のファイル](https://github.com/git/git/tree/master/contrib/completion)を確認のこと。

```bash:ホームディレクトリ下で実行するコマンド
cd
curl -o .git-completion.sh \
    https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash
curl -o .git-prompt.sh \
    https://raw.githubusercontent.com/git/git/master/contrib/completion/git-prompt.sh
```

### .bashrc の編集

.bashrc に次の内容を（後ろのほうに）追記する。 

```bash:.bashrc
if [ -f ~/.git-completion.sh ]; then
    source ~/.git-completion.sh
fi
if [ -f ~/.git-prompt.sh ]; then
    source ~/.git-prompt.sh
fi
GIT_PS1_SHOWDIRTYSTATE=true
GIT_PS1_SHOWUNTRACKEDFILES=true
GIT_PS1_SHOWSTASHSTATE=true
GIT_PS1_SHOWUPSTREAM=auto

PS1='[\[\033[32m\]\u@\h\[\033[00m\] \[\033[33m\]\w\[\033[1;36m\]$(__git_ps1 " (%s)")\[\033[00m\]]\n\$ '
```

なお、`PS1` の冒頭 `\[\033[32m\]` のところでプロンプトの”アカウント名@ホスト名”部分の色を決めている。`32`の部分を下表の色値にすると色を変えられる。[^bash_color]

[^bash_color]:ここでは詳細は省くが ”Bash プロンプト 色変更” あたりで検索して欲しい。頑張れば２５６色カラー対応などもできる。


|カラーコード|色値|
|:-:|:-:|
|`#000000`|30|
|`#ff0000`|31|
|`#00ff00`|32|
|`#ffff00`|33|
|`#0000ff`|34|
|`#ff00ff`|35|
|`#00ffff`|36|
|`#ffffff`|37|
PowerShellの起動時間をPSProfilerモジュールで確認してみる

[PowerShell Gallery - PSProfiler](https://www.powershellgallery.com/packages/PSProfiler/)

PowerShellでは開始時に読み込むProfileに設定を記述することで、環境をカスタマイズすることができます。

ただしProfileに色々と処理を追加した結果、起動処理に時間がかかるようになることが多々あるかと思います。

そのような場合、Profileのどの部分で時間がかかっているか調べることになりますが。

PowerShell Galleryで公開されているPSProfilerモジュールを利用すれば、どの部分で時間がかかっているか簡単に調べることができます。

## モジュールのインストール

下記コマンドでPsProfilerモジュールをインストールできます。
インストールするスコープはお好みで。

今回は2022年6月30日時点でpreview版となっている`1.0.5-preview1`をインストールしたかったため、`-AllowPrerelease -Force`のオプションをつけています。

```PowerShell
# スコープはCurrentUserでインストール
Install-Module -Name psprofiler -Scope CurrentUser -AllowPrerelease -Force
```

## 今回の環境

- PowerShell 7.3.0-preview.5
- PSProfiler 1.0.5-preview1

## 起動時間を計測してみる

PsProfilerではスクリプトの実行時間を計測してくれる、`Measure-Script`コマンドレットが提供され、このコマンドレットを利用します。

起動時間を調査する方法としては。

PowerShellで開始時にProfileを読み込まないオプション -NoProfile で起動して、Measure-Scriptで$profileを実行して計測します。

上記の流れをコマンドで実行すると下記のようになります。

```PowerShell
# topオプションが使えるのは、1.0.5-preview1から
pwsh.exe -NoProfile -Command {Measure-Script -path $profile -Top 5}
```

コマンドを実行すると下記のように、各ステートメントでの実行時間が表示されるようになります。

今回オプションで`-top 5`としているため、実行時間の上位5つについては赤く表示されている事がわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/dd20e5c2-dde9-ad34-709c-a919b2673738.png)

このようにして、処理に時間がかかっているステートメントを簡単に洗い出す事ができます。

## 参考サイト

[Optimizing your $Profile](https://devblogs.microsoft.com/powershell/optimizing-your-profile/)

## 総評

起動プロファイルは色々とやりたい事を盛り込み始めると、起動に時間がかかるようになってしまう事がありますが、PSProfilerを使うことで簡易に調査が行なえます。

また今回は起動プロファイルでしたが、普通にスクリプトの実行時間を調査するにも有用となります。
docker-entrypoint.shについて

# はじめに
この記事はdocker-entrypoint.shについて学習したこと、気づいたことをまとめていってる記事です。
余裕があれば随時更新していこうと思っています。
**※ 課題解決系の記事ではないです。**


# docker-entrypoint.shとは
docker-entrypoint.shは**初回起動時のみに処理したい内容を記述するヘルパースクリプト**です。 
railsであればseedでデータを流し込みたいみたいなときです。
[Dockerfile](https://qiita.com/michikun06/items/a846b03d73dfe8871131)のENTRYPOINTで読み込ませることができます。
[公式](https://docs.docker.jp/engine/articles/dockerfile_best-practice.html)では下記のように言われています。
> ベストな使い方は、イメージにおけるメインコマンドの設定です。これによりイメージを指定したコマンドを通して実行します（そして、 CMD がデフォルトのフラグとして使われます）。





# docker-entrypoint.shの例
[Dockerfile のベストプラクティス](https://docs.docker.jp/engine/articles/dockerfile_best-practice.html#entrypoint)は公式のもので何をentrypointに書くべきか的なことが書いてあります。
```docker:entrypoint.sh
#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
```
docker-compose.ymlについて

# はじめに
この記事はdocker-compose.ymlについて学習したこと、気づいたことをまとめていってる記事です。
余裕があれば随時更新していこうと思っています。
**※ 課題解決系の記事ではないです。**


# docker-compose.ymlとは
いわゆるサービス（コンテナ）を定義するYAMLファイルのことをComposeファイルと言います。
Docker Desktopに含まれているDocker Composeに解釈され、Docker Composeが、複数のコンテナーの Docker アプリケーションを実行する仕組みになっています。



# docker-composeの内容
一部です。

```docker:docker-compose.yml
version: "3.9"

volumes:
  mysql:

services:
  db:
    image: mysql:8.0
    ports:
      - "3306:3306"
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: example
  web:
    build: .
    ports:
      - "8080:8080"
    environment:
      RAILS_ENV: development
```
[Rails]path指定してJSONを取得する方法


railsで開発をしていたときに
ローカルでは正しくJSONファイルを読み込めているが、本番環境でRoutingエラーになる事案が発生しました。

# やりたかったこと
ページの最初の挙動としてロゴをアニメーションで表示することでした。
```
var title_animation = {
  wrapper: title_dom,
  animType: 'svg',
  prerender: true,
  loop: true,
  autoplay: true,
  path: '/logo_animation'
};
```
jsファイル内でイベントの設定を記述。
ロゴアニメーションをJSONファイルに変換したものをpathで読み込んでいました。

# エラー内容
開発環境では正しく動いていたものの、GCP cloud runにデプロイした途端に問題発生。
devツールで確認したところ、JSONの取得が404エラーになっており、実際にURLを入力したところRoutingエラーでした。

![スクリーンショット 2022-06-30 11.00.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880195/9f0c5af1-0192-eefc-5e56-a9cff5e4b3ec.png)

調査していたところGCPは対象かどうか分かりませんでしたが、サーバーによってはJSONを使用する設定が必要みたいです。。。。


# 対策
今回とった対策はpath指定してJSONデータが返ってくるgetリクエストの設定です。
設計的に正しいかは保証できかねます。


```ruby:routes.rb
get    'get_json'  => 'static_pages#getjson'  # リクエスト名は仮です。
```
```ruby:static_pages.rb
def getjson
  getjson = {ここにjsonを書く}
  render json: getjson
end
```
できた👀
オリジナルアプリ　Kiyora

卒業制作で作成したアプリを紹介します。初のオリジナルアプリです。
### 開発の理由
１. スクールで学んでいく間に前職で使用していたシステムがどのように動いているのか
知りたくなった。
2. 就職する前に業務アプリとはどのようなものであるのか把握してみたかった。


ログイン画面![スクリーンショット 2022-06-29 11.22.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530703/41be28c9-4a22-7547-3bdd-5fb4d71596ec.png)

E-R図
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530703/03ff4de7-ea9d-a16c-91b6-c92c6749425f.png" width=50%>


アプリの説明
建築設備の業界で使用する業務アプリケーションとなります。

使用環境について
・Ruby on Rails 6.0.3
・PostgreSQL 14.2
・ruby 3.0.1

・API
 Google maps API
 OPEN_WEATHER_MAP_API

.Amason S3にサンプルデモの動画を上げています。

使い方の説明
実際の業務に沿った流れとなります。
１　スケジュール画面でスケジュールを確認
![スケジュール情報.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530703/7fb27c5b-a521-beab-d690-e44a9ab47704.gif)

２　カレンダーは月間と週間の２つのカレンダーを表示させることができます。

3 必要に応じて物件情報、管理会社情報を更新します。
![スクリーンショット 2022-06-29 22.05.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530703/55c74824-c51a-8764-9f74-e1e182654fe4.png)

![スクリーンショット 2022-06-29 22.09.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530703/78f7e0f7-e3d0-0448-fcb9-5532f900baf2.png)

４　伝票作成画面にて伝票を作成。
　　従来作成するのに３０分程度かかっていた時間を15分程度に削減。
　　１日２０伝票の処理があると想定すると一日に５時間。
　　１週間で25時間の時間が削減できます。

５　伝票作成画面
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530703/6421febf-4bff-d8b6-76bb-055cb7fbf013.png" width=80%>


伝票フォロー機能　気になる伝票を社員同士でフォローすることができます
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530703/1be07a1a-222a-ba15-0fd7-29d5b6539fe1.png" width=７0%>

７　作業に行く前に顧客情報画面でお客様の住所や天気予報を確認することができます。建築設備業は天候によって作業が左右されます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530703/0d3552f4-cdc9-e139-2e60-3f42b347b514.png" width=７0%>

８　作業が終わったら、売上情報画面にて伝票の金額を確認
月間での売上や範囲を指定しての売上検索が可能です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530703/06ffc39f-2091-7867-d310-565dbed6086c.png" width=７0%>

９請求書発行画面
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530703/07120a8c-5f03-ee9f-aacb-8fa74ab095ad.png" width=50%>

### 今後改善したいこと
---------
1. Google　Twitterログイン機能の追加

2. AWS Dockerとの連携

3. GASとの連携で伝票を共有できるようにしてみたい。
-------

謝辞
-------
最後までお読み下さってどうもありがとうございました。
ご指摘や改善点などありましたらご連絡を頂ければと思います。
スタートラインにようやく立てた状態かと思います。温かい目で見て頂ければと思います。
次回は技術的な面で記事を書きます。
【jQuery】特定要素に対して一度だけイベントを実行するメソッド

「クリックしたときに一回だけメソッドを実行したい」のようにイベントに対して関数を一度だけ呼び出すメソッドについて紹介します。

# one()メソッド概要
[one()メソッド](http://semooh.jp/jquery/api/events/one/type%2C+%5Bdata%5D%2C+fn/)は要素に対して指定できて、コールバック関数を一度だけ呼び出します。
類似のメソッドに```.on('click', ```がありますがこちらと違うのは一度しか実行されない点です。

ボタンなどに対して適用することでdisableな状態にすることができます。
```
var n = 0;
$("div").one("click", function(){
  n += 1
});
```

# one メソッドの引数
```one(type, [data], fn)```

- type
click、mousedownのようなイベントを指定

- [data]

イベントにしたいデータの指定

- fn
イベント着火時に処理したい内容を指定
Laravelで外部キー制約したいんですけどっ！？？

# イントロ

Laravelでテーブルのカラムに外部キー制約を実装する方法を紹介するZE☆

> 俺「外部キー制約ってなんやねん」

って方はこちらで詳しく解説しています！

https://qiita.com/Sunasuna24/items/6d4d15fd22b14ee1e580

こちらの記事はLaravelドキュメントのマイグレーションにある[外部キー制約](https://readouble.com/laravel/8.x/ja/migrations.html#column-method-foreignId)の段落を分かりやすく噛み砕いたものになります。

:::note
今回解説するLaravelのバージョンは8.xです！
:::

# migrationを操作する方法が2つあるよ！

Laravelでカラムに外部キー制約を実装するには、migrationを操作する必要があります！

migrationでの設定方法は大きく分けて2つ方法があります！

今回はドキキュメントに沿ってusersテーブルとpostsテーブルを例に紹介します。

# 今まで通りの方法

まずは今までのマニュアル通りの方法を紹介します。

実際のコードを見てみましょう。

```PHP:databases/migration/create_〇〇_table.php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

Schema::table('posts', function (Blueprint $table) {
    $table->unsignedBigInteger('user_id');                      // 1
    $table->foreign('user_id')->references('id')->on('users');  // 2
});
```

## まずは1行目で普通にカラムを作る

まずは普段migrationを操作しているように、`user_id`を作成します。

このとき注意したいのは、`user_id`のデータ型はなんでもOKなわけではなくて、usersテーブルの`id`カラムと同じでなければなりません。

デフォルトのusersテーブルでは`id`カラムを作成するときに`$table->id()`を用いて作成されます。

`$table->id()`を用いて作成されるカラムのデータ型はunsignedBigInteger型なので、今回migrationに作成する`user_id`のデータ型もunsignedBigInteger型で設定しましょう！

## 2行目で外部キー制約をかける

そしたら、新しい行で`$table->foreign('user_id')->references('id')->on('users');`のようにして外部キー制約を実装します。

1. `foreign('xxx')`で外部キー制約したいカラムを指定
1. `references('yyy')`で参照したい外部のカラム名を指定
1. `on('zzz')`でその参照したいカラムがあるテーブル名を指定

これらより、usersテーブルにある`id`カラムをpostsテーブルの`user_id`に参照させたい時は、

`$table->foreign('user_id')->references('id')->on('users');`

と書くことで`user_id`を外部キー制約することができます！

# 2つ目の方法(省略形)

2つ目の方法は今紹介した方法よりも短く書くことができます。

具体的には`foreignId`メソッドを使うことで書き直すことができます。

```PHP
Schema::table('posts', function (Blueprint $table) {
    $table->foreignId('user_id')->constrained();
});
```

外部キー制約したいカラム名を`foreignId`メソッドの引数に与えます。

`constrained`メソッドは`foreignId`メソッドに与えられた引数からいい感じに「どのテーブルのどのカラム」を参照したいのかを判断してくれます。

`user_id`を`foreignid`メソッドに与えると、`contrained`メソッドは

「`user_id`だから、usersテーブルの`id`カラムを参照したいんだな」

と判断してくれます。

:::note warn
なので外部キー制約を指定するときは命名法に注意しましょう！
:::
Reactの環境構築をしてみる

# Reactの導入方法(mac)
## 1.Node.jsのインストール
Reactを使うにはNode.jsをインストールするのが便利
Node.jsはJavaScriptエンジン上に構築されたJavaScript実行環境の1つ
公式HPからダウンロードする
https://nodejs.org/ja/
![スクリーンショット 2022-06-30 12.40.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727856/ece6a16a-e1a4-b1fc-43e3-7ab9992b21db.png)

## 2.Creat React Appのインストール
以下のコマンドをターミナルで打ち込む

```
$ npx create-react-app my-app
$ cd my-app
$ npm start
```
このようなページが表示されれば成功
![スクリーンショット 2022-06-30 12.45.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727856/2db2fe35-31f2-bb19-6d0f-d59538561669.png)

my-appをエディタで開き、my-app/src/App.jsを編集する
Intentの初期化で渡すContextについて

`ApplicationContext`と`ActivityContext`について調べていると、「`Intent`に`ActivityContext`を渡すと、メモリリークするからよくない」という割と古めの記事を見かけたので、`Intent`に渡す`Context`が何をしているのか実際に調べてみました。

```kotlin
val intent = Intent(context, SecondActivity::class.java)
startActivity(intent)
```

### Intentの実装
[Android Open Source Project](https://github.com/orgs/aosp-mirror/repositories) で、`Intent`のコードを確認しました。

```platform_frameworks_base/core/java/android/content/Intent.java
public Intent(Context packageContext, Class<?> cls) {
    mComponent = new ComponentName(packageContext, cls);
}
```

```platform_frameworks_base/core/java/android/content/ComponentName.java
public ComponentName(@NonNull Context pkg, @NonNull Class<?> cls) {
    mPackage = pkg.getPackageName();
    mClass = cls.getName();
}
```

コードを確認するとわかるように、`Context`はパッケージ名（`String`）を取得する処理に使われています。

`Intent`で受け取った`Context`を`static`な変数に保持したりしているわけではないので、`Intent`に渡すのは、`ApplicationContext`・`ActivityContext`のどちらでも問題なさそうです（`ActivityContext`を渡すのが普通かな？）
Cypressv10でのnext.js  ComponentTest

## Cypress v10版Component Test設定

Cypressがv10になっていろいろ変わりComponent Testも変わった

migration-guideを見ましょう
https://docs.cypress.io/guides/references/migration-guide#Configuration-File-Changes

sampleはここ
https://github.com/cypress-io/cypress/tree/develop/npm/react/cypress/component

### 変わったこと
#### Plugins File Removed
cypress.config.ts になりe2eとcomponentで別れて設定します
```ts
import { defineConfig } from 'cypress';

const componentConfig: Cypress.ResolvedConfigOptions['component'] = {
  devServer: {
    framework: 'next',
    bundler: 'webpack',
  }
};

export default defineConfig({
  e2e: {},
  component: componentConfig,
});

```

#### supportファイル設定

https://docs.cypress.io/guides/references/migration-guide#supportFile

デフォルトの置き場
```js
{
  component: {
    supportFile: 'cypress/support/component.js'
  },
  e2e: {
    supportFile: 'cypress/support/e2e.js'
  }
}
```

#### supportファイルにmountコマンドを追加する

```typescript:cypress/support/component.ts
import { mount } from 'cypress/react'

Cypress.Commands.add('mount', mount)
```

### intergration
*.cy.tsx / *.cy.jsx という名前にして置けばOK

## i18nの設定方法

v9まではここ
https://github.com/cypress-io/cypress/tree/v9.7.0/npm/react/cypress/component/advanced/i18n

v10がないのでやってみました
参考にしたのはここ
https://docs.cypress.io/guides/component-testing/custom-mount-react

### mountコマンドをaddするときにwrapしてやればいいみたい

optionsを拡張するとmount時に外からパラメータが渡せる

```react:cypress/support/component.tsx
import { mount, MountOptions, MountReturn } from 'cypress/react';
import '@testing-library/cypress/add-commands';
import './commands';
import { WrapComponent } from './WrapComponent';

type InitializeState = (t: any) => void;

declare global {
  namespace Cypress {
    interface Chainable {
      /**
       * Mounts a React node
       * @param component React Node to mount
       * @param options Additional options to pass into mount
       */
      mount(
        component: React.ReactNode,
        options?: MountOptions & { initializeState?: InitializeState },
      ): Cypress.Chainable<MountReturn>;
    }
  }
}
Cypress.Commands.add('mount', (component, options = {}) => {
  const { initializeState } = options;
  const wrapped = <WrapComponent initializeState={initializeState}>{component}</WrapComponent>;
  return mount(wrapped, options);
});
```

i18nと一緒にRecoilも入れてPropsでinitializeできるようにした

```react:WrapComponent.tsx
import i18 from 'i18next';
import { ReactNode } from 'react';
import { I18nextProvider } from 'react-i18next';
import { RecoilRoot } from 'recoil';

interface Props {
  children: ReactNode;
  initializeState?: (t: any) => void;
}
export const WrapComponent: React.FC<Props> = ({ children, initializeState = () => null }: Props) => {
  return (
    <I18nextProvider i18n={i18n}>
      <RecoilRoot initializeState={initializeState}>{children}</RecoilRoot>
    </I18nextProvider>
  );
};
```
Dockerfileとは（随時更新予定）

# はじめに
この記事はDockerfileについて学習したこと、気づいたことをまとめていってる記事です。
余裕があれば随時更新していこうと思っています。
**※ 課題解決系の記事ではないです。**


参考コード　 :　  [Quickstart:Compose and Rails](https://docs.docker.com/samples/rails/) (dockery公式document)


# Dockerfileファイルとは
「イメージを構築するためのテキストファイル」です。
必要となるコマンドを全て盛り込んでいます。
dockerファイルからイメージを作成するので以下のようなメリットがある。
- 環境構築の手順を自動化
- 開発者が皆、同じ環境下で開発できる
- 環境をファイルで管理可能

# Dockerfileファイルの内容
こちらのコードを参考にしています。
[Quickstart:Compose and Rails](https://docs.docker.com/samples/rails/) (dockery公式document)

```docker:Dockerfile
# syntax=docker/dockerfile:1
FROM ruby:2.5
# 使用するイメージの定義、ruby:2.5を使用する。

RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
# 実行するコマンドを指定します。
# apt-get update -qq : ライブラリをアップデートします。-qq はquietモードで実行。エラー以外を表示しないオプションです。
# apt-get install -y nodejs postgresql-client ... 全て承諾（-yオプション）で必要なライブラリを入れます

WORKDIR /myapp
# 作業ディレクトリの指定
# RUN,COPYなどのあらゆる起点となります。

COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
# Gemfile、Gemfile.lockをDockerコンテナ内にコピーして、bundle installします。

# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
# entrypoint.shをコンテナ内の/usr/bin/にコピーします。

RUN chmod +x /usr/bin/entrypoint.sh
# entrypoint.shの実行権限を付与します。

ENTRYPOINT ["entrypoint.sh"]
# 最初に実行するコマンドを指定。entrypoint.shを実行する。

EXPOSE 3000
# コンテナがリッスン（待機）するポート番号を指定します。

# Configure the main process to run when running the image
CMD ["rails", "server", "-b", "0.0.0.0"]
# ソフトウェアを実行するコマンドです。
# ["実行ファイル","パラメータ1","パラメータ2", ...]の形式で書かれています。
```
User Timing APIを使って処理にかかった時間をブラウザ開発者ツールで表示する方法のメモ

`User Timing API` を使うと任意の区間の時間を計測することができます。

Vue.jsの`app.config.performance`をtrueにした場合にもこの方法が使われており
[profiling.ts](https://github.com/vuejs/core/blob/v3.2.37/packages/runtime-core/src/profiling.ts) というところで使われています。

## 使い方
以下のようなコードで計測します。

``` js
async function action() {
  await doShortProcess();

  await doLongProcess();
}
```

短い処理`doShortProcess`と長い処理`doLongProcess` があります。
これらのそれぞれにかかった時間を計測します。

``` js
async function action() {
  window.performance.mark("短い処理:start");

  await doShortProcess();

  window.performance.mark("短い処理:end");
  window.performance.measure("短い処理", "短い処理:start", "短い処理:end");
  
  window.performance.clearMarks("短い処理:start")
  window.performance.clearMarks("短い処理:end")

  //-----------------------------------
  window.performance.mark("長い処理:start");

  await doLongProcess();

  window.performance.mark("長い処理:end");
  window.performance.measure("長い処理", "長い処理:start", "長い処理:end");
  
  window.performance.clearMarks("長い処理:start")
  window.performance.clearMarks("長い処理:end")
}
```

実行前、実行後 それぞれに[mark](https://developer.mozilla.org/ja/docs/Web/API/Performance/mark) メソッドを使い目印を作成します。

次に[measure](https://developer.mozilla.org/ja/docs/Web/API/Performance/measure) を使い2点間の時間を計測します。第1引数はメジャーのエントリー名、第2、第3引数は2点間のマークの名前です。

最後に[clearMaks](https://developer.mozilla.org/ja/docs/Web/API/Performance/clearMarks) で2点のマークを削除します。

[clearMeasures](https://developer.mozilla.org/ja/docs/Web/API/Performance/clearMeasures)というものもありますがVue.jsでは使われていなかったのでここでは実行していません。

### 計測結果

`Chrome` の `DevTools` の`Performance` の機能を使って計測した結果です。
![quiita01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628749/11aedeba-79eb-763e-1d1d-ce7a99b80a6b.png)


`Timing` のところに今回作成したエントリが描画されていることが確認できます。

### 使いやすくしてみる
このままだとコードが冗長なので まとめてみます。

計測の関数
``` js
function markStart(tag) {
  const startTag = `${tag}:start`
  window.performance.mark(startTag)
}

function markEnd(tag) {
  const endTag = `${tag}:end`
  window.performance.mark(endTag)
  
  const startTag = `${tag}:start`
  window.performance.measure(tag, startTag, endTag);
  window.performance.clearMarks(startTag)
  window.performance.clearMarks(endTag)
}
```

使う側
``` js
async function action() {
  markStart("短い処理");
  await doShortProcess();
  markEnd("短い処理");

  markStart("長い処理");
  await doLongProcess();
  markEnd("長い処理");
}
```

こうしておくと他でも使いやすくなるかと思います。

## 他に
今回は ブラウザの開発者ツールでの表示を紹介しましたが、他にも

- [getEntries](https://developer.mozilla.org/ja/docs/Web/API/Performance/getEntries)
- [getEntriesByName](https://developer.mozilla.org/ja/docs/Web/API/Performance/getEntriesByName)
- [getEntriesByType](https://developer.mozilla.org/ja/docs/Web/API/Performance/getEntriesByType)

といった計測結果の取得用メソッドも用意されており、自作のツールなどを作る際には必要になるかと思います。

## 最後に
今回はUser Timing APIと開発者ツールを組み合わせた計測方法を紹介しました。

知らないと自前で計測の仕組みを作ったりすることもあるかもしれないですが
これを知っていると視覚的にも見やすい計測結果が得られて便利だと思います。


## 参考
- [User Timing Level 3](https://w3c.github.io/user-timing/)
- [User Timing API](https://developer.mozilla.org/en-US/docs/Web/API/User_Timing_API)
Railsアプリで使っているライブラリのバージョンを一覧表示する

受託開発などで仕事を請けたりしていると、提出するドキュメント（設計書など）に、使用しているソフトウェアのバージョンの記載を求められることがあります。

僕が以前請けた仕事でも、Railsアプリケーションで使用しているライブラリ一覧を記載する必要がありました。

毎回やり方を調べているので、コマンドをメモしておきます。

## bundle installでインストールしたgem
### コマンド

```
bundle exec gem list
```

### 出力例

```
actioncable (5.2.3)
actionmailer (5.2.3)
actionpack (5.2.3)
actionview (5.2.3)
activejob (5.2.3)
activemodel (5.2.3)
activemodel-serializers-xml (1.0.2)
activerecord (5.2.3)
...
```

## yarnでインストールしたパッケージ
### コマンド

```
yarn list --depth=0
```

※依存関係の深さは0にしていますが目的に合わせて変更します。

### 出力例

```
yarn list v1.21.1
├─ @babel/code-frame@7.5.5
├─ @babel/core@7.6.4
├─ @babel/generator@7.6.4
├─ @babel/helper-annotate-as-pure@7.0.0
├─ @babel/helper-builder-binary-assignment-operator-visitor@7.1.0
├─ @babel/helper-call-delegate@7.4.4
├─ @babel/helper-create-class-features-plugin@7.6.0
├─ @babel/helper-define-map@7.5.5
...
```

----

あとは出力されたリストを適宜加工してドキュメントに貼り付ければ完了です。
Google タグマネージャーにユーザー IDを送信する際のハマりごと

ログインするウェブサイトで、GA4にユーザーIDを送信する設定を行なった。

公式ガイドでは、タグマネージャー設定が下記の流れで紹介されている。
1. タグマネージャーでGA4設定タグを追加
2. ユーザー定義変数`user_id`を設定。dataLayer.push関数でウェブサイトから送信。
3. Googleアナリティクス4設定タグで、`user_id`を送信。

https://developers.google.com/analytics/devguides/collection/ga4/user-id?platform=websites#tag-manager

ところが、ga4でuser_idが受け取れない。
タグマネージャーのデバッグを確認したところ、GA4の発火時にはdataLayerが空で、その次のステップでdataLayerが送信されていた。

dataLayer.push関数ではなく、dataLayerの配列をタグマネージャーの読み込み前に作成すると、GA4の発火時にdataLayerが取得できて解決。
```
dataLayer = [{
'user_id': 'USER_ID'
}];
```
【PHP】【Laravel】モデルの書き方とコントローラからの呼び出し方

モデルの使い方がいまいちピンと来なかったので、改めて学習して備忘録として残しておきます。

# モデルとは何か

- DBのデータを操作する機能のこと。
- テーブルに対応するモデルがあり、コントローラでモデルを操作すると、DBにデータを書き込んだり、DBからデータを削除したりできる。

# 具体的には

こちらの記事が参考になりました！！
[【Laravel】モデル（Model）とは何か？命名規則やマイグレーションとの関連性｜Eloquentやクエリビルダとは何か？](https://prograshi.com/framework/laravel/model-eloquent-and-query-builder/)

# Eloquent

- LaravelでDBを操作する際に使う。
- 下図のように、DB操作のためのメソッドが沢山用意されている。
![スクリーンショット 2022-06-30 11.49.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/985164/d89b6fdc-58ab-42de-e18b-fa6d2824f3be.png)

# モデルにはどんな内容を書けば良いのか

- fillableとguarded(データ登録時、登録できるデータや登録させたくないデータを設定する機能)の設定
- 任意のメソッド
- Eloquentで発行するSQL
   - SQLはコントローラに書いても良いが、コントローラのソースコードが長くなると読みにくくなるため、モデルに書くのがおすすめ。
   - モデルに書いた場合はコントローラから呼び出す必要あり。

# モデル書き方の例

### ユーザ情報を取得するSQL

```php:User.php
class User extends Model
    {
        $user = User::find(1); // id番号１のユーザ情報を取得
        $user->email; // users.email の値を取得
    }
```

### Fruitモデルにcolorが赤色の物のみ抽出するSQLを書いた例

```php:Fruit.php
class Fruit extends Model
{
    use HasFactory;

    protected $hidden = ['price', 'created_at', 'updated_at'];
    protected $guarded = ['created_at', 'updated_at'];

　　　　　　　　// 自作メソッド
    // $this::whereColorで、Colorカラムに’red’が指定されているものだけ取ってきて、呼び出し元に返しています。
    public function fetchRedColorItems()
    {
        // モデル内では$thisで自分自身のことを指すことが可能
　　　　　　　　    // get() は「結果を取得する」Eloquentのメソッド
        return $this::whereColor('red')->get();
    }
}
```

### Customerモデルに男性の割合を計算するSQL、女性の割合を計算するSQLを書いた例

```php:Customer.php
  // 男性の割合を計算
  public function mens()
  {
    $all = Customer::all()->count();
    $mens_num = Customer::where('gender', 0)->count();
    $mens_percent = round($mens_num / $all * 100);
    return $mens_percent;
  }

  // 女性の割合を計算
  public function womens()
  {
    $all = Customer::all()->count();
    $womens_num = Customer::where('gender', 1)->count();
    $womens_percent = round($womens_num / $all * 100);
    return $womens_percent;
  }
```


## モデルで作ったメソッドをコントローラから呼び出す例

- 呼び出す時には、対象のモデルをnew（インスタンス化）してからメソッドを呼ぶようにします。
- コントローラからVIEWにreturnすることで、クライアント側に表示します。

```php:FruitController.php
  public function redFruitReport()
  {
　　　　　　  $fruitModel = new Fruit();
　　　　　　  dd($fruitModel->fetchRedColorItems()->toArray());
  }
  return view('red_fruit_report');
```

```php:ProductController.php
  public function productReport()
  {
    $customer = new Customer;
    $mens = $customer->mens();
    $womens = $customer->womens();
    return view('product_report',compact('mens', 'womens'));
  }
```

以上になります。
Web開発ツール スター数調査（テストツール、状態管理、GraphQL）

２０２１年末から２０２２年６月までのスター数増加分を調査

調査元
２０２１年までの累積データ
JavaScript ライジングスター 2021
https://risingstars.js.org/2021/ja

２０２２年６月までのデータ
各ツールのGithubページ

| | |2021年|2022年6月30日| |
|:----|:----|:----|:----|:----|
||**テストツール**|累計スター数|現在のスター数|増加分|
|1|Playwright|32.00|39.60|7.60|
|2|storybook|67.90|72.10|4.20|
|3|Cypress|35.80|39.30|3.50|
|4|Puppeteer|75.5|78.7|3.20|
|5|Jest|37.60|39.50|1.90|
|6|Mock Service Worker|8.00|9.9|1.90|
|7|rrweb|10.90|11.80|0.90|
|8|React-testing-library|15.70|16.60|0.90|
|9|Vitest|2.1|5.3|3.20|
|10|jsdom|16.80|17.60|0.80|


| | |2021年|2022年6月30日| |
|:----|:----|:----|:----|:----|
||**状態管理**|累計スター数|現在のスター数|増加分|
|1|Zustand|12.70|18.70|6.00|
|2|XState|18.50|20.60|2.10|
|3|Jotai|6.70|8.90|2.20|
|4|Recoil|15.40|17.10|1.70|
|5|Pinia|4.70|7.90|3.20|
|6|Redux|57.30|58.30|1.00|
|7|Valtio|3.6|4.70|1.10|
|8|Vuex|27.20|27.60|0.40|
|9|MobX|24.70|25.40|0.70|
|10|Nano stores|1.20|1.40|0.20|


| | |2021年|2022年6月30日| |
|:----|:----|:----|:----|:----|
||**GraphQL**|累計スター数|現在のスター数|増加分|
|1|Prisma|19.40|23.80|4.40|
|2|Hasura GraphQL Engine|25.00|27.30|2.30|
|3|Redwood|10.50|14.10|3.60|
|4|Gatsby|52.10|53.20|1.10|
|5|GraphQL Code Generator|8.10|8.90|0.80|
|6|Apollo client|17.10|17.90|0.80|
|7|Directus|13.40|16.50|3.10|
|8|GraphiQL|13.00|13.70|0.70|
|9|Apollo Server|12.20|12.70|0.50|
|10|Vendure|3.00|3.50|0.50|

トップ以外で、今年に入って伸びてきているツール
Vitest（テストツール）
https://vitest.dev/

Pinia（状態管理）
https://pinia.vuejs.org/

Directus（GraphQL）
https://directus.io/

あなたのプロダクトに Apollo Client は必要ないかもしれない - 一休.com Developers Blog
https://user-first.ikyu.co.jp/entry/2022/07/01/121325


## 状態管理

The new wave of React state management | Hacker News
https://news.ycombinator.com/item?id=31959289


昔（6年ぐらい前）はRedux一択でしたが、今は選択肢が大量にあります。
Photoshop,Googleスプレッドシートのような大量の状態管理が必要な場合はReduxが良いのでしょうが、そうでなければReactQuery等で十分です。

Redux ToolKit(RTK)の登場によりReduxの冗長性が排除され簡素化されました。

そして、RTK Queryも生まれました。
これはReduxやRedux Toolkitを知らなくても使えます。


### React Query 改め TanStack Query

https://tanstack.com/query/v4/?from=reactQueryV3&original=https://react-query-v3.tanstack.com/

React Query は Ver4より TanStack Queryと名前が改められました。
TanStack Queryにより、サーバーの状態を処理するあらゆる種類のアプリの構築が非常に簡単になりました。これまで作成するのが非常に困難だったものが、今ではほんの数行で、以前よりもうまく機能します。

キャッシュを使用するか、しないかを設定したい等と細かく設定したい場合。

### urql

https://formidable.com/open-source/urql/

キャッシュとGraphQLを使用する場合。

### Jotai

https://jotai.org/

### Zustand

https://github.com/pmndrs/zustand

グローバルストアが必要な場合は、APIがおそらくこれらの中で最も簡単です。

## SWR
https://swr.vercel.app/ja

複雑なローカル状態の状態管理（Photoshop等）と、
APIを介してデータをフェッチおよび更新するための状態管理を区別する。
これらに必要な解決策はかなり異なっています。

## Recoil
コンポーネントをまたいだStateを自由にいくつでも持つことができる

https://nulab.com/ja/blog/nulab/recoil-example/

https://engineering.linecorp.com/ja/blog/line-sec-frontend-using-recoil-to-get-a-safe-and-comfortable-state-management/

# GraphQL

https://user-first.ikyu.co.jp/entry/2022/07/01/121325

# Stack Overflow Developer Survey

https://survey.stackoverflow.co/2022/

Stack Overflow

https://dev.insights.stackoverflow.com/trends?tags=reactjs%2Cangular%2Cvue.js
Rails console で autoload のパスを確認する ( ActiveSupport::Dependencies.autoload_paths )

# コマンド

rails console で以下を実行

```
ActiveSupport::Dependencies.autoload_paths
```




# 実行例

```rb
irb(main):001:0> ActiveSupport::Dependencies.autoload_paths
=>
["/Users/yumainaura/example/app/channels",
 "/Users/yumainaura/example/app/controllers",
 "/Users/yumainaura/example/app/controllers/concerns",
 "/Users/yumainaura/example/app/helpers",
 "/Users/yumainaura/example/app/jobs",
 "/Users/yumainaura/example/app/mailers",
 "/Users/yumainaura/example/app/models",
 "/Users/yumainaura/example/app/models/concerns",
 "/Users/yumainaura/example/app/uploaders",
 "/Users/yumainaura/.rbenv/versions/2.7.0/lib/ruby/gems/2.7.0/gems/actionmailbox-7.0.2.4/app/controllers",
 "/Users/yumainaura/.rbenv/versions/2.7.0/lib/ruby/gems/2.7.0/gems/actionmailbox-7.0.2.4/app/jobs",
 "/Users/yumainaura/.rbenv/versions/2.7.0/lib/ruby/gems/2.7.0/gems/actionmailbox-7.0.2.4/app/models",
 "/Users/yumainaura/.rbenv/versions/2.7.0/lib/ruby/gems/2.7.0/gems/activestorage-7.0.2.4/app/controllers",
 "/Users/yumainaura/.rbenv/versions/2.7.0/lib/ruby/gems/2.7.0/gems/activestorage-7.0.2.4/app/controllers/concerns",
 "/Users/yumainaura/.rbenv/versions/2.7.0/lib/ruby/gems/2.7.0/gems/activestorage-7.0.2.4/app/jobs",
 "/Users/yumainaura/.rbenv/versions/2.7.0/lib/ruby/gems/2.7.0/gems/activestorage-7.0.2.4/app/models",
 "/Users/yumainaura/example/test/mailers/previews"]

```

# autoloadの追加設定

`config/application.rb` などで設定する

```rb
require_relative "boot"

require "rails/all"

Bundler.require(*Rails.groups)

module Example
  class Application < Rails::Application
    config.load_defaults 7.0
    config.autoload_paths << "#{root}/app/uploaders"
  end
end

```

<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
[React-pdf] 改行設定を日本語に適したものにする

## React-pdfで、文書全体に以下の設定を適用する方法
* 改行時にハイフンを入れないようにする
* 単語の途中で改行する

## こちらにスマートな解決法がありました。
https://github.com/diegomura/react-pdf/issues/419#issuecomment-1161308596

```typescript
Font.registerHyphenationCallback((word) =>
  Array.from(word).flatMap((char) => [char, ''])
)
```

## 解説

React-pdfで改行時の体裁を変更するには、
`Font.registerHyphenationCallback`でメソッドをオーバーライドする。

この時、文章が単語ごとに区切られて`word`としてメソッドに渡されるのだが、
その区切り方は英語に準拠したものとなっているため、日本語の単語では適切に区切られない場合がある。

そこで、メソッドに１文字づつを`word`として認識させ、単語の区切りを気にせずどこでも改行するようにする。
改行時に挿入される文字には`''`を指定して、`'-'`と置き換える。
React+Redux+Toolkitのメモ

ReactでReduxを使ったときのメモです。
@reduxjs/toolkitを使っています。

# 1. 動かす
[公式](https://react-redux.js.org/introduction/getting-started)によると、[official Redux+JS template](https://github.com/reduxjs/cra-template-redux)か[Redux+TS template](https://github.com/reduxjs/cra-template-redux-typescript)を推奨しているようなので、これを参考にしました。

ReduxとToolkitのインストール
```
npm install redux react-redux
npm install @reduxjs/toolkit
```


今回は下記画面のように[https://jsonplaceholder.typicode.com/users](https://jsonplaceholder.typicode.com/users)からユーザを取得する画面で試しました。入力フィールドにidを入力すると、そのidのuserを取得してテーブルに表示します。ステータスとダウンロード時間も表示します。
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2726391/58984eac-d1dd-11cb-f2d1-fa0f84ad97d5.jpeg)


Reduxで管理する値は下記にしました。Sliceの名前も記載します。
・入力フィールド→inputTextSlice
・jsonplaceholderからダウンロードしたuser(配列)→usersSlice
・ステータス、ダウンロード時間→loadStatusSlice

StoreにはSliceを登録します。Sliceには管理したい値と、値に対してアクションするための関数を登録します。

usersSliceを例にして各ソースコードの関係図を示します。

線あり
![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2726391/60233adc-dc58-0ab3-e579-a728c40bd164.jpeg)


線なし
![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2726391/8cbd610c-8802-6689-f681-a4307a7e66b7.jpeg)


ソースのGitHubは[ココ](https://github.com/gomagon/react-redux-test)


# 2.Redux DevToolsでStoreを確認
Chromeに[Redux DevTools拡張機能](https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd?hl=ja)を入れてStoreの中身が見れます。
![4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2726391/68fc1e4d-d64e-a1aa-3803-f20c992e212c.jpeg)

これをオフにするには、StoreにdevTools:falseを設定します。(デフォルトはtrue)
```javascript:Store.ts
import { configureStore, ThunkAction, Action } from '@reduxjs/toolkit';
import loadStatusSlice from './loadStatusSlice';
import inputTextSlice from './inputTextSlice';
import usersSlice from "./usersSlice";

export const store = configureStore({
  reducer: {
    loadStatus: loadStatusSlice,
    inputText: inputTextSlice,
    users: usersSlice,
  },
  devTools: false
});

export type AppDispatch = typeof store.dispatch;
export type RootState = ReturnType<typeof store.getState>;
export type AppThunk<ReturnType = void> = ThunkAction<
  ReturnType,
  RootState,
  unknown,
  Action<string>
>;
```

# 参考
[ここ](https://reffect.co.jp/react/react-redux-for-beginner)を参考にさせていただきました。
PHP 複数階層にある特定のファイルのみをrequire_onceする

## 名前空間構成
```json:composer.json
{
  "require": {
    <省略>
  },
  "autoload": {
    "psr-4":{ "App\\": "root/" }
  }
}
```

## ディレクトリ構造
```
root/
  ├─ functions/
  │       ├─ func1.php
  │       └─ nest/
  │            └─ func2.php
  └─ Main.php
```

## 関数ファイル
```php:func1.php
namespace App\functions;

function func1() {
    echo "func1" . PHP_EOL;
}
```
```php:func2.php
namespace App\functions\nest;

function func2() {
    echo "func2" . PHP_EOL;
}
```

## 読み込み
```php:Main.php
namespace App;

use function App\functions\func1;
use function App\functions\nest\func2;

array_map(fn($v) => require_once $v, glob(__DIR__ . "/functions/{*.php,nest/*.php}", GLOB_BRACE));

func1();
func2();
```
```:実行結果
func1
func2
```

https://www.php.net/manual/ja/function.glob.php
🔰【メモ】Railsの基礎中の基礎の用語集②

# はじめに
前回に引き続き、今回も基礎的な用語のアウトプットを行います。

# 運用環境
運用環境とはシステムをどこで使用するか定められている環境のこと。3つの種類がある。
| 運用環境 | 通称 | 概要 |
|:-|:-|:-|
|  development | 開発環境  | 主にアプリケーションを開発する際に使用する環境  |
| test  | テスト環境  | アプリケーションの動作をテストする際に使用する環境  |
| production  | 本番環境  | アプリケーションを実際にリリースする際に使用する環境  |

なぜこのように環境を分けるのかというと、環境ごとに必要な設定が多く存在するためである。
例えば、開発環境では「バグを探しやすいツール」を導入したほうが便利だが、本番環境ではアプリケーションのパフォーマンスを上げるために、余分なツールは使わないほうが適切である場合などがあるため。
Railsでは`database.yml`を編集することで、データベースの設定を運用環境ごとに変更できる。

# ライブラリ
他のプログラムと合わせて使用するために、複雑なプログラムを１つのセットにしたもの。
複雑な機能実装でも、ライブラリをアプリへ読み込ませることにより、簡単に実装できるようになる。
Rubyのライブラリは`RubyGems`

# CRUD
アプリケーションのデータ取り扱いに関して、基本的な処理の頭文字を並べたもの。
| Create | Read | Update | Delete |
|:-:|:-:|:-:|:-:|
| 生成  | 読み取り  | 更新  | 削除  |

# レイアウトテンプレート
アプリケーションのビューファイルの共通部分をまとめたもの。
例えばヘッダーやフッターなどが全てのビューに共通となる場合、レイアウトテンプレートに記述しておくことで各テンプレートファイルは各々の見た目を記述するだけでよくなる。
Railsの場合は`applicaｔion.html.erb`というファイルがレイアウトテンプレートとなる。

# ストロングパラメーター
ストロングパラメーターは意図しないデータベースの読み書きを防ぐために使用します。
全てのパラメーターを受け取る仕様の場合、悪意のあるパラメーターによって第三者にデータを改竄されてしなうなど、セキュリティ上の欠陥を作り出してしまう恐れがある。

# バリデーション
データを登録する際に一定の制約をかけること。例えば、空のデータは登録できないようにしたり、文字数を制限するなど。

# 終わりに
本日も短いですが、ここまでにしようと思います。
知識等間違いがあれば、ご指摘頂けましたら幸いです。
k8sのバージョンを指定してクラスター構築

# インストール

※インストール済みの場合は一度削除
```bash
sudo kubeadm reset
sudo apt purge kubelet kubeadm kubectl
```

バージョン一覧を取得

```bash
apt list -a kubeadm
```

`apt-get install`する際にバージョンを指定します。  
今回は`1.22.11`を指定してみます。

[doc - Install kubeadm](https://kubernetes.io/ja/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#kubeadm-kubelet-kubectl%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)

```bash
# 必要パッケージ
sudo apt-get update && sudo apt-get install -y apt-transport-https curl

# gpgキー
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -

# リポジトリ
cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF

# バージョンを指定してインストール
sudo apt-get update
sudo apt-get install -y kubelet=1.22.11-00 kubeadm=1.22.11-00 kubectl=1.22.11-00
sudo apt-mark hold kubelet kubeadm kubectl
```

# クラスター構築

```bash
kubeadm init \
    --control-plane-endpoint=<CONTROL_PLANE_IP> \
    --apiserver-advertise-address=<CONTROL_PLANE_IP> \
    --pod-network-cidr=<POD_CIDR> \
    --kubernetes-version=1.22.11
```

※ `docker`と`containerd`が共存していて`containerd`を使いたい場合

```bash
kubeadm init \
    --control-plane-endpoint=<CONTROL_PLANE_IP> \
    --apiserver-advertise-address=<CONTROL_PLANE_IP> \
    --pod-network-cidr=<POD_CIDR> \
    --kubernetes-version=1.22.11 \
    --cri-socket=/run/containerd/containerd.sock
```

※ 参考

```bash
$ kubeadm init -h
...
      --cri-socket string                    Path to the CRI socket to connect. If empty kubeadm will try to auto-detect this value; use this option only if you have more than one CRI installed or if you have non-standard CRI socket.
...
      --kubernetes-version string            Choose a specific Kubernetes version for the control plane. (default "stable-1")
...
```
デプロイ時に起こったType error: Cannot find moduleエラー

# ローカルでは起こらないビルドエラーが発生

Next.jsとTypeScriptで作成したアプリをVercelにてデプロイした際に下記のエラーによりビルドが失敗しました。

```tsx
Type error: Cannot find module '../../types/fetchMemoList' or its corresponding type declarations.
```

情報を調べるとtypeconfigやpackage.jsonの設定ミスなど色々な情報が出てきましたが、読んでみてもどれも違いそう。。。

この調査で2時間くらいネットを彷徨いました。

## 結論：参照先のファイル名が違った、、、

結論から申し上げますと、モジュールとして参照しているファイル名とimport文のファイル名が違ったことにより参照先が見つからなかったという凡ミスだったのです。

まさになんの捻りもないエラー文そのままのエラーです。

# ファイル名の大文字小文字の変更が落とし穴

わたしも含めプログラミング経験が浅いと意外と気がつかない落とし穴だと思いますので、誰かの参考になればと思い記事にしました。

上記のミスに気がつかなかった要因として、ローカル環境では問題なくビルドできていた点にあります。ですのでコードをいくら見返しても原因が分かりませんでした。

そんなときに下記の記事に行き当たりました。

**[TypeScriptで、TS2307のエラーが出たとき、TS1149のエラーも疑う](https://himenon.github.io/docs/javascript/case-sensitive-paths-error/)**

そうして自分のローカルのファイル名とGitHubのリポジトリを比較すると、ローカルではファイル名の先頭が小文字だったのですが、リモート側はファイル名の先頭が大文字となっています。

> ファイル名の大文字小文字だけを変換した場合、gitに観測されないことがある。
> 

そのため、ファイル名変更ができているように見えて、実はローカルリポジトリのステージングには載っておらず、何度プッシュしていてもリモート上のファイル名は更新されていなかったのです。

## ローカルリポジトリのファイル名を変更して再プッシュで解消

 下記の対応をし、ローカルとリモートのファイル名に差異が無いことを確認したところビルドエラーは解消されました。

> gitの処理[](https://himenon.github.io/docs/javascript/case-sensitive-paths-error/#git%E3%81%AE%E5%87%A6%E7%90%86)
> 

> ファイル名の大文字小文字だけを変換した場合、gitに観測されないことがある。 `git mv`を利用することで、ステージングに載せることが可能である。
> 

```tsx
git mv 【現在のファイル名】【新しいファイル名】
```

ちなみにリモートにプッシュしていなくても、`git ls-files`コマンドでローカルリポジトリのファイル名を参照するとファイル名に差異が確認できるので、ファイル名だけを変更した場合にgitに観測されているかを確認してからプッシュしておくとプッシュの2度手間にならない。

merge後に気づいたらより面倒ですしね。。。

ファイル名変更したあとに普通にプッシュできてたのと、ローカル環境ではエラーにならないため全く気がつかない落とし穴でした。

誰かの参考になれば幸いです。
Ubuntuのdocker-composeでmysqlを立てるときのパーミッション設定

WindowsやMacOSで使う`Docker Desktop`とはパーミッション周りの挙動が少し違うみたいです。  
`my.cnf`でログ出力設定をした際にエラーが出ました。

# 動く`docker-compose.yml`

```yaml
version: "3.7"

services:
  mysql:
    image: mysql:8
    volumes:
      - db_data:/var/lib/mysql
      - type: bind
        source: "./my.cnf"
        target: "/etc/mysql/conf.d/my.cnf"
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      TZ: ${TZ:-UTC}
    command: >
      bash -c "mkdir -p /var/log/mysql
      && chown -hR mysql:mysql /var/log/mysql
      && /entrypoint.sh mysqld"
    ports:
      - ${MYSQL_PORT:-3306}:3306
    restart: unless-stopped

volumes:
  db_data:
```
※ `command`の３行はインデントがずれると動かない場合があるので注意

追記部分

```diff
+    command: >
+      bash -c "mkdir -p /var/log/mysql
+      && chown -hR mysql:mysql /var/log/mysql
+      && /entrypoint.sh mysqld"
```

# エラーと対処

## No such file or directory

```
mysql_1       | 2022-06-30 01:50:51+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.29-1debian10 started.
mysql_1       | 2022-06-30 01:50:51+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
mysql_1       | 2022-06-30 01:50:51+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.29-1debian10 started.
mysql_1       | 2022-06-30 01:50:51+00:00 [Note] [Entrypoint]: Initializing database files
mysql_1       | 2022-06-30T01:50:51.803532Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.29) initializing of server in progress as process 41
mysql_1       | 2022-06-30T01:50:51.805709Z 0 [ERROR] [MY-010187] [Server] Could not open file '/var/log/mysql/error.log' for error logging: No such file or directory
mysql_1       | 2022-06-30T01:50:51.805753Z 0 [ERROR] [MY-013236] [Server] The designated data directory /var/lib/mysql/ is unusable. You can remove all files that the server added to it.
mysql_1       | 2022-06-30T01:50:51.805762Z 0 [ERROR] [MY-010119] [Server] Aborting
```

→ ディレクトリ作成

```bash
mkdir -p /var/log/mysql
```

## Permission denied

```
mysql_1       | 2022-06-30 01:56:49+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.29-1debian10 started.
mysql_1       | 2022-06-30 01:56:49+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
mysql_1       | 2022-06-30 01:56:49+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.29-1debian10 started.
mysql_1       | 2022-06-30 01:56:49+00:00 [Note] [Entrypoint]: Initializing database files
mysql_1       | 2022-06-30T01:56:49.795239Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.29) initializing of server in progress as process 44
mysql_1       | 2022-06-30T01:56:49.796978Z 0 [ERROR] [MY-010187] [Server] Could not open file '/var/log/mysql/error.log' for error logging: Permission denied
mysql_1       | 2022-06-30T01:56:49.797012Z 0 [ERROR] [MY-013236] [Server] The designated data directory /var/lib/mysql/ is unusable. You can remove all files that the server added to it.
mysql_1       | 2022-06-30T01:56:49.797019Z 0 [ERROR] [MY-010119] [Server] Aborting
```

→ パーミッション設定

```bash
chown -hR mysql:mysql /var/log/mysql
```
最新Laravle9.19.x ～ のbreeze ログイン実装コマンド

## Laravle9.19.x ～ breeze ログインができない？を解決
みなさんこんにちは 
[ジーズアカデミー学校長 山崎ですm(_ _)m](https://gsacademy.jp/mentor/)
今回はLaravel9.19からLOGINを生成するコマンドが変わったようなのでメモしておきます。

### 環境
AmazonLinux2/cloud9 

---


#### Laravel9.19.x ログイン画面作成
#####  breezeをインストール


```cmd:ターミナル

#1. Laravel 9.19～ の場合
composer require laravel/breeze --dev

#2. artisan コマンドを実行
php artisan breeze:install

#3. npmパッケージをインストール
npm install

#4. パッケージをビルド
#公式サイトでは「npm run dev」
npm run build

#5．テーブル作成
php artisan migrate


```

![スクリーンショット 2022-06-30 110517.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104530/193a66f3-a609-e03e-a8fa-69ec92a982fb.jpeg)

これでLaravel9.19~ のLOGIN機能が実装できました！
**★ ここでハマったのが4つ目のコマンド！！**
今までは dev で良かったのが build でないと動作しませんでした。
EC2/Cloud9 環境だからかもしれませんが！

【公式ドキュメント】👇
https://laravel.com/docs/9.x/starter-kits#breeze-and-blade








## YouTubeでも解説
是非こちらも見てください
#### 「Laravel 9.19~ Breeze 45分でアプリを作る！」

<iframe width="560" height="315" src="https://www.youtube.com/embed/BQBNJ-wArLo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


以上
Windows Power ShellでOSのバージョンを確認する

## 方法
Windows PowerShellで下記実行
```powershell
(Get-WMIObject win32_operatingsystem).name
```

出力
```powershell
Microsoft Windows 11 Pro|C:\WINDOWS|\Device\Harddisk0\Partition3
```

Note
Windows PowerShellで実行すること。
Anaconda Promptで実行したら動かなかった。

## 参考
[How to Get Operating System Details with PowerShell on Windows](https://www.faqforge.com/powershell/get-operating-system-details-powershell/)
ESLintでParsing error…となった時の備忘録

ESLintがいちいちイラっとする

てんてるさんの『【Firebase】Cloud Functions チュートリアル』で
https://zenn.dev/tentel/books/a96e4a64d3a672911f25
FirebaseのCloud Functionsを学習中（08 HTTPリクエスト編(JavaScript)より）にESLintでエラーが発生。

```terminal
  5:77  error  Parsing error: Unexpected token =>

✖ 1 problem (1 error, 0 warnings)
```

参考：
ESLintでParsing error…となった時の対応　parserOptionsを設定する
https://note.com/shift_tech/n/n550ac679fbfa

```terminal
{
	"env": {
		"es2022": true
	},
	...
	"parserOptions": {
		"ecmaVersion": 13
	},
	...
}
```
こんな感じでparserOptionsを設定したらerrorが消えました。
Salesforce翻訳（標準オブジェクトとカスタムオブジェクト）のやり方

--標準オブジェクト（タブと表示ラベルの名称変更機能）
①オブジェクトの名称の指定：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442974/85c0aa4c-7fad-f83c-7ca1-483c449f7557.png)
②項目の名称の指定：
■「編集」リンクをクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442974/232b85bd-415c-76b0-8225-a8fc08c788fe.png)
■「次へ」ボタンをクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442974/cfb64463-bd55-3774-7bcd-c154d5426996.png)
■項目名の変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442974/cdf6049d-4640-d79d-5c9d-7d08dee8ba47.png)
■オブジェクト名の表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442974/be124c68-ad11-b3e9-2ae7-75ddada3aeb0.png)
■項目名の表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442974/a7986582-3559-6205-8c39-7f1ac03798c5.png)
--カスタムオブジェクト（トランスレーションワークベンチ）
翻訳範囲：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442974/0393dc9f-b4b4-ecfa-b7a1-669ecc9f19bc.png)
翻訳の設定：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442974/e0db095a-a434-e908-fbd4-5a8dfe594861.png)
ツール記事を無料で提供するメリット

弊社ではFXの関わるWEBサイトを運営していく中で、無料の計算ツール、自動取得ツールを作成して提供している。

無料ツールを作って提供すること自体は何のメリットもなく、ただ制作費がかかるだけだ。

しかし、無料ツールを提供することによって、間接的なSEOのメリットがあるため、開発を続けている。

今回は弊社が開発したツールを紹介しながら、WEBサイト運営者に自動ツールの開発をおすすめしたいと思う。

自動化することで普段の更新の手間が減ったり、ユーザーにとってメリットもたくさんあると考えている。


## ツール記事による間接的なSEO効果について

無料の計算ツール、自動取得ツールはユーザーが定期的に訪問するような内容にすることで、リピーターが増える。

その内容に関わる内部リンクを入れておけば、ごく一部のユーザーは内部リンクを辿ることにより、他のページの評価が上がる。

ツール記事のみ訪問した場合でもサイト全体のPVが上がり、リピート率も上がるために評価が高くなる。

そうすることでドメイン全体の評価が上がり、コンバージョンに関わる記事の評価も上がって検索順位が高くなる。という流れだ。

このような間接的なことを行ってドメイン評価を上げようとする人は少ないが、他の人がやらないから付加価値が上がって評価される。

既にライバルサイトが実施していればツール記事を作るメリットは減ってしまうが、他社がやっていなければチャンスかもしれない。


## 弊社の提供する無料ツール

コチラが弊社の提供する無料ツールで、すべて無料で公開している。

ツールの内容によって、毎日チェックするものもあれば、必要な時に利用するようなツールもある。

以下はすべてFXに関わるツールだが、ぜひご自身のビジネスで利用できるものがあればご活用頂きたいので紹介する。


### ロスカット計算ツール

ロスカット計算ツールはトレーダーがエントリーする前、エントリー後にロスカットされないか計算するツールだ。

これは1つの通貨ペアまでしか対応していないが、複数ポジションを持っていても計算可能なので、ナンピン系EAを運用している人も利用可能。

「追加入金するか諦めるか」の判断が必要になる場面で、すぐに計算できるのは嬉しい機能だと思っている。

実際に毎日使っている。という意見も頂くので、作った甲斐がある。

・[ロスカット計算機](https://nagoweb.co.jp/kaigaifx/losscut-calculators/)	

### レバレッジ計算ツール

こちらは「何ロットまで買えるか？」が簡単に分かるツール。基本的にはエントリー前に使うもの。

現在レートが自動取得されるので、今の証拠金に対して何ロットまで買えるのかが分かって便利だと思う。

慣れている人は必要ないかもしれないが、初めて利用する通貨ペアや、フルレバレッジでエントリーしたい人に役立つツールである。

・[レバレッジ計算機](https://nagoweb.co.jp/kaigaifx/leverage-calculators/)

### 証拠金計算ツール

こちらは「必要証拠金がいくらか？」が分かるツール。主にロット数が決まっていて、それに対して証拠金がいくら必要か計算したい人が利用する。

レバレッジ計算ツールは「何ロット」、証拠金ツールが「いくら」となっていて、対になっているツールである。

証拠金ツールは上の2ツールと比べて利用者は少ないが、補完的な役割になっている。

・[証拠金計算機](https://nagoweb.co.jp/kaigaifx/forex-calculators/)

### pips計算ツール

こちらはFX特有の言葉pipsを計算してくれるツールで、円と決済通貨の2種類で表示してくれる。

USDJPYなど決済通貨が円の場合は計算が簡単だが、EURUSDなど決済通貨が円以外の場合がよく分からない人が多くなる。

さらにゴールドやシルバーになると1ロットの通貨数が違うので、複雑になってくる。

このあたりのpipsが簡単に表示されるので、pipsの計算が分からなくなった場合に便利だと思う。

利用頻度は少ないと思うが、あれば便利だと思って作ってみた。

・[pips計算機](https://nagoweb.co.jp/kaigaifx/pips-calculators/)

### 税金計算ツール

税金計算ツールは税理士監修の元で作成したツールで、東京都を基準に計算されるようにできている。

所得税は全国統一だが、住民税は市町村によって変わるため、あくまでざっくりした計算をするためのツール。

このツールは毎日利用者はいるが、主に年末から確定申告終了あたりまでの利用者が多い。

給与所得者が対象なので、個人事業主は利用できないが、計算は調整控除など細かい計算式も入っていて、ふるさと納税の限度額まで分かる機能付き。

これは制作にかなりの時間を使ってしまい、税理士にもかなりの負担をかけてしまった。

・[税金計算ツール](https://nagoweb.co.jp/kaigaifx/tax8/)

### スワップポイント計算ツール

スワップポイントは「通貨間の為替差損益」で、これを自動取得して円に自動換算してくれるツール。

コチラは手書きコンテンツも入っているので、ツール感があまりないが、なかなか優れたものだと思っている。

通常、スワップポイントは「ポイント」という単位で表示されるため、そこから為替計算が必要になる。

決済通貨が円の場合はスワップポイントに×100をすれば良いが、決済通貨が円以外の場合は、そこから為替計算が必要。

このツールでは為替を自動取得するため、常に円で見ることができるのが特徴。

さらに複数業者のスワップポイントがチェックできるので、長期保有したい人やスワップポイントで稼ぎたい人に便利なツールだ。

両建てをする人は同じ通貨ペアだけでなく、相関性が-1に近いものを探すことで、別の通貨ペアでの両建てもすることができるため、その判断に便利なツールとなっている。

FXの世界ではスワップを気にする人は少ないが、なかなか便利な機能を搭載したツール記事だと思っている。

・[スワップポイント自動ツール](https://nagoweb.co.jp/kaigaifx/swap/)


以上、6つのツール記事を作って来たが、ユーザーからの利用頻度が高く、作った甲斐があると思う。

WEBサイト運営をしている人は、手書きのお役立ちコンテンツだけでなく、このような自動ツールをプログラマーに依頼して作ることで、付加価値のあるWEBサイトになる可能性を秘めていると思う。

特にお金に関わるサイトや、料金が常に変動するようなサイトを運営している人などは、自動化する方が手間が減り、コスパ的にも良いと思う。

ぜひ今後のWEBサイト運営に役立てて頂ければと思って紹介した。
【BizRobo!】プルダウンの選択で、該当するものがない場合の条件分岐方法

# はじめに
今回はプルダウンメニューで選択したい項目が無かった時の対処方法です。
ぜひ活用してください。

# フローサンプル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902544/e8a6a4bb-f544-5b50-f467-ee42bf292938.png)

# 概要
１：対象アプリケーションの使用
２：Excelを読み込み、カテゴリーを変数に取得
３：１のアプリケーションにて、２の変数のカテゴリーを自動選択する
※既存のカテゴリーと同じものがない場合は「該当なし」を選択する

# 設定方法
①アクションステップを作成し、Desktop Automationを選択

②対象のExcelを読み込み、変数を開く

③Excel画面左上を右クリックし「ループ⇒選択行をループ⇒最初の行を除外」を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902544/0fca760d-8618-fcca-e7f6-24280f332c96.png)

④B2のカテゴリーを右クリックし「コンテンツ設定」で、コンテンツに変数を入れる

⑤アクションステップを作成し、Desktop Automationを選択
　※入力値に④の変数を入れて、DAエディターを開ける

⑥商品登録タブに表示を切り替え、以下の赤枠を右クリックし、「クリック⇒Left」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902544/b3f9bb26-3a96-60ab-7edd-a53f964d452c.png)

⑦食料品を右クリックし、「クリック⇒Left」を選択
※ここはComponentの設定のためにクリックさせています

⑧⑦で作成したステップを開け、Componentを以下のように設定します。
一覧項目[name="DAカテゴリー"]
↓
"一覧項目[name=￥""+DAカテゴリー+"￥"]"
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902544/c0e6c48f-b181-172e-ba84-1af17dedb2df.png)

⑨⑦で作成した下のSecondsを2に変更し、「ThrowTimeOut」を削除する
※該当するメニューがなかった場合に、2秒まってから処理を行う。
「ThrowTimeOut」を削除する理由は、これがあるとエラーと認識されてしまうため。

⑩以下の〇をダブルクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902544/7f9554bd-0272-e46e-47e5-d50cb01a0b68.png)

⑪カテゴリーの該当なしを右クリックし「クリック⇒Left」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902544/2fcefe78-c2b3-621a-613c-9cda19a8228d.png)

# さいごに
ぜひご活用いただけると幸いです。