OmniAICreator/Qiita-1.07M huggingface dataset:
IvyDE で追加したライブラリが VSCode の Project Manager for Java に認識されない

[IvyDE](https://ant.apache.org/ivy/ivyde/) は Eclipse 用の拡張機能で、[Apache Ivy](https://ant.apache.org/ivy/) で管理している依存ライブラリを Eclipse のクラスパス管理に統合します。Ivy 管理下の JAR ファイルへのパスを `.classpath` に直接記載していると、ライブラリの更新等でファイル名が変わった際にエラーが発生します。しかし、IvyDE でクラスパスコンテナを作成している場合、自動的にクラスパスの情報が変更されるためエラーになりません。

![ivyde.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463374/f543c0b2-b3b3-f72d-4bb4-f994e299d428.png) 

一方、[Extension Pack for Java](https://github.com/Microsoft/vscode-java-pack) は VSCode 用の拡張機能パックです。
VSCode 上で Java コードに対する IntelliSense、デバッグ、テストが実行できるほか、プロジェクトの管理（Maven / Gradle / アンマネージド）も可能です。[^1]

[^1]: 実体としては[Project Manager for Java](https://github.com/Microsoft/vscode-java-dependency)がプロジェクトの管理を担当しています。

![vscode-java-dependency](https://raw.githubusercontent.com/Microsoft/vscode-java-dependency/main/images/manage-dependencies.gif) [^2]

[^2]: https://github.com/Microsoft/vscode-java-dependency

IvyDE でライブラリを追加したプロジェクトを VSCode で開くと、それらのライブラリを認識せずエラーが表示されます。IvyDE は Eclipse 用の拡張機能ですから、当然といえば当然です。

## IvyDE で追加したライブラリが Extension Pack for Java に認識されない理由

`.classpath` ファイルを確認するとわかります。`java.configuration.checkProjectSettingsExclusions` が `true` の場合（デフォルト）、左ペインでは見つからないため、エクスプローラから開いてください。以下のような記載があるはずです：

```xml
<classpathentry kind="con" path="org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=ivyde-test&amp;ivyXmlPath=ivy.xml&amp;confs=*"/>
```

通常の JAR ファイルをクラスパスに追加するには `kind="lib"` として記載しますが、IvyDE で追加した依存は `kind="con"` 、すなわち[クラスパスコンテナ](https://help.eclipse.org/latest/index.jsp?topic=/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/core/IClasspathContainer.html)として記載されています。いまのところ、Extension Pack for Java は IvyDE クラスパスコンテナ内の JAR を参照してくれないようです。

## 対処法

シンプルに `.classpath` を編集する方法もありますが、あまり便利ではないのでお勧めできません。せっかくなので、Extension Pack for Java の機能を活用しましょう。

Extension Pack for Java は、現在開いているプロジェクトがアンマネージドであると認識した場合、`settings.json` でクラスパスを通すことができます：

```jsonc
"java.project.referencedLibraries": [
    "ivy/**/*.jar", // デフォルト値は "lib/**/*.jar" です
]
```

![ivyde2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463374/36a410bf-428e-ac8e-0442-5400efa5ac55.png)

`Referenced Libraries` 右隣の + マークからは JAR を個別に追加できます。しかし、 `settings.json` では [glob パターン](https://ja.wikipedia.org/wiki/%E3%82%B0%E3%83%AD%E3%83%96)が使えますので、 `ivy:retrieve` の `pattern` とすり合わせることで IvyDE の使い勝手に寄せられます。

`.project` があるとマネージドであると認識されてしまいますが、一時的に削除やリネームすればアンマネージド扱いになります。引き続きエラーが表示される場合は、`Clean Workspace` とファイルの開きなおしで解決する場合があります。

## 参考リンク

* [サンプルプロジェクト](https://github.com/yokra9/ivyde-test)
* [How to add referenced library JAR files using relative path for eclipse Java project in vscode](https://stackoverflow.com/questions/69216059/how-to-add-referenced-library-jar-files-using-relative-path-for-eclipse-java-pro)
* [Add java.project.referencedLibraries setting #1196](https://github.com/redhat-developer/vscode-java/pull/1196)
画面収録ファイル（mov）からgifを作成

# これは何？

Qiita等へ投稿する際に、画面の様子をアップしたい時に、画面のgifをさくっと作成するためのワークフローです。

環境は、以下のとおりです。

- MacBook Pro (13-inch, 2019, Four Thunderbolt 3 ports)
- Darwin monju.local 21.2.0 Darwin Kernel Version 21.2.0
- ffmpeg: stable 4.4.1 (bottled)


# 概要

手順は、以下のとおりです。

1. 画面収録
1. ffmpegを使用して、ファイルを変換


# 画面のとりこみ

```sh
Shift + Command + 5
```

を押すと、選択範囲の画面を収録することができます。
私の場合、保存先をデスクトップにしています。


# ffmpegにてgifの作成


保存されたファイルを、ffmpegを使って変換します。
[こちら](http://blog.pkh.me/p/21-high-quality-gif-with-ffmpeg.html)のスクリプトを拝借します。


```sh:gifenc.sh
#!/bin/bash

palette="/tmp/palette.png"

filters="fps=15,scale=640:-1:flags=lanczos"

ffmpeg -v warning -i $1 -vf "$filters,palettegen" -y $palette
ffmpeg -v warning -i $1 -i $palette -lavfi "$filters [x]; [x][1:v] paletteuse=dither=floyd_steinberg"  -y $2
```

使用方法は、以下のとおりです。
sl.movが、収録した画面のファイルです。

```sh
$ chmod +x gifenc.sh
$ ./gifenc.sh sl.mov sl.gif
```

以下の、gifが作成されました。

![sl.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191337/b8338e30-ae16-3db7-0d7c-d5957c4e1b1e.gif)
dbtのgeneric testの実装基準を言語化してみた

# この記事はなに？
dbtの`generic test`を用いたデータ品質のチェックを実装する上で、どのような観点でどのテストを組み込むのかを言語化した記事になります。
各社、扱うデータによって実装基準に差異があると思いますので、ぜひ別の観点がございましたらコメントやTwitterのDM等で教えていただけますと幸いです。(記事にも追記させていただきます！)

# dbtのテストについて
dbtでは、YAMLファイルにテスト内容を記載する`generic test`の方法と、SELECT文を書いて実行する`singular test`の2つの方法が用意されています。
この記事では、前者の`generic test`を組み込む基準について記載しております。(後者は、ビジネスロジックに合わせて独自定義で実装するケースを想定しているため)

# generic testの種類と実装基準
では、本題に移っていきます。
dbtのgeneric testでは、下記4つのテスト機能が用意されています。

- unique
- not null
- accepted values
- relationships

以下で、各テストの簡単な説明と実装基準について記載していきます。

## [unique](https://docs.getdbt.com/reference/resource-properties/tests#unique)

### 説明
その名の通り、指定したカラムに対して重複しているレコードが存在するかをチェックします。

### 実装基準 

- 主キー
    - 単一カラムの場合は、そのカラムに対して実装します。
    - 複数カラムの場合は、結合した上でその列に対して実装します。([参考](https://docs.getdbt.com/reference/resource-properties/tests#testing-an-expression))
- メールアドレス、電話番号
    - ビジネスロジック上、`同一の情報で登録ができない`等の制約がある場合に実装します。
    - 取引先や担当者など、複数レコードで同一のメールアドレスや電話番号を設定する可能性がある場合は、その限りではありません。

## [not_null](https://docs.getdbt.com/reference/resource-properties/tests#not_null)

### 説明
その名の通り、指定したカラムに対してnullのレコードが存在するかをチェックします。

### 実装基準

- 主キー
    - 単一カラムの場合は、そのカラムに対して実装します。
    - 複数カラムの場合は、結合した上でその列に対して実装します。([参考](https://docs.getdbt.com/reference/resource-properties/tests#testing-an-expression))
- 作成日時、所有者IDなど
    - データを生成する過程で必ず値がセットされることが予想されるカラムに対して実装します。
- 取引先名、商談名など
    - ビジネス上、何かしらの値がセットされていることが望まれるカラムに対して実装します。

## [accepted_values](https://docs.getdbt.com/reference/resource-properties/tests#accepted_values)

### 説明
valuesで設定した値以外の値を持つレコードが存在するかをチェックします。
なお、nullはチェック対象外となっています。(おそらく、not nullでチェックする前提のため)

### 実装基準
- 性別、年齢帯など
    - 一般的にMECEに分けられる(分けられている)カラムに対して実装します。
    - ただし、都道府県など値の種類が多い場合は、`singular test`で実装して呼び出すことも検討にいれます。(YAMLファイルの可読性を担保するため)
- 値の種類が10個以下、かつ変動する可能性が低いカラム

## [relationships](https://docs.getdbt.com/reference/resource-properties/tests#relationships)

### 説明
あるテーブルのカラムが持つ値が、別テーブルのカラムに存在するかどうかをチェックします。(参照整合性とも呼ばれる)

### 実装基準
- 外部キー


# おわりに

ここまで読んでくださりありがとうございました。
この記事を書いて感じたのは、dbtの`generic test`は`データ品質を向上させる上での必要最低限の設定である`ということです。
`generic test`を実装した上で、ビジネスロジックに沿って`singular test`を実装していくことで、本当の意味でのdbtを用いたデータ品質の向上を実現できるのではないでしょうか。
各社、扱うデータによって実装基準に差異があると思いますので、ぜひ別の観点がございましたらコメントやTwitterのDM等で教えていただけますと幸いです。
mp4からオーディオファイルを作成

# AACを作成

以下の設定にて、エンコードできます。
入力ファイルはmp4の動画を例示していますが、wavなどの音源ファイルでも構いません。

固定ビットレート320 kbps

```sh
afconvert -d aac -s 0 -b 320000 inputFileName.mp4 outputFileName.m4a
```

平均ビットレート320 kbps

```sh
afconvert -d aac -s 1 -b 320000 inputFileName.mp4 outputFileName.m4a
```

可変ビットレート320 kbps

```sh
afconvert -d aac -s 2 -b 320000 inputFileName.mp4 outputFileName.m4a
```
品質指定127

```sh
afconvert -d aac -s 3 -u vbrq 127 inputFileName.mp4 outputFileName.m4a
``` 

# ALAC: Apple Lossless Audio Codecを作成

ALACで出力します。

```sh
afconvert -d alac inputFileName.mp4 outputFileName.m4a
```

# FLACを作成

FALCも作成できます。

```sh
afconvert -d flac inputFileName.mp4 outputFileName.m4a
```

この他にも、

```sh
$ afconvert -hf
```

で、対応可能なフォーマットを確認することができます。


# zshのfunctionを使用

```sh
function mp42alac(){
  afconvert -d aac -s 2 -b 320000 $1 $1:r.m4a
}
```

上記の内容を~/.zshrcに記載します。

使用方法は、以下のとおりです。

```sh
$ mp42alac inputFileName.mp4
```


# foreach でフォルダ内のファイルを変換（tcsh, zsh）

フォルダ内のファイルを一括で変換するには、foreachを使用します。

```sh
$ foreach i (*.wav)
foreach> afconvert -d alac $i $i:r.m4a
foreach> end
```
blenderで親ボーンに子オブジェクトつけたらジャンプしたり回転したりすったもんだするじゃろ？

# 解決してうれしくてとりいそぎ公開します!!

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/8404044c-9ec3-14eb-c923-c9b265ab7e7b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/fa452a09-e31d-d39e-c1d7-f9890614253b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/adbccf5d-aa8f-dc9c-8820-213ad5a023e8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/f3868e4e-425b-71fa-301b-ddd1876c2d3c.png)
IT用語(OSS等)のカタカナ読みまとめてみました

## はじめに

皆さんは、IT用語の読み方を間違えて恥ずかしい思いをしたことはありますでしょうか？

私はあります。

特にOSSで初見じゃ分からないライブラリの名前とか結構ありますよね。（`nginx`とか最初どうやって読むんだよって思いました・・・）

そんな時に"XXX 読み方"とかでググるのも何だかめんどくさいと思うので、まとめてみました。

## 検索方法

下記で`markdown` + `mkdocs` + `Github Pages`で作成しました。

https://doara-developer.github.io/pronunciation-dict/


右上の検索ボックスから用語を入力すると

<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497222/195e5822-c061-07d3-7979-b4775e687418.png">

読み方が表示されます。

<img width="500" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497222/b70c7f0b-deba-ac81-d73d-affb211c6368.png">


## FAQ

#### 私はこの記事と違って「XXXX」って読んでいるんだけど？ or そもそも英語の発音なんだからカタカナ読み要らなくない？
全く構いません。

これは「そもそも何て読むんだ？」と分からない人の助けになればと思い作っただけなので、読み方に自信を持っている人はそのままで大丈夫です。(例えば`Kubernetes`とかも人によって読み方結構違いますし、国によっても違いがあるようですし)

#### この用語が載っていない or 「XXXX」の読み方も分かりづらいから載せてほしい。 
作者の技術の偏りが原因です。

この記事にコメントや下記にIssuesやPR頂ければ追加します。その時にはできれば読み方がわかるリンクがあるとありがたいです。

[Github Repository](https://github.com/doara-developer/pronunciation-dict)

#### 「XXXX」の読み方が違うんだけど。
私の知識不足なので教えてくださると助かります。
[iOS]純正アプリ ショートカットを使ってパスワード管理アプリを作ってみよう

# はじめに
みなさん iPhone アプリの`ショートカット`ってご存知ですか？
このアプリが結構便利で iPhone 上で色々できてしまうんです。
今回はこのショートカットアプリでできることを紹介しようと思います。

突然ですが、各種パスワードの管理ってどのようにしてます？
私は元々 iPhone のメモアプリで管理していました。
でも、これって各パスワードの検索がすごく大変なんですよね。
とはいえ、有料のパスワード管理アプリを使うのもなんか費用対効果が伴っていない気がしていました。
そこで、ショートカットアプリを使ってパスワード管理アプリを作れないか挑戦してみました。

このパスワード管理アプリ作成を通してショートカットアプリにできることの一部を紹介していきます。

# 構成
構成は以下のようになります。
各項目の概要を説明します。

- DB
- 検索入力フォーム
- 検索エンジン


##　DB
まずはアプリケーションの構成から紹介していきます。
パスワードを保存しておくデータベースですがこちらも iPhone のアプリケーションでかつ無料で再現したいですね。
ということで純正アプリの`メモ`を使用します。
どのようにデータベースを再現するのかは後術するのでお待ちください。

##　検索入力フォーム
今回はテキストでの曖昧検索を行えるようにします。
こちらは`ショートカット`アプリでテキスト入力が提供されるので簡単に実装できてしまいます。

##　検索エンジン
入力フォームで入力された文字列を使用してデータベースを検索します。
こちらも`ショートカット`アプリで実現できます。

#　ショートカットアプリとは
ここでショートカットアプリについて私のイメージに沿ってどんなことができるのか簡単に説明しておこうと思います。
私のイメージでは`ショートカット`アプリは iPhone 上で動く RPA　アプリケーションです。
iPhone にインストールされている各アプリケーションを繋ぎ各アプリケーション動作の間の手動作業を自動化することでより少ない動作で結果を得られるようにしてくれます。
例えばワンタップで特定の相手に LINE のメッセージを送ったりできちゃいます。
そして色々できると言った背景としては、この`ショートカット`アプリから Python で作成したアプリケーションを自動実行できるのです。
これで iPhone から自分のプログラムを実行できるようになります。
以上、一部ですが`ショートカット`アプリでできることを紹介しました。

次項から検索アプリの作成方法を紹介していきます。

#　アプリ作成
##　DB
まず、パウワードを管理する DB から作成していきます。
下記のイメージのようにメモアプリでフォルダを作成します。
その中にパスワード単位でテキストを作成します。
これで DB は完成です。
管理するパスワードが多いと初期設定の際に全てを登録するのが大変ですが、
一度作ってしまえば、あとはパスワードが増えるたびに1件づつ追加していけばいいので
メンテナンスはさほど大変ではありません。
![IMG_1291.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472784/4308fab3-8e97-cd85-ac97-e95e393c2e1c.png)

## 検索入力フォーム
次に検索のための入力フォームを作成していきます。
こちらはとても簡単です。
ショートカット作成画面の検索項目`Appおよびアクションを検索`に`入力を要求`と入れ検索します。
検索にヒットしたアクションを選択し、下記のイメージのようにテキスト入力を要求するように設定します。
再度、`Appおよびアクションを検索`から`変数を設定`を検索し、イメージのように設定します。
これで、入力フォームで入力した内容を`検索キーワード`という変数に保存するできるようになります。
![IMG_1289.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472784/82e9548b-ec97-4bd3-5543-79bf74359517.png)


結果、このような画面表示がされます。
検索のための入力フォームができましたね。
![IMG_1292.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472784/d9490812-0b1f-6b0c-0208-71c8696949ad.png)

## 検索エンジン
最後に検索エンジンを作成していきます。
まず、事前準備として検索対象フォルダ名をテキスト保存しておきます。
こちらは`Appおよびアクションを検索`に`メモの検索`と入力して出てきたテキストのアクションを使用し、
イメージのように設定してください。
ここで設定するフォルダ名は DB 作成の項目で作成したフォルダになります。
![PNGイメージ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472784/08326123-a36e-9c60-79f5-3e139ddb9f29.png)

次にショートカット作成画面の検索項目`Appおよびアクションを検索`に`メモを検索`と入力します。
でてきたアクションを選択し、イメージのように設定します。
これで検索エンジンの完成です。

![IMG_1290.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472784/53e9af6c-a568-c134-ec14-eaae69ff4d8d.png)

最後に`Appおよびアクションを検索`に`メモの表示`と入力して出てきたアクションを使用し、
検索結果の表示を行います。

# 動作確認
出来上がったアプリをデスクトップに表示し、動作確認を行います。
入力フォームに`サンプル`と入力し、タイトル`サンプル`のパスワードを表示します。
動作結果は以下のイメージのようになりました。
うまく検索できましたね。
![IMG_1294.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472784/11d991f4-17c8-9d06-862c-2ebac2dc1148.png)
![IMG_1295.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472784/80cbd92e-41f7-7f43-dc8a-f7a57ec09452.png)

# 終わりに
いかがでしたでしょうか？
今回はパスワード管理アプリの作成を通してショートカットアプリを紹介しました。
このアプリ初期から入ってるけどなんのために使うの？
とか思っていた方もいるかと思いますが、こんな感じに使います。
操作も直感的で難しすぎないと思っています。
ショートカットを使えばもうちょっとこうだったらいいのにが実現できます。
ぜひショートカットアプリを使用して色々なことを試してみてください。
マテリアルなUIを単独で使用する方法

# はじめに
マテリアルなUIがかなり浸透してきていて、画像を丸く表示する為のShapeableImageViewや、枠などを設定できるMaterialCardViewなどを使用したいケースが多くなってきていますよね。
UIに枠や角丸をつけたいが故に、Drawableを大量生産している、、、歴史のあるプロジェクトではよく見かける例な気がします。
そんな時に、単独でマテリアルなUIを使用したいと思っても、基本はstyleから変えなければならず改修範囲が広く使えない、そんな経験あるのではないでしょうか？

もしかしたらご存知の方も多いのかもしれませんが、styleを変更しなくてもマテリアルなUIを使用できる方法がありますので、ご紹介しようと思います。

# 設定内容

設定は非常に簡単です。
対象のマテリアルなUI、もしくは親のレイアウトに以下を付与するだけです。

```
android:theme="@style/Theme.MaterialComponents"
```

上記を設定する事で、本来styleのparentにMaterialの設定を行わなければならない所を上記設定のみでマテリアルなUIを使用できます。

# さいごに
本来はparentにMaterialComponents.Lightなどを設定して、もっと大きなレイヤーでマテリアルなUIに対応する、、、これが正しい気はしていますが、これにかかるコストや影響範囲などを考えると全てのプロジェクトで対応するのはハードルが高い気がしています。
そんな時にはこの対応も選択肢に入れてもらうと良いかもしれません。
ECS Fargateハンズオン

ハンズオンは[こちら](https://catalog.us-east-1.prod.workshops.aws/v2/workshops/a2b9971a-7a6e-40f3-96e7-5a04b46d1f98/ja-JP/0-introduction)

以下のようなアーキテクチャで実装されます
![スクリーンショット 2022-02-05 17.15.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933058/94908a00-5cca-c137-0176-beead17fe449.png)

#ECSとは？
クラスターでコンテナの実行、停止、管理を簡単に行うことのできる、高度にスケーラブルで高速なコンテナ管理サービス。

クラスター
タスクまたはサービスの論理グループ


タスク定義
アプリを構成する一つ以上のコンテナを記述するJSON形式のファイル

ECRのイメージからコンテナを起動する
#Fargateとは？

クラスター
サービス
タスク→Fargate
コンテナ

https://pages.awscloud.com/rs/112-TZM-766/images/AWS_CICD_ECS_Handson.pdf


#ECRとは
Docker hubのAWSバージョン
ECRにリポジトリを作成
ECRにDockerイメージを登録
登録したイメージをECSで使用する
Webの勉強はじめてみた その30 〜GitHub認証とテスティングフレームワーク〜

N予備校「プログラミング入門Webアプリ」を受講しています。
今回は第4章4〜6節です。

## GitHub認証
GitHub上のログインの認証機能を、自分が開発するアプリケーションに利用する。

### OAuth の利用
その前に認可と認証について

:::note
アプリケーションの利用者が第三者のアプリケーションに権限を与えることで、 そのアプリケーションの機能や認証を第三者のアプリケーションでも利用できるようにする仕組み
:::

`OAuth2.0`は認証済みユーザーに対して権限を与える、認可のためのプロトコル。

```
user => github => website => user
     認証      認可        ログイン
```

なんとなくこんな感じだろうか。

### ストラテジーモジュール
必要なものだけをインストールできるように部品に分けたモジュール。
今回はGitHubなので、`passport`の他に、`passport-github`, `express`内でログイン情報をセッション管理するための、`express-session`ライブラリを一緒にインストール。

```javascript
// OAuth
const session = require('express-session');
const passport = require('passport');
const GitHubStrategy = require('passport-github2').Strategy;
// GitHub Token
const GITHUB_CLIENT_ID ='xxxxxxxx';
const GITHUB_CLIENT_SECRET = 'xxxxxxxxxxxx';
// Passport の設定
passport.serializeUser(function(user, done){
  done(null, user);
});
passport.deserializeUser(function(obj, done){
  done(null, obj);
})
// Passport の登録
passport.use(new GitHubStrategy({
  clientID: GITHUB_CLIENT_ID,
  clientSecret: GITHUB_CLIENT_SECRET,
  callbackURL: 'http://localhost:8000/auth/github/callback'
},
  function(accessToken, refreshToken, profile, done){
    // 非同期で実行する
    process.nextTick(function(){
      return done(null, profile);
    });
  }
))

// Sessionを利用する
app.use(session(
  { 
    // Secret Key
    secret: 'xxxxxxxx',
    // セッションを保存しない
    resave: false,
    // 初期化時にセッションを保存しない
    saveUninitialized: false
  }
));

app.use(passport.initialize());
app.use(passport.session());

// /auth/github にアクセスがあった場合
app.get('/auth/github',
  // GitHub ログイン画面へジャンプ
  passport.authenticate('github', {
    // GitHub上のユーザー名とアドレスを使って認可する
    scope: ['user:email']
  }),
  function(req, res){    
    // ログを出力したいときはここに処理をかく
  }
);
// Callback
app.get('/auth/github/callback',
  passport.authenticate('github', {
    // 認可失敗の場合 ログイン
    failureRedirect: '/login'
  }),
  function (req, res){
    // 認可成功の場合 トップページへ
    res.redirect('/');
  }
)
// ログイン
app.get('/login', function(req, res){
  res.render('login');
})
// ログアウト
app.get('/logout', function(req, res){
  req.logout();
  res.redirect('/');
})
```

## テスティングフレームワーク
テストについて

:::note
ユニットテスト: モジュール単体をテストする
結合テスト: 複数のモジュールを結合して機能をテストする
システムテスト: システム全体が正しく動くことをテストする
:::

### Jest を使う
`Node.js`上でテストの実行結果を集計して、わかりやすく表示してくれる。

```
yarn add jest@25.1.0 --dev
```

`--dev`: 開発時のみ利用するライブラリを`package.json`に記述しつつインストールする。

#### npx
ローカルにインストールされたモジュールを直接実行できる。

```
node node_modules/.bin/jest -h
```

が、

```
npx jest -h
```

になる。

```javascript
// 一つ上の階層のindex.jsをimport
const dc = require('../');
// テストのカテゴリ分け
describe('#effectiveDamage()', () => {
  // 1つのテストにテキストで意味をつける
  test('正常なダメージ計算ができる', () => {
    // 実際にテストする内容
    expect(dc.effectiveDamage(100, 50, 30)).toBe(83);
  });
  
  test('負の異常値におけるダメージ計算ができる', () => {
    expect(dc.effectiveDamage(-1, 0, 0)).toBe(0);
    expect(dc.effectiveDamage(0, -1, 0)).toBe(0);
    expect(dc.effectiveDamage(0, 0, -1)).toBe(0);
  });
});
```

## まとめ
テストの大切さ、とは言いつつ実際経験しないと手順とか、勉強だけではわからない部分が増えてきた印象。そろそろこれまでの部分をまとめたい。
dockerでifcopenshell環境を構築する

# 課題

- IFCファイルをifcopenshellで操作したい
- pc内の環境を汚したくない（環境構築がめんどくさい）

以上の理由より、Dockerを使ったifcopenshellの環境構築を行いたいと考えた。しかし、検索してもそれらしい記事が見つからなかったため、備忘録として残す。

また今回の方法は、windows11、macos10.15(Catalina)において動作確認済み。

# 方法

## 事前準備

- [docker desktop](https://www.docker.com/products/docker-desktop)をインストールする

## 環境構築

任意のディレクトリ内にdocker-compose.ymlとDockerfileを作成する

#### docker-compose.yml
```yml
version: '3.8'
services:
  ifc_os:
    container_name: ifc-os
    build:
      context: .
      dockerfile: ./Dockerfile
    volumes:
      - ./:/code
    ports:
      - "8000:8000"
    tty: true
```

#### Dockerfile

```docker
FROM continuumio/miniconda3

ENV APP_PATH=/code \
    PYTHONPATH=.
#　開発物のソースコードはcodeデイレクトリ下に配置する

RUN conda create -n ifcos python==3.8

SHELL ["conda", "run", "-n", "ifcos", "/bin/bash", "-c"]
RUN conda install -c conda-forge -c oce -c dlr-sc -c ifcopenshell ifcopenshell

WORKDIR $APP_PATH

EXPOSE 8000
```

## 実行

```bash

cd {docker=compose.ymlとDockerfileがあるディレクトリに移動}

docker-compose up -d
```

以上でifcopenshellをインストールしたdocker環境が立ち上がる

# 課題点など

- conda環境を介した方法で構築したが、linux環境でifcopenshellをインストールできる方法があればそちらの方が良いかもしれない。
AWS DeepRacer 日記 2022/1 (今月はエラー解決がメインになりました)

AWS DeepRacer 日記 2022/1

2021年10月から本格的にDeepRacerリーグに参加し始めました。
今回はDeepRacer日記第3回です。
筆者の試行錯誤を記載していきます。
参考になればうれしいです。

※DeepRacer参加方法については下記にまとめています

https://qiita.com/toma_shohei/items/a79abd8d71a2e284273f

## 1/17

前回（12/6）Learning late（学習レート）を最大値の0.001に変更したが、学習が収束しなかった。

↓前回記事

https://qiita.com/toma_shohei/items/9d56e89c3a593a0eb353#126


最大値を0.0007に変更して収束するか試す。

トレーニングに失敗(初)
「Unable to complete training. You can still evaluate the model that's trained up to the failure.」
![スクリーンショット 2022-01-28 221950.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311339/d98c2352-012c-0844-7647-11783e92b5c4.jpeg)

この状態で一旦評価をしてみる。
評価は上々で2周を100%
（1周は急カーブのところでコースアウト）

![スクリーンショット 2022-01-18 084953.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311339/daab7e0d-16c2-b121-2e86-9d556fdd3553.jpeg)

この日はエラー原因は分からず。。

## 1/24
1/15でre:Invent 2021 Open Raceが終わっていたので、エラーになった理由は置いておいて、
新たに開催されていた2022 Pre-season向けに新たにモデル作成しなおすことに。

2022 Pre-seasonで利用されるVivalas Speedwayはカーブが多い難コース

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311339/54e16e3c-dfc1-7fac-0c4e-4a8279282abd.png)


下記資料参考にハイパラ検討する。

https://www.dnp-ds.co.jp/tech_fun/pdf/tech_fun_007_1.pdf

「バッチサイズ、エポック数、エピソード数は最初に大きな値を設定した」
↑この一文を参考にしてみる

:::note info
・バッチサイズ大→安定するがトレーニングが長くなる
・エポック数大→安定するがトレーニングが長くなる
・エピソード数大→安定するがトレーニングが長くなる
:::

※ハイパーパラメータチューニングについては下記の記事にまとめています。

https://qiita.com/toma_shohei/items/54367c179ac4c927f7aa

最初は安定志向の方が良いとのことだと理解しつつ、一旦下記の値に変更して試すことにする。

``` A:学習パラメータ
バッチサイズ　64→128
エポック数　10→10（デフォルト最大なのでそのまま）
エピソード数　20→40（推奨される値は10、20 および 40 ）
Maximum Speedは1から2に変更
※カーブが多いコースなのでMinimumSpeedは0.5のまま
```

## 1/28
またエラーになった。学習開始とほぼ同時にエラーになっており、ほとんど学習が進んでいないモデルが作成された。。

トレーニングログを確認
![スクリーンショット 2022-01-28 222357.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311339/264ed1e5-ba12-a9db-f3da-3062cdccde5f.jpeg)

報酬が1e5を超えていた模様。（※報酬が「107,998」でエラーになっている。）
※1e5＝10万
※前回エラー時も軽くログは見ていたが、気づけなかった。。

原因を調査する必要あり。ハイパーパラメータ変えるまでは起きなかった挙動。

## 1/31
報酬関数は初期のころから下記を利用させて頂いている。

https://github.com/VilemR/AWS_DeepRacer/blob/master/reward_function.py

この報酬関数は「900,000」（90万）を超えないように考慮がされているが、これは9万の間違いっぽい。。

![スクリーンショット 2022-02-13 151820.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311339/e443b0b3-18cb-0ae4-c933-a39e0ad74b4d.jpeg)

900,000の部分を90,000に修正

        # Finally - check reward value does not exceed maximum value
        if result_reward > 90000:
            result_reward = 90000

再度安定志向のハイパーパラメータで試したところ、エラー解消できた。（学習結果は来月以降確認。）

``` A:学習パラメータ
コース：VivalasSpeedway
バッチサイズ　64→128
エポック数　10→10（デフォルト最大なのでそのまま）
エピソード数　20→40（推奨される値は10、20 および 40 ）
MinimumSpeed 0.5→1
Maximu speed 1→2
学習時間 120分
```

## まとめ
今月はハイパーパラメータチューニングについて知見を溜めていく予定だったが、
エラー対応に追われて大きな進捗はなかった。
改めてエラーログをよく見るという基本動作の大事さには気づけた。
AWS CLIの振り返り ~ACM入門編~

#本記事の目的
JAWS-UG CLI オンラインハンズオンの復習として、ハンズオンで取り上げられたAWSサービスに関する用語と、使用したAWS CLI コマンドを箇条書きでまとめる。
今回はACM入門編を取り上げる。

#主なAWSサービス用語
####ACM証明書
ACMで発行されるSSL証明書。

####ドメイン認証
SSL証明書をリクエストしているドメインの所有権を確認する事。

#主なAWS CLI コマンド一覧
####ACM証明書の要求
```
aws acm request-certificate \
  --domain-name ${ACM_DOMAIN_NAME} \
  --validation-method ${ACM_VALIDATION_METHOD}
```
|オプション|引数|必須/任意|備考|
|---|---|---|---|
|--domain-name|ドメイン名|必須||
|--validation-method|ドメイン認証方法|任意|引数に`DNS`を指定する事で、DNSレコードを使用してドメイン認証を実施する。|

####ACM証明書の一覧表示
```
aws acm list-certificates
```

####ACM証明書の詳細表示
```
aws acm describe-certificate \
    --certificate-arn ${ACM_CERTIFICATE_ARN}
```
|オプション|引数|必須/任意|備考|
|---|---|---|---|
|--certificate-arn|ACM証明書ARN|必須||

####ACM証明書の削除
```
aws acm delete-certificate \
  --certificate-arn ${ACM_CERTIFICATE_ARN}
```
|オプション|引数|必須/任意|備考|
|---|---|---|---|
|--certificate-arn|ACM証明書ARN|必須||

####ACM証明書へのタグ追加
```
aws acm add-tags-to-certificate \
  --certificate-arn ${ACM_CERTIFICATE_ARN} \
  --tags ${STRING_TAG_CONF_ACM}
```
|オプション|引数|必須/任意|備考|
|---|---|---|---|
|--certificate-arn|ACM証明書ARN|必須||
|--tags|タグ文字列|必須|引数の例：`"Key=<タグのキー名>,Value=<タグの値>"`|

####ACM証明書のタグ表示
```
aws acm list-tags-for-certificate \
  --certificate-arn ${ACM_CERTIFICATE_ARN}
```
|オプション|引数|必須/任意|備考|
|---|---|---|---|
|--certificate-arn|ACM証明書ARN|必須||
※`list-certificates`コマンドはタグ表示ができない。そのため同名の証明書が複数ある場合、全ての証明書に対して`list-tags-for-certificate`コマンドでタグの有無をチェックする必要がある。


#参考文献
- AWSCLIコマンドリファレンス:[ACM](https://docs.aws.amazon.com/cli/latest/reference/acm/index.html)
- JAWS-UG CLI専門支部：[ハンズオン(簡易版): ACM入門](http://prototype-handson-cli.s3-website-ap-northeast-1.amazonaws.com/handson_light-aws_service/handson_light-aws_service-acm-novice/index.html)
wasm-packインストール時にno precompiled binaries available for CPU architecture: arm64と言われた

※2021/02/13現在の情報です

エラーメッセージそのままですが、
以下ページにて記載されているインストールコマンドを実行するとM1 Macだとインストールできませんと言われてしまいました。

https://rustwasm.github.io/wasm-pack/installer/

```shell
> curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
wasm-pack-init: no precompiled binaries available for CPU architecture: arm64
```

以下コマンドでインストールをおこないます。

```
cargo install wasm-pack
```
Python マルチな処理で悩んだときにみる スレッド？プロセス？


# 結論

CPUリソースを最大限に使って君のために命かけるん！

 →**マルチプロセス**

大雑把に書けて楽。リソース管理も不要。アプリケーションにマルチコアマシンの計算能力をより良く利用させたい場合は絶対にマルチプロセス。

----

CPUリソースを食われるのだけは嫌！だって、そんなに大事なことじゃないだもん！だけど、マルチな処理がさせたいん！

→**マルチスレッド**

リソース管理が面倒。I/Oバウンドなタスクを並行して複数走らせたい場合においては、 マルチスレッドはベストな選択。

# Python

JavaやCなどの一部の言語は、タスクを複数のCPUに同時に自動的に送信します。

しかし、Pythonでは、

**各プロセスはシングルコアで実行されるため、同じプロセスの複数のスレッドが同じコアで実行される**


`これPythonでマルチな処理を行う上で最も重要なので覚える`


# プログラムの粒度

タスク <= プロセス < マルチスレッド < マルチプロセス

 の順で大きくなる


# プロセス

例) 
ブラウザ、ワード、VSCodeなどのプログラム全体のこと


# マルチプロセス(並列処理)

複数のCPUコアを使って複数のプロセスを実行すること

**並列回路をイメージする**
→ イメージのまま同時にプロセスが行われる

**メモリ**
プロセスごとに独立

**例)**
ブラウザ、ワード、VSCodeなどのマルチスレッディングなプロセスを同時に使うときにOSが各プロセスを超高速に切り替えて動作している


# マルチスレッド(並行処理)

単一のCPUコアを使って、１つのプロセスを分割して複数のタスクを実行すること

**直列回路をイメージする**
→ 並列処理のようにみせかけること。１本の路をバトンリレーしながらタスクが行われている。

**メモリ**
複数のタスク(スレッド)が１つのメモリを共有
→ リソースとメモリを管理する必要がある
 
**例)**
テレビゲームでは、BGMが再生され、グラフィックが変化し、ユーザの入力を取得するなど、それぞれを別スレッドに分けで`同時並行`に実行されている




# 図で表すと

参考
https://ichi.pro/python-de-no-maruchitasuku-116855511813169

## マルチプロセス

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282788/aca595c9-6108-8b14-1f9d-5d2fff8b7a99.png)

## マルチスレッド

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282788/2521cb2c-3540-e3a6-9930-49a09c7ba2e8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282788/45fd9d99-533e-2946-96f5-06575dea0466.png)
Windows10/初期設定

##CapsLockとCtrlの入れ替え
言わずもがな。
[ctrl2cap](https://docs.microsoft.com/en-us/sysinternals/downloads/ctrl2cap)をDL、解凍後に管理者権限でコマンドプロンプトにて"ctrl2cap /install"を実行し再起動。

##Alt-Tab を押したときにサムネイル表示をしないようにする
レジストリエディター(win+r, regedit)で以下を編集

|パス|キー|バリュー|
| :-- | :-: | --: |
|HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer|AltTabSettings|1|

##タスクバーのプレビューをやめる
レジストリエディター(win+r, regedit)で以下を編集
完全にプレビューを非表示にすることは出来ないため、オンカーソルしてからプレビュー表示までの時間を60000(msec)に設定しあたかも非表示になったかのように振る舞わせる

|パス|キー|バリュー|
| :-- | :-: | --: |
|\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced|ExtendedUIHoverTime|60000|

##ライブサムネイルをやめてリスト表示にする
レジストリエディター(win+r, regedit)で以下を編集
タスクバーの実行中アプリにカーソルを合わせるとウィンドウの小さなサムネイルプレビューが表示される、それをライブサムネイルと言うらしい。

|パス|キー|バリュー|
| :-- | :-: | --: |
|HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Taskband|NumThumbnails|0|

##タスクバーの検索ボックスでWeb検索をやめる
gpedit.mscを開いて、コンピューターの構成 > 管理用テンプレート > Windows コンポーネント > 検索 > Web検索したりしないを有効化

##エクスプローラーの今日とか先週とかのグルーピングをやめる
エクスプローラー > 表示 > グループ化 > (なし)

##日本語入力時の予測変換をやめる
タスクバーの[あ(A)]を右クリック > 設定 > 全般 > 予測入力 > オフ

##文字切替をしたときに画面中央に出てくるあれを消す
プログラマのためのキャンプ特集（準備中）

野球選手にはキャンプがあるのに、エンジニアにはキャンプがないのはなぜ？
https://qiita.com/soepy/items/1ccb386eab3610a6b3d7

プログラマには、さまざまなキャンプがあります。知らない人がまだいたんだと思い、広報不足を嘆き、記事を書き始めました。

温泉旅館などに泊まり込んで、一日中プログラミングなどをする会合を、ここでのプログラミングキャンプに分類します。

# IPA セキュリティキャンプ
https://www.ipa.go.jp/jinzai/camp/index.html

「セキュリティキャンプ」そんな素敵な
https://qiita.com/kaizen_nagoya/items/7c94180fb0415ef83f4d

TOPPERS開発者会議
https://www.toppers.jp/devconf2021.html

SWEST
https://swest.toppers.jp/about/

WWEST
SWESTの実行委員が、冬に集まる会合。
その年の夏の企画のお試し版を実行するのが一番の目的。
SWESTの実行委員になると案内が来る。

# 今はない企画
## JUNET合宿
インタネットを最初に個人、組織で連携するためのJUNETが主催した温泉旅館での一泊の会合。

名古屋地区では、最初に名古屋に拠点を設けた方のご実家が旅館だったらしいこともあり、名古屋で単独で合宿を開いたような気がする。

## ６ヶ月研修
公的試験研究機関の職員が、３ヶ月は中小企業大学校、３ヶ月は現在の産業総合研究所に研究生として、短期留学する制度。

私の場合は、中小企業大学校では、「デザイナ指導者養成講座」を、各地のデザイン部門の方々と一緒に参加した。電総研には言語システム研究室に３ヶ月居候し、OBJという抽象データ型言語のシンタックスチェッカを作り、SEAで発表した。

# プログラマ向け合宿を企画している宿など
企業の研修所をお借りして、実施したこともあります。

三菱電機、Denso、横浜ゴム、KDD、SCSKなどです。
その企業の方が参加する場合と、主催がその企業が加入している団体の場合と、当該企業の顧客企業・団体が主催する場合など、ありとあらゆる手段を通じて実施させていただきました。

合宿型行事は５０回ほど主催者側で作業またはお手伝いさせていただいています。

当初は単なる参加者で参加しても、現地でネットワークの敷設、ルータの調整、Wi-Fiの試験、ソフトウェアのインストールから、電話のモジュラージャックへの変換などの工事（アナログ１種・デジタル１種電話工事担任者）などもさせていただいています。ありがとうございます。プログラマとしては２流でも、インフラエンジニアとしては、いつでもどこでもお役に立てることを心がけるようにしています。
プロジェクタのコネクタの変換機器、プロジェクタの設定の変更などはあまり得意ではありません。

##湯河原
https://www.onyadomegumi.co.jp

## 葉山

https://www.shonan-village.co.jp

## 熱海

【熱海で開発合宿】温泉も楽しめてネット環境が整ったおすすめ宿6選

https://work-hub.gobanchi.com/training_camp_atami/

【静岡】研修合宿・セミナーでも使える会議室のある熱海のホテル＆旅館５選

https://www.travelbook.co.jp/topic/5789
## 修善寺

場所を検索中です。

## 浜名湖

現在は、該当施設は営業していないような気がします。

## 豊橋・愛知県

駅から近くのホテル。

## 犬山・愛知県

池のほとりのホテル（旅館）

## 北陸・石川県

なんどか、温泉旅館で行事を開催させていただきました。

小松から金沢の間の、どの駅にも温泉旅館がある感じで驚いた記憶があります。

## 御座・三重県

名工大の研究室の合宿で利用しました。

# 参考資料

私のAdvent Calendar 2022 ーー はじめたきっかけ、1月のふりかえり、今後の展望

https://qiita.com/torifukukaiou/items/891db4e40a7f6194af56

## 自己参照

今、AdventCalendar2021を書いている理由

https://qiita.com/kaizen_nagoya/items/dca73e903785bea2a106
【Laravel8】アセットファイルの読み込みに認証を通す方法

# 概要
Laravelではapp/storageへstoreAsメソッドなどでファイルを保存することができます。保存したファイルへのアクセスは、ファイルが保存されているディレクトリへのシンボリックリンクを貼り、パスを入力することで容易にできます。
例：app/storage/thumbnailにkuma.jpegを保存
![スクリーンショット 2022-02-13 13.55.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637441/459b4adf-84a5-06cd-2ee1-e9eb111bc8fa.png)

```php:config/filesystems.php
    'links' => [
        public_path('storage') => storage_path('app/public'),
        public_path('thumbnail') => storage_path('app/thumbnail'), //追加
    ],
```

```
http://localhost:8000/thumbnail/kuma.jpeg
```

しかし会員制サイトの場合、外部のユーザーがURLを入力するだけでファイルへアクセスできることは望ましくありません。
今回は非認証ユーザーからのアクセスはログイン画面へリダイレクトし、認証済みユーザーのみがアクセスできるようにする方法を備忘録としてまとめます。

# 結論

```php:route.php
Route::middleware('auth:user')->group(function () {
    // (略)
    Route::get('{file}/{any}', [AuthFileController::class, 'getFile'])
        ->where(['file' => 'pdf_file|thumbnail', 'any' => '.*'])
        ->name('auth.file');
    // (略)
});
```

```php:AuthFileController.php
class AuthFileController extends Controller
{
    public function getAssetFile($file, $any)
    {
        // ファイルの存在を判定
        if(Storage::disk("local")->exists($file."/".$any)) {
            // storage/app下のファイルを返す
            return response()->file(Storage::path($file."/".$any));
        } else {
            // 404エラーの送信
            abort(404);
        }
    }
}
```

# 詳細
### route.php
middlewareのgroupメソッド内に追加することで、ファイルへのアクセスパスに認証を通すことができます。

```php:route.php
Route::middleware('auth:user')->group(function () {
```

### whereメソッド

```php:route.php
Route::get('{file}/{any}', [AuthFileController::class, 'getFile'])
            ->where(['file' => 'pdf_file|thumbnail', 'any' => '.*'])
            ->name('auth.file');
```
whereメソッドによって、{file}に入るルートパラメータの制約条件を追加することができます。この指定により、任意のファイルへのアクセスに認証を通す事ができます。今回の例ではstorage/thumbnailへのファイルと、storage/pdf_fileへのアクセスに認証を追加しています。
[正規表現の制約](https://readouble.com/laravel/8.x/ja/routing.html#:~:text=%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE%E3%81%AE-,%E5%88%B6%E7%B4%84,-%E3%83%AB%E3%83%BC%E3%83%88%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E3%81%AE)

他のファイルへの認証を追加する場合、whereメソッドのルートパラメータへの追加と、シンボリックの追加のみで対応できます。


### AuthFileController.php
こちらは今回の本筋とは少しずれますが、ルートパラメータからファイルの存在を確認し、なければ404エラーを返すようにしています。こちらは状況に応じてカスタマイズが必要な箇所だと思います。


# まとめ
ファイルへのアクセス認証をまとめました。会員制サイトの制作に携わることがこれからも多そうなので、もし次同様のケースがあれば適用できればと思います。
[Delphi] Windows11 の角丸ウィンドウを抑止する

# Windows11 の角丸ウィンドウ

Windows 11 から下図の様にウィンドウが角丸になるようになりました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12977/8e19823c-00d5-b2ec-48c4-c7d7df4fd41e.png" width=400>

でも！
それでは困る場合もあります。
ということで、Windows 11 で角丸ウィンドウを抑止する方法です。

# 角丸ウィンドウの抑止

[DwmSetWindowAttribute](https://docs.microsoft.com/ja-jp/windows/win32/api/dwmapi/nf-dwmapi-dwmsetwindowattribute) API を使います。
DwmSetWindowAttribute の第二引数に属性を指定するのですが Windows 11 から [DWMWA_WINDOW_CORNER_PREFERENCE](https://docs.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute) という属性が増えています。
この属性と第三引数に以下の値を設定するとウィンドウの角丸を制御出来ます。

|名前|値|説明|
|---|---|---|
|DWMWCP_DEFAULT|0|システムの設定に従う|
|DWMWCP_DONOTROUND|1|角を丸くしない|
|DWMWCP_ROUND|2|角丸|
|DWMWCP_ROUNDSMALL|3|小さな角丸|

角を丸めないのであれば ```DWMWCP_DONOTROUND``` を指定すれば良い、ということですね。

ということで、これを実装したソースはこちら。
FireMonkey 用ですが、VCL 用も簡単に作れると思います。

```pascal
(*
 * WindowCorner を変更出来る関数
 *
 * PLATFORMS
 *   Windows 11
 *
 * ENVIRONMENT
 *   Delphi 10.4.2, 11
 *
 * LICENSE
 *   Copyright (c) 2021 HOSOKAWA Jun
 *   Released under the MIT license
 *   http://opensource.org/licenses/mit-license.php
 *
 * HISTORY
 *   2021/09/24 Version 1.0.0
 *
 * Programmed by HOSOKAWA Jun (twitter: @pik)
 *)

unit PK.GUI.WindowCornerRound.Win;

interface

uses
  FMX.Forms;

type
  TCornerRound = (
    Default,    // DWMWCP_DEFAULT    = 0  システムの設定に従う
    DoNotRound, // DWMWCP_DONOTROUND = 1  角を丸くしない
    Round,      // DWMWCP_ROUND      = 2  角丸
    RoundSmall  // DWMWCP_ROUNDSMALL = 3  小さな角丸
  );

function SetWindowCornerRound(
  const AForm: TCommonCustomForm;
  const ACornerRound: TCornerRound): Boolean;

implementation

{$IFDEF MSWINDOWS}
uses
  Winapi.Windows
  , Winapi.DwmApi
  , FMX.Platform.Win
  ;

const
  DWMWA_WINDOW_CORNER_PREFERENCE = 33; // Windows 11 で追加された角丸属性

function SetWindowCornerRound(
  const AForm: TCommonCustomForm;
  const ACornerRound: TCornerRound): Boolean;
begin
  var CornerRound: DWORD := Ord(ACornerRound);

  // Windows 11 より前では常に False
  Result := Succeeded(
    DwmSetWindowAttribute(
      FormToHWND(AForm),
      DWMWA_WINDOW_CORNER_PREFERENCE,
      @CornerRound,
      SizeOf(CornerRound)
    )
  );
end;
{$ELSE}
function SetWindowCornerRound(
  const AForm: TCommonCustomForm;
  const ACornerRound: TCornerRound): Boolean;
begin
  Result := True;
end;
{$ENDIF}

end.
```
使い方は↓こんな感じで呼び出すだけ。

```pascal
uses
  PK.GUI.WindowCornerRound.Win;

procedure TForm1.FormCreate(Sender: TObject);
begin
  SetWindowCornerRound(Self, TCornerRound.DoNotRound);
end;
```

# おわりに
もうみんな知ってる事を今更書いた。
なお、詳しくは MSDN の下記の記事をどうぞ。

[Windows 11 向けデスクトップ アプリケーションで角の丸めを適用する](https://docs.microsoft.com/ja-jp/windows/apps/desktop/modernize/apply-rounded-corners)
DEBUG|output[{"message":"Access from current IP address is not allowed","errorCode":"INSUFFICIENT_ACCESS"}]

IP範囲をホワイトリストに登録すると解決したようです。

[DEBUG|output[{"message":"Access from current IP address is not allowed","errorCode":"INSUFFICIENT_ACCESS"}]](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000EBjoA)
ブルーグリーンデプロイ とは

## 勉強前イメージ

新しい環境を用意してパっと切り替えるリリース？

## 調査

### ブルーグリーンデプロイ とは

旧環境をブルー環境、新環境をグリーン環境として
LBの接続先を切り替えるなどして新環境を本番にリリースすることを言います。
イメージとしては以下になります。

![12022-02-13 # ブルーグリーンデプロイ とは - diagrams.net - Googl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/f751c99b-e574-c96f-c7f5-ee826de7eaa9.png)


### メリデメ

#### メリット

- リリース時のダウンタイムを短くできる

どちらの環境も動いていて、あるポイントの切替だけでリリースができるので再起動など不要。
できるだけダウンタイムを短くできる

- 切り戻しも可能

旧環境が動いた状態で新環境への移行を行うので
もし問題が発生した際もポイントの切替をもとに戻すだけで切り戻しが環境、もとに戻すことができます。

#### デメリット

- 新環境と旧環境で運用コストが必要

新環境、旧環境どちらもお客様がのっても大丈夫な環境にしているので
コストが純粋に考えて2倍程度に膨らみます。

### カナリアリリースとの違い

メリデメを見てたら、ほぼ [カナリアリリース](https://qiita.com/miyuki_samitani/items/e543b7d11af9b1979fc2) と一緒では？というとこがありますが、
カナリアリリースとの違いは以下になります。

実はカナリアリリースはブルーグリーンデプロイの一種で、
ブルーグリーンデプロイに一部お客様だけリリースを行いテストの工程を追加したのがカナリアリリースです。
ブルーグリーンデプロイには切り替えによりリリースを行いますが、テストの工程は含まれていません。

## 勉強後イメージ

ブルーングリーンデプロイやと思ってたw
雰囲気は合ってたけど、ちゃんとした言葉で言えなかったから調べられてよかった。
あとブルー環境とグリーン環境、知らなかった。

## 参考

- [ブルーグリーン・デプロイメントとは](https://www.redhat.com/ja/topics/devops/what-is-blue-green-deployment#:~:text=%E3%83%96%E3%83%AB%E3%83%BC%E3%82%B0%E3%83%AA%E3%83%BC%E3%83%B3%E3%83%BB%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4%E3%83%A1%E3%83%B3%E3%83%88%E3%81%AF%E3%80%81%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC,%E7%92%B0%E5%A2%83%E3%81%A8%E5%91%BC%E3%81%B0%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82)
- [カナリアリリースとは？ブルーグリーンデプロイメントとの違いや実施方法を紹介](https://www.sedesign.co.jp/dxinsight/what-is-canary-release)
- [3分でわかる ブルーグリーンデプロイメント](https://xtech.nikkei.com/atcl/nxt/keyword/18/00002/070800077/)
SQLのDECODEについて

ものすごく久しぶりの記事になってしまった。
いまの現場ではSQLを使用する機会が多いので、今回はすぐに使い方を忘れるDECODEについて説明しようと思います。
DECODEはJavaでいうIF文のようなもので、条件分岐によって値を変換させることができます。

|Code|Name|Result|
|:-----|:-----|:-----|
|01|田中|1|
|02|鈴木|2|
|03|中村||
|04|山崎|1|

今回は上記のテーブルを使用します。
名前と、テストの評価結果を格納しているテーブルです。
また、DECODE関数は以下の形式で使用します。

```ruby:DECODE
DECODE(列名, 値1, 結果1, 値2, 結果2, 結果3)
```

実際にSQLに組み込むと以下のようになります。

```ruby:SQL
SELECT
    Code,
    Name,
    DECODE(Result, 1, '合格', 2, '不合格', '審査中') AS Result
FROM
    TABLE1;
```

上記のSQLの実行結果は、以下のようになります。

|Code|Name|Result|
|:-----|:-----|:-----|
|01|田中|合格|
|02|鈴木|不合格|
|03|中村|審査中|
|04|山崎|合格|

このように、Resultが1の場合は「合格」に変換、2の場合は「不合格」に変換、それ以外の場合は「審査中」に変換……といったことがDECODEではできます。
意外と使う機会が多いので、きちんと覚えておいた方がいい関数です。
ラムダ式って美味しいの？って思ってる方でもわかるラムダ式の解説

#はじめに
ラムダ式を理解するのって初心者にとっては難しいですよね。
僕も理解するのに苦労しました。
今回は初心者の方でも分かるようにラムダ式をまとめました。
この記事が皆さんのお役に立てれば幸いです。
##ラムダ式とは？
メソッドを一つしかもたないインターフェイスの実装とインスタンス生成が同時に作成できる文法のことを言います。
要するにラムダ式は、クラス宣言とインスタンス生成がが同時にできるってことです。

:::note info
メソッドを一つしか持たないインタフェースのことを関数型インターフェイスと言います。
:::

#どのように使うの？
サンプルコードを通して使い方を説明していきます。
###構文
最初はその場で名前のないメソッドを作るようなイメージでいいと思います。

```
構文
（引数）　->{処理}
```
###サンプルコード
例えば、モンスターというインターフェイスを作ろうとします。
このモンスターはlevelが１なので、１つしか技を持っていません。
しかも、技名だけであり、未完成です。

<p align="center">
<img width="200" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526916/6b2c4747-2cca-73fc-2fbc-38cc834a5465.png"/>
</p>

```Monstor.java
public interface Monster {
 void infection();
}
```
そこで、トレーナがやってきました。
トレーナは未完成の技をこのモンスターに覚えさせます。
<p align="center">
<img width="200" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526916/e2544d4e-5c6a-f9a4-7d8b-e5b7e4ba4fcf.png"/>
</p>

```Trainer.java
public class Trainer  {
	public static void main (String[] args) {
		Monster monster = () -> {
			System.out.println("感染する");
		};
	monster.infection();
	}
}
```
トレーナはインスタンスを生成をせずにモンスタに技を完成させました。

```
結果
感染する
```
#まとめ
・ラムダ式は、クラス宣言とインスタンス生成がが同時にできる
AuraからLWRに移行する

LWR



手順が紹介されています。今のところ情報が少ない。


1. 新しいLWRサイトと空のページを作成します

2.  既存のカスタムLWCを新しいページに移動します

3. 古いサイトで使用していたサポートされていないLightningLWCコンポーネントの代わりにLWCを作成します。何か違うものが必要な場合は、UI / UXを変更する良い機会です

4.テストと改良

5.カスタムドメインを変更して公開する

[Migrate from Aura to LWR](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000FQxOX)


Build Your Own（LWR）は、その名前が示すように、すぐに使用できる最も重要なページとコンポーネントのみを提供する最小限のテンプレートです。
[LWRテンプレートのページとコンポーネント](https://developer.salesforce.com/docs/atlas.en-us.exp_cloud_lwr.meta/exp_cloud_lwr/template_pages.htm)

# 参考になりそうな質問と回答

+ [How can I include SLDS styles resources in my LWR Node app ?](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000EnIzR)
+  [Error while Publishing LWR Site](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000PfAwk)

Getting Error: The selection of publish items is invalid. 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/17170c14-2926-a782-6f8b-2755b9af9623.png)

:::note
As per Salesforce, If we try to run 2 or more publish commands at the same time (maybe within 1-5 secs timeframe), there is a possibility that one of the publish might get struck. So they suggested not to publish 2 sites at the same time. 


We had few LWCs which are reused in 2 different Experience Cloud Sites, so we configured our pipeline to publish both the sites after deployment which caused this issue. We raised a case to Salesforce to unblock it. 
:::

# LWR 

+ [LWR Enhanced サイトのページはモバイルでは使用できません](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000PiV0jSAF)

Google モバイル フレンドリー テストで本番環境の LWR サイト ページが「ページはモバイルでは使用できない」として分類されるという、非常に奇妙な問題が発生しています。Google はデスクトップ版でページをレンダリングします。実際には応答性が高く、モバイルでは問題なく表示されます。そしてここでさらに奇妙な部分が来ます。まったく同じコードでサンドボックス ページをテストすると、すべて問題がないことがわかります。そこで Google はモバイル版をレンダリングします。 

# エラー

+ [【未解決】Routing error: Error importing view with name "default", failure was: LWR3008: Error loading](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000O868z)

+ [We couldn't load all the components on this page. If possible, contact the site administrator and provide the following error details. In the "{flow name}" flow, remove these Aura components or replace them with Lightning web components: flowruntime:image.](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007clIZv)
+ [login page error](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ifjMaSAI)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/1313be4d-024b-2852-10a2-5f71b4c8fd4b.png)
アジャイルの始め方～化石エンジニアがアジャイル本の分布図を更新（2021年版）～

#前段

塩漬け状態だった本の地図（書籍の分布図）を更新しました。


#課題
アジャイル本の裏付けとなる他のジャンル本も読まなければ……。
なお、この地図はマンダラートでカテゴリー分けされており、マネジメント系、等、他のジャンルも作ってたりします。

##ジャンル一覧
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1668633/ce52c89b-fc88-6aa3-d958-327d3aebfca4.png)
この中の「開発系」をさらに分けていて、「アジャイル系」を作っています。



##アジャイル系
※書影はすべて版元ドットコム様より。
![本の地図_2021.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1668633/abe36f11-bf3c-275c-86a3-7fb7e4551b65.png)

『アジャイルサムライ』を「0地点」とした場合の独断と偏見による分布図。
間違ってるところもあるかもですが、「独断と偏見」なのでご容赦ください。

以下、版元ドットコム様 リンク：
　※画像にリンクを貼ろうとして力尽きたのでURL…。

・SCRUM BOOT CAMP THE BOOK【増補改訂版】：
　　https://www.hanmoto.com/bd/isbn/9784798163680
・いちばんやさしいアジャイル開発の教本（書影なし）：
　　https://www.hanmoto.com/bd/isbn/9784295008835
・ここはウォーターフォール市、アジャイル町：
　　https://www.hanmoto.com/bd/isbn/9784798165387
・カイゼン・ジャーニー：
　　https://www.hanmoto.com/bd/isbn/9784798153346
・チーム・ジャーニー：
　　https://www.hanmoto.com/bd/isbn/9784798163635
・アジャイルサムライ：
　　https://www.hanmoto.com/bd/isbn/9784274068560
・SCRUMMASTER THE BOOK：
　　https://www.hanmoto.com/bd/isbn/9784798166858
・みんなでアジャイル：
　　https://www.hanmoto.com/bd/isbn/9784873119090
・スクラム現場ガイド：
　　https://www.hanmoto.com/bd/isbn/9784839951993
・リーン・スタートアップ：
　　https://www.hanmoto.com/bd/isbn/9784822248970
・This is Lean：
　　https://www.hanmoto.com/bd/isbn/9784798169514
・アジャイルプラクティス：
　　https://www.hanmoto.com/bd/isbn/9784274066948
・アジャイルレトロスペクティブズ：
　　https://www.hanmoto.com/bd/isbn/9784274066986
・Lean UX 第2版（書影なし）：
　　https://www.hanmoto.com/bd/isbn/9784873118055
・スクラム実践者が知るべき97のこと：
　　https://www.hanmoto.com/bd/isbn/9784873119397
・アジャイルコーチング（書影なし）：
　　https://www.hanmoto.com/bd/isbn/9784274219375
・Fearless Change：
　　https://www.hanmoto.com/bd/isbn/9784621087862
・スクラム実践入門：
　　https://www.hanmoto.com/bd/isbn/9784774172361
・アジャイル開発とスクラム 第2版：
　　https://www.hanmoto.com/bd/isbn/9784798167466
・スクラム　仕事が４倍速くなる“世界標準”のチーム戦術：
　　https://www.hanmoto.com/bd/isbn/9784152095428
・エクストリームプログラミング：
　　https://www.hanmoto.com/bd/isbn/9784274217623
・正しいものを正しくつくる（書影なし）：
　　https://www.hanmoto.com/bd/isbn/9784802511193
・ソフトウェア・ファースト：
　　https://www.hanmoto.com/bd/isbn/9784822289911

アジャイル系以外も読んでるので、あまり前回の地図から変更がなかった感じがします。
あと抽象度の高い、裏付けとなる文献を読んでないと判明。
今年はいっぱい本を読むぞー！

本日は以上で終わりです。お付き合いいただき、ありがとうございました
Herokuでアプリを公開する

概要
-
Herokuでアプリケーションを公開=「デプロイ」する。

1. Herokuにコミットする
-
① CLIでHerokuを操作するため、HerokuのCLIをインストールする。
herokuというコマンドが使用できる。

```
% brew tap heroku/brew && brew install heroku
```

②インストールできたか確認

```
% heroku --version

⇨　heroku/7.40.0 darwin-x64 node-v13.15.1

```

上記のように、バージョンが確認できれば、インストール成功！


③ Herokuにログインする

```
% heroku login --interactive
  => Enter your Heroku credentials.
# メールアドレスを入力し、エンターキーを押す
  => Email:
# パスワードを入力して、エンターキーを押す
  => Password:

⇨ Logged in as 登録したメールアドレス
```
上記のように表示されれば、ログイン成功！

2. Heroku上にアプリケーションを作成する
-
該当のアプリケーションのディレクトリで行う。

```
...MacBook-Air frima-app % heroku create frima-app
```

下記のコマンドを入力し、正しく作成できたことを確認する。

```
% git config --list | grep heroku
```

「fatal: not in a git directory」が表示されなければ、作成完了！


3. Heroku上でMySQLを利用可能にする
-
①データベースの設定をする
Herokuでは、使用するデータベースの設定が、デフォルトでPostgreSQLになっているため、
「ClearDBアドオン」を追加することで、HerokuでMySQLを利用できるように設定する。
（ClearDBアドオン：　MySQLを使うためのツール）

```
% heroku addons:add cleardb
```

②
Ruby on Railsを使う場合は、MySQLに対応するGemについて考慮する。

```
% heroku_cleardb=`heroku config:get CLEARDB_DATABASE_URL`
% heroku config:set DATABASE_URL=mysql2${heroku_cleardb:5}
```

4. Heroku上で非公開の値を暗号化する
-
credentials.yml.encファイルとmaster.keyファイルは、セットにすることで、中身を解読できるようになる。

① credentials.yml.encの中身を確認する。

```
% EDITOR="vi" bin/rails credentials:edit
```
「esc」→「:」→「q」→「enter」を押して credentials.yml.encを閉じる。

② Heroku上に、環境変数として、master.keyの値を設置する (Herokuへプッシュする前に)

```
% heroku config:set RAILS_MASTER_KEY=`cat config/master.key`
```
「heroku config」：Heroku上で環境変数の参照・追加・削除などするためのコマンド

5.Herokuで使用する動作環境を設定する
-
Herokuには、Stack（スタック）という環境が用意されている。

```
% heroku stack:set heroku-18 -a frima-app
```
6. Herokuで使用するNodeのバージョンを設定
-

Herokuの初期設定におけるNodeのversionと、自身のアプリにおいてインストールしたNodeのversionを一致させる。不一致だと、正常なデプロイが行えないため。
そのため、HerokuのNodeのversionを指定する。


① 「buildpack」を使用する。Herokuで様々な言語のアプリを扱える。

```
% heroku buildpacks:add heroku/nodejs
% heroku buildpacks:add heroku/ruby

​​% heroku buildpacks
⇨nodejsとrubyの2つがインストールできてれば成功！
```
②　使用するnodeのバージョンをpackage.jsonへ記述する

```
% node -v

v13.15.2 
```
```package.json
~省略~
 "version": "0.1.0",
 "devDependencies": {
   "webpack-dev-server": "^3.10.3"
 },  // カンマを記述
 "engines" : {
   "node": "13.15.2 "  // nodeのバージョンを記述
 }
}
```
③ ここまでの変更をコミットプッシュ

7. Gitで管理しているリポジトリをHerokuに反映する 
-

```
% git push heroku master
```

---今後、アプリに変更を加えた場合はここから----------------------------------------------

今後、開発環境でappに変更を加えた場合は、

```
% git add .
% git commit -m "後から見てわかりやすいコミット名"
% git push heroku master
```

8. Heroku上でマイグレファイルを実行する
-
コードはHerokuに反映できたが、データベースにはマイグレーションの情報が反映されていないので、rails db:migrateを実行したい。Heroku上で実行したいので、

```
% heroku run rails db:migrate
```

9. 公開を確認する
-

```
% heroku apps:info
```

公開されたアプリの詳細を確認できる。

＊ エラーが発生したら
-

```
% heroku logs --tail --app frima-app
```
これにより表示されるエラー文からエラーの原因を確認する
予測困難な簡易乱数

単純に、物理状態（日時、タイマー、パフォーマンス、CPU温度、ユーザー操作に依存するものなど）を取得する関数を使います。この方法の欠点は、再現性の低いバグの原因となって、デバッグが難しくなる場合があることです。

以下では window.performance.now() の値を使って、Math.random を数回更新した後の値を使用します。この場合、出てきた順番から次の候補（4個）を予測することまでは可能かもしれませんが、一つに絞り込むことは困難なハズです。

動作確認は Google Chrome バージョン: 98.0.4758.80（Official Build）（x86_64）で行っています。

```html:
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>乱数テスト</title>
  </head>
  <body>
    <h1>乱数テスト</h1>
    <p><label><input type="button" onclick="doClick();" value="次"></label> : Math.random() = <span id="value"></p>

    <script type="text/javascript">
    <!--

      function doClick() {
          let n = 0;
          for (const c of window.performance.now().toString())
              n += c.charCodeAt(0);
          n &= 3;
          // ここでは Math.random() を使用してますが
          // もっと簡易な乱数を想定しています。
          for (let s = 0; s < n; s++)
              Math.random();
          document.getElementById('value').innerText = Math.trunc(Math.random() * 100);
      }

      doClick();

      -->
    </script>
  </body>
</html>
```
バッチファイルと同じ場所のPythonスクリプトファイルを呼び出す

# バッチファイルと同じ場所のPythonスクリプトファイルを呼び出す
Pythonスクリプトファイルの関連付けがPython以外でファイルをドロップできない場合など、バッチファイルからスクリプトを呼び出したいことがあります。このときはバッチファイルのスクリプトファイル名の前に`%~dp0`を付けます。

```batch:test.bat（test.pyを呼び出す）
python.exe %~dp0test.py %*
```

`%~dp0`はバッチファイルの親ディレクトリのパス+「\」を指すバッチパラメーターです。省略した場合、ドラッグ＆ドロップによりカレントディレクトリの場所が変わり、ファイルが見つからない、間違ったファイルを呼び出すといった想定外の動作につながります。

# 蛇足：ストアアプリ版PowerShell 7による関連付け消失時

PowerShell 7をインストーラー版からストアアプリ版に切り替えた場合、ps1ファイルの関連付けが消えることがあります。この場合はインストーラー版PowerShell 7に戻すことで関連付けとドラッグ＆ドロップが復活します。ストアアプリ版の場所を探して手動で関連付ける方法でも可能かもしれません。
Burpでscope以外の通信を遮断する方法

Burpの設定を変更するとscope以外の通信を遮断することができる。

## やり方

Project options > Connections > Out-of-Scope Requests Drop all out of scope requestsにチェックを入れる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2306409/71703784-ef50-33e0-8b68-10be6da8ff93.png)
jQueryをES Modules形式でインポートするには (Rollup)

最近、モダンなフロントエンドの現場では、ReactやVue.jsといった技術が使用されることが増えました。
しかし今でも、ちょっとしたDOM操作をしたいときに、jQueryを使用すると便利な場面がたまにあります。

jQueryを使いたいけど、せめて、jQueryのインポートにはモダンな技術を使いたい。

というわけで、最近、jQueryをES Modules形式でインポートしようとしたのですが、
なかなかうまくいかず、苦戦しましたので、備忘録もかねて、解決策を解説させていただきます。

## この記事で書かないこと

- Rollup の使い方
- ES Modulesについての説明

上記はこの記事では解説しません。適宜ご自身でお調べください。

## （前提条件）Rollupの設定

前提条件として、今回は、Rollupでビルド・バンドルする場合の手順を解説いたします。
Rollupの設定は下記のとおりです（今回の解説に必要な最低限の構成にしています）。

```rollup.config.js
import resolve from 'rollup-plugin-node-resolve'

export default {
    input: 'src/js/hoge.js',
    output: {
        file: 'dist/js/hoge.js',
        format: 'iife',
    },
    plugins: [ resolve() ]
}

```

## 発生するエラーとその原因

まず、npmでjQueryをインストールします。

```
npm i jquery
```

続きまして、 hoge.js というファイルで、次のように、jQueryをインポートしてみます。

```hoge.js
import $ from 'jquery'
```

すると、ビルド時に、下記のエラーが発生します。

```
Error: 'default' is not exported by node_modules/jquery/dist/jquery.js, imported by hoge.js
```

原因は、jQueryのソースコードを読めば、すぐにわかります。
そもそもES Modules形式でのインポートがサポートされていないのです。
個人的にjQueryに期待していただけに、ちょっと残念でした…

## 解決策

jQueryのソースコードを読むと、 `window.jQuery` と `window.$` というグローバル変数をセットしているということがわかります。
そこで、次のようなファイルを作成すると、ES Modules形式でjQueryをエクスポートできます。

```jquery.esm.js
import 'jquery'
export default window.jQuery
```

しかし、せっかくES Modulesで管理しているのに、グローバルスコープが汚染されるのは気持ち悪いですよね。
そこで、jQueryの公式ドキュメントを読むと、 `noConflict` メソッドを呼び出すと、jQueryがセットしたグローバル変数を消し去ることができるということがわかります。
https://api.jquery.com/jquery.noconflict/
そして、このメソッドは戻り値としてjQuery自身を返します。
ということは、先ほどのファイルを、次のように書き換えると、グローバルスコープを汚さずにjQueryをエクスポートできます。


```jquery.esm.js
import 'jquery'
export default window.jQuery.noConflict(true)
```

あとは、このファイルをふつうにインポートするだけでjQueryが使えます！

```hoge.js
import $ from './jquery.esm'
```

## おまけ

jQueryは便利な機能が多数搭載されている反面、ファイルサイズが大きくなりがちです。
アニメーションやAjax系のメソッドを使わないのであれば、Slim版を使用することによってファイルサイズを抑えることができます。
その場合、 jquery.esm.js を下記の通り書き換えましょう。

```jquery.esm.js
import 'jquery/dist/jquery.slim'
export default window.jQuery.noConflict(true)
```