OmniAICreator/Qiita-1.07M huggingface dataset:
nextjsでモバイル端末を使うとauthorizationヘッダーが見つからない場合

# 問題

クライアントからは確かにauthorizationヘッダーを流しているのに、サーバー側で検知できない。
しかもこれが何故かモバイル端末だけで起きている。

```ts:client
await fetch(`/api/test`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    authorization: `Bearer ${token}`,
  },
  body: JSON.stringify({
    ...data,
  }),
})
```

```ts:server側（/api/test/）
import type { NextApiRequest, NextApiResponse } from "next"
export default async (req: NextApiRequest, res: NextApiResponse) => {
  console.log(req.headers) // authorizationがない...
}
```

# 解決方法

多分[こういう設定][1]をしているはず。
これがあると`/api/test` => `/api/test/`に切り替えてくれるので404エラーが出ないが、モバイル端末だとこのリダイレクト間でどうもヘッダーの引き継ぎをしない様子で、この為に設定した`authorization`などの項目が抜け落ちてしまっている。

```js:next.config.js
module.exports = {
  trailingSlash: true,
}
```

なのでクライアント側から呼ぶ際には`/`で確実に終わるように確認する。

```ts:client
//             「/」で終わっているか確認
fetch(`/api/test/` ...
```



[1]: https://nextjs.org/docs/api-reference/next.config.js/trailing-slash
javascript オブジェクト指向の備忘録

オブジェクトの基本構造
var オブジェクト名= {
　　　プロパティ名: ------,
　　　プロパティ名: ------
}

呼び出しは
オブジェクト名.プロパティ名();

関数をオブジェクト内に組み込むことを考える
関数名　→　プロパティ名

例

function start(){
　ーーーー
}

↓

var object= {
  start: function (){
　ーーーー
　}
}

呼び出し
object.start();


ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
Tips
関数を実行する際についての豆知識

----------= start();
はページが読み込まれた際にstart関数が実行される

----------= start；
は----------が発生する度に実行される
CSS 調査

# 概要

2021年2月時点でCSSの動向について軽く調査した時の記録です。

# 1. CSSクラス

CSS, SCSS, SASS等のファイルをwebpack等でCSSとして出力し、HTML上で読みこむ。

* メリット

SCSS, LESSが使える。覚えることが少なく簡単。

* デメリット

グローバルスコープにスタイルを追加していくのでクラス数が増えると管理が大変になる。
気づかぬままにスタイルを上書きし、別の画面に影響がでるなど。
BEMやOOCSSなどで規則をつけることで回避してきた歴史がある。

# 2. インラインスタイル

スタイルの文字列をJSオブジェクトにまとめて、style属性にそのまま対応させる方法。
部分的に利用する以外、公式で推奨されていない。
メリットの部分に書くが、動的にstyleを生成したい箇所には有効。

```js
const style = {
	color: red
}
export default (props) => <button style={style} {...props} />;
```

* メリット

styleを動的に生成することが可能。
これはCSSだけでは実現できない。

```js
const style = {
	color: color ? color : red
}
```

* デメリット

:hoverなどの疑似要素が設定できない。
イベント発火時にJSで追加したりとやる必要がある。


# 3. CSS Modules

ローカルスコープ(ファイル内でのみ有効なスコープ)を持つCSSクラスをツールで生成する。
これにより、グローバルでクラス名の衝突が起きないようにする。
よく見る、「class="TQc1id rhstc4"」というようなやつ。

* メリット

スコープを気にせず、CSSとUIコンポーネントのコードを分離できる。

* デメリット

子コンポーネントのスタイルを親が上書きした場合、子と親のどちらのスタイルが適用されるかはビルド時のファイルの読み込み順により決定する場合がある。
暗黙的に上書きされている場合、ディレクトリ変更によりファイルの読み込み順が変わり、Cascadingの順序が変わることでスタイルが崩れる例がある。
この辺に注意しながら利用する必要がある。

https://speakerdeck.com/kubosho/solution-of-css-is-too-fragile-by-abematv?slide=27

上記の例ではBEM + PostCSSに移行している。(2019.05)

# 4. CSS in JS

インラインスタイルの持つ、疑似要素を設定できない等のデメリットを解消したライブラリ(styled-components, emotion等)を利用する方法。

* メリット

インラインスタイルと同様、styleを動的に生成することが可能。
CSSでよくあるmodifierのクラスが増える場面において、無駄にクラスを増やさずに済む。

```css
.msg-base {
	font-size: 10px;
}
.msg--err {
	background-color: red;	
}
.msg--success {
	background-color: green;
}
```

素のCSSだと上記のように3クラス必要になるところが、以下のように1つのモジュールで完結する。

```js
const msg = styled.div`
	font-size: 10px;
	background-color: ${props => props.color};
`
```

* デメリット

JSの式が加わることによりかえって複雑になる場合がある。
CSSモジュールとうまく付き合うようにするか、BEMを使えばよいという意見も。
また、1つのファイルにまとまるのは簡潔でよいが、バージョン管理する場合、スタイルの変更と制御の変更が混ざる。

参考:

https://postd.cc/stop-using-css-in-javascript-for-web-development-fa/

https://qiita.com/xrxoxcxox/items/9df67f41ac1f27ca5460

## その他参考

https://qiita.com/lightnet328/items/218eb1c4a347302cc340

https://medium.com/asoview-engineering/hisroty-of-css-environment-f93c0b6d07bd
LaravelとVueの連携、Array型からObject型になってしまう問題の解決

#バージョン
Laravel 6.20.2
 Vue.js 2.6.12 

#問題
LaravelからVueに値を渡した際に、
マイグレーションで作成した初期値の値は正しく表示されるが、
追加した値は正しく表示されない問題が発生した。

検証モードで詳しくみたところ、dataがArray型からObject型に変わってしまうのが原因だと思われます。


**検証モード画像**
[良い例] dataがArray型になっている。
![スクリーンショット 2021-03-12 15.06.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639996/35ea6caa-e546-865a-f071-9cfd0744f9b7.png)

[悪い例]　dataがObject型になっている。その他、特に変わったところはありません。
![スクリーンショット 2021-03-12 15.05.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639996/0cda5ef0-2eeb-6b9f-6361-60f7cf60a695.png)


#原因
~~DBからデータ取得後に配列をソートすると、キーが0から始まらなくなるのが原因のようです。
Vue.jsの仕様のようなのですが、詳しい記述は見つからなかったので、
原因は参考程度でお願いします。~~

コメントにて@nunulk さんより原因の詳細を教えて頂きました。
コメントありがとうございます。

正しくはLaravel と PHP の問題で、
sortByでソートした場合、ソート後にキーを維持してしまい、配列でなく連想配列になるのが原因でした。
(詳細はコメントを確認下さい。)


#コード例
getメソッドの前にクエリビルダのorderByで整列しておくのが重要です。

```PHP:Controller.php
//[Array型になる良い例]  (orderByメソッドのあとにget() )
public function index(){
$tutorials = Auth::user()->tutorials()->orderBy('created_at')->get();


//[Object型になってしまう悪い例]  (get()したあとにsortByDescメソッド)
$tutorials = Auth::user()->tutorials()->get()->sortByDesc('created_at');


 return [
       'tutorials' => $tutorials,
 ];
}
```

```PHP:index.blade.php
      <tutorial
      :initial-title='@json($tutorials)'
      >
      </tutorial>
```

```Javascript:Tutorial.vue
<script>
export default {
  props: {
    initialTitle:{
      type:Array,
      default:[]
    },
  },
  data(){
    return {
      getLists:this.initialTitle,
    }
  }
}
},
```


#Collectionを使った場合  (クエリビルダ orderByを使わない場合)
コレクションに対してvalues()メソッドを使う場合も、同じような処理ができます。
valuesメソッドはキーをリセット後、連続した整数にした新しいコレクションを返します。

```PHP:Controller.php

public function index(){
$tutorials = Auth::user()->tutorials()->get()->sortByDesc('created_at');

 return [
       'tutorials' => $tutorials->values(),  //valuesメソッドを使用
 ];
}
```


#最後に
Laravelの参考書等を調べても載っていないような情報だったので共有してみました。
もし内容に間違い等あればコメント頂けると幸いです。
Oracle x86とx64を共存させる

# 共存させたい理由
Visual Studio の開発で、x64限定のライブラリを利用している時、実行プラットフォームがx64にするわけだが、この状態で、Instant Client (ODP.NET) をx86、x64のどちらともインストールされていると、どうも接続がうまくできない。

『Oracle クライアント ライブラリを読み込もうとしましたが、BadImageFormatException が発行されました。この問題は、32 ビットの Oracle クライアント コンポーネントがインストールされている環境で 64 ビット モードを実行すると発生します。』
って言われる。

でも、開発環境を分離できない状況で、x86としても開発するし、x64でも開発するし、だとすると、Instant Client を入れたり消したりなどしないとダメそうで勝手が悪い。

# やり方
[Oracle Instant Client の64ビット版と32ビット版を共存させる方法](http://everything-you-do-is-practice.blogspot.com/2018/01/oracle-instant-client-6432.html)に載ってた。

System32とSysWOW64に、それぞれシンボリックリンクを張ればいいそうな。
『oracle_instant_client12_2』部分は任意だけど、どちらも同一でなければならない。

```
-- x64のシンボリックリンクを張る
C:\> cd C:\Windows\System32
C:\Windows\System32> mklink oracle_instant_client12_2 C:\Oracle\instantclient_12_2x64

-- x86のシンボリックリンク張る
C:\> cd C:\Windows\SysWOW64
C:\Windows\SysWOW64> mklink oracle_instant_client12_2 C:\Oracle\instantclient_12_2x86
```

んで、環境変数のPATHに、

```
C:\Windows\System32/oracle_instant_client12_2
```
を追加すればいいらしい。

# 確認
Visual Studio でx86、x64プラットフォームどちらでも接続ができた！

# 足りないこと
上記の方法はOracleの実行イメージ？を切り替えるものであり、コマンドについても対応しているわけではない。
sqlplusなどを実行したい場合は、そのパスも環境変数のPATHに追加しなければならない。

私の場合、SI Object Browser などや、x86開発も多くあるため、コマンドとしてはx86の Instant Clientのパス情報を通すようにした。
PHP7.1からPHP7.4へのバージョンアップ（さくらＶＰＳ）

## 前提
wordpressをインストールしたところ、管理画面にphp7.1はサポート終了のためアップデートしてほしいとの表示があり、バージョンアップを実施。
今後のために、備忘録を残しておきます。

### 環境
CentOS Linux release 7.9.2009（さくらVPS）

### システムアップデート
とりあえず、システムのアップデートにて、特にないとのことを確認

```sh
$ yum update
No packages marked for update
```


## 手順
今後も対応する可能性があるので、更新した際の手順を記載する。

### バージョン確認
```sh
$ rpm -qa | grep php
php-7.1.33-12.el7.remi.x86_64
php-json-7.1.33-12.el7.remi.x86_64
・
・
・
```

### php71の削除
```sh
$ yum remove php-*
# Packageを削除
Complete!
```

### 問題発生
当初は、下記の記事を参考にしていたのですが、自身の環境ではうまくいかず、wordpressにて、「お使いのサーバーの PHP では WordPress に必要な MySQL 拡張を利用できないようです。」と表示された。
https://www.geekfeed.co.jp/geekblog/centos-remi-epel-php

>原因は、php-mysqlndをインストールしていなかったみたい・・

### 気を取り直して、再度phpの削除からphp-mysqlndを含めてインストール
```sh
$ yum remove php-*
# Packageを削除
Complete!

$ yum install --enablerepo=remi,remi-php74 php php-devel php-mbstring php-mysqlnd php-pdo php-gd
# Packageをインストール
Complete!

$ systemctl restart httpd
# httpdを再起動
```

## 結果
無事、なんとかバージョンアップできたようです。
wordpressのmysql問題も解決して、アクセスできるようになりました。

```sh
$ php -v
PHP 7.4.16 (cli)
```

## 参考にしたサイト
https://www.geekfeed.co.jp/geekblog/centos-remi-epel-php
https://qiita.com/pugiemonn/items/6f642ffb0165f69dab3d
https://www.sakura-vps.net/centos7-setting-list/php-settings-for-sakura-vps-centos7/
日本にはソフトウェアエンジニアはいなかったので

過激なタイトルの駄文

https://qiita.com/e99h2121/items/419c3bd39d8dea40f21a

## システムインテグレータ

日本はSIが盛んな国なんですよ。外部アウトソーシングすると開発手法はウォータフォールになります。
ウォータフォールの場合、ソフトウェアの比重は低くなります。アウトソーシングの摩擦とウォータフォールを管理するプロジェクトマネジメントの手法が大事になります。

そして重視された人材が、いわゆる上流とかPMというそれです。

## 儲けのしくみの問題

実際、既存のIT化の時代は、紙をデジタル化するだけです。大事なのは情報を残すデータなんですね。
これがアウトソーシングになると物売りに変わります。

SI屋も固定資産として残るデータベースとハードウェアインフラを売りつけるため金額の比重を上げやすいのです。逆に、製造工程という工程に予算は避けないので、必然的に製造は安かろう悪かろうが常識化していきます。製造しか"出来ない"プログラマーという職種はありました。

土建的に言えば、とても良い防犯装置と、職人が無駄に時間かけた多分よい柱。どっちが欲しいのって話です。そんな無駄な防犯装置もお金たくさん出して買う人達はいっぱいいたのですが、製造には回りませんでした。

## ユーザー系の中に生まれた文化

アメリカやヨーロッパにもSIもいますが、メインはユーザー系です。するとソフトウェア開発の比重も上がります。モノを売るというより自分達に必要なものを用意するわけです。安くて必要なモノを作れという圧力や負担になります。生き残るための創意工夫が必要になるのです。

生き残り策として、標準化の促進や、パッケージソフトウェアを使うようにしたり、開発方法を工夫をしていきました。日本は、この辺り遅れてた三銃士まんまですね。英語の壁はあるかもですが、こういう壁のほうがヤバイかも。だって、必要だと思わなや標準なんていらないから。

## ソフトウェアエンジニアの誕生

そして、最も効率的な有力な開発方法の工夫が「プログラマの能力を最大限に生かすと良いものが出来るぜ。」アジャイル開発とかXPとかだったのです。当時からこの辺りの熱の違いが既に顕著でしたね。

さらに人の流動性が高いため、実績を残し優れたエンジニアは評価され有名になり賃金も上がり、人材にも厚みが出ていきます。
（なんとまあ、プログラマの人材だけなら日本も多いんですけどね！）

## インターネットですありがとうございました

そんな下地の違いが既にX0年以上前からあったわけで、そこにインターネットのBtoCへの隆盛により一気に明確化されたのでしょう。ソフトウェアはたくさん必要だし複雑に膨れがあることになり、優れたソフトウェアエンジニアが必要になります。その人材を提供できる基盤があったのです。日本には、そんな役割がそもそもいなかったのです。SIが飼ってる"出来るプログラマ"さんぐらいですね。

## まとめ

DXとか政府が言ってるのみると、やっとそういう人材に気付いたわけです。
ソフトウェアエンジニアがやっと日本に誕生したのです。みなさんがんばっていきましょい！

## 注意

偏見と適当な妄想なので現実との乖離はあるかもです。
Mac環境にNode.jsをインストールする

#はじめに
Mac環境にNode.jsをインストールする方法としていくつかの方法があります。ここではバージョン管理を行うためにnodenvを利用した方法についてまとめます。

#インストール
Node.jsをインストールするためには、以下をインストールする必要があります。

1. Homebrewをインストール
2. nodenvをインストール


##Homebrewのインストール
Homebrewをインストールします。[Homebrew](https://brew.sh/index_ja)に書かれているインストールコマンドを実行します。

```bash
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```
```brew doctor```を実行して、インストール確認を行います。

``` bash
$ brew doctor
Your system is ready to brew.
```
これでHomebrewのインストールは完了です。

##nodenvのインストール
Homebrewからnodenvをインストールします。

```bash
$ brew install nodenv
```


~/.bash_profile、または~/.zprofileに```eval "$(nodenv init -)"```を追加します。
```nodenv init```を実行することで、どこに何を追加したらよいのかを確認することができます。

```bash
$ nodenv init
# Load nodenv automatically by appending
# the following to ~/.bash_profile:

eval "$(nodenv init -)"
```

nodenv-doctorを実行してインストール確認します。

```bash
$ curl -fsSL https://github.com/nodenv/nodenv-installer/raw/master/bin/nodenv-doctor | bash
Checking for `nodenv' in PATH: /usr/local/bin/nodenv
Checking for nodenv shims in PATH: OK
Checking `nodenv install' support: /usr/local/bin/nodenv-install (node-build 4.9.32)
Counting installed Node versions: none
  There aren't any Node versions installed under `/Users/*****/.nodenv/versions'.
  You can install Node versions like so: nodenv install 2.2.4
Auditing installed plugins: OK
```
これでnodenvのインストールは完了です。


##Node.jsのインストール
nodenvからNode.jsをインストールします。
インストール可能なバージョンを確認します。

```bash
$ nodenv install -list
0.1.14
0.1.15
0.1.16

# 省略...

nightly
node-dev
rc
v8-canary
```

バージョンを指定してNode.jsをインストールします。(ここでは14.16.0をインストール)

```bash
$ nodenv install 14.16.0
Downloading node-v14.16.0-darwin-x64.tar.gz...
-> https://nodejs.org/dist/v14.16.0/node-v14.16.0-darwin-x64.tar.gz
Installing node-v14.16.0-darwin-x64...
Installed node-v14.16.0-darwin-x64 to /Users/*****/.nodenv/versions/14.16.0
```
インストールした後は、```nodenv rehash```を実行しておきます。

```bash
$ nodenv rehash
```

これでNode.jsのインストールは完了です。

#使用するNode.jsの指定
```nodenv global```を実行して使用するNode.jsのバージョンを指定します。(ここでは14.16.0を指定)

```bash
$ nodenv global 14.16.0 
```
また、プロジェクト別(ディレクトリ別)に指定することもできます。

```bash
$ nodenv local 14.16.0 
```
#アンインストール
##Node.jsのアンインストール
特定のバージョンをアンインストールしたい場合は```nodenv uninstall```を実行します。(ここでは14.16.0をアンインストール)

```bash
$ nodenv uninstall 14.16.0
```
Python+VSCode+Unitテスト+Debugするときにライブラリモジュールの中までステップインする設定

# 経緯

PythonのUnittestをVSCodeでDebug実行した際、importした外部のライブラリモジュールまではステップインできませんでした。
その際、DEBUG CONSOLEには下記のメッセージが表示されます。

```
Frame skipped from debugging during step-in.
Note: may have been skipped because of "justMyCode" option (default == true). Try setting "justMyCode": false in the debug configuration (e.g., launch.json).
```

`justMyCode: false` 設定は知っています。Debug実行時に外部のライブラリモジュールにステップインするための設定です。
ですが、VSCodeのテスト機能の場合はどう記述するのでしょうか？

## （参考）Debug Test起動スイッチたち
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53115/4a6f50d0-0d24-fff2-c533-a35364c164e7.png)


# (2021年3月時点の）答え

:::note warn
2022年10月時点ではこの記述でも動作しますが、requestキーに対する値は `launch` または `attach` にするようシンタックス警告されます。
オススメ設定を次のセクションに記載します
:::

`launch.json` への記述で、`"request": "test"` 、 `"justMyCode": false` とします。
これで、テストをデバッグ実行した際に適用されます。

```launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python Unittest",
            "type": "python",
            "request": "test",
            "justMyCode": false
        },
# 以下省略
```

# 2022年10月時点の記述方法

**以前との違い**
- request: test→launch
- purpose: 新規 ["debug-test"]

参考: https://code.visualstudio.com/docs/python/debugging#_purpose



```launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Debug Test",
            "type": "python",
            "request": "launch",
            "purpose": ["debug-test"],
            "console": "integratedTerminal",
            "justMyCode": false
        },
# 以下省略
```
「操作を繰り返す[Shift+R]」をまとめて処理する雑な方法

「操作を繰り返す (Repeat Last)[Shift +R] 」便利なんだけど適用したい対象が数十にを超えたので実行するのが面倒になり書きました。

```
import bpy
try: 
    for o in bpy.context.selected_objects:
        bpy.context.view_layer.objects.active = o
        bpy.ops.screen.repeat_last()
except:
    pass
```
雑極まりないものだけど割と便利。
pm2  を Systemd で動かす

Ubuntu 20.10 で確認しました。

次のようにして、pm2 を動かせるようにします。

起動

>```bash
sudo systemctl status pm2-uchida.service
```

停止

>```bash
sudo systemctl stop pm2-uchida.service
```

モニター

>```bash
sudo systemctl status pm2-uchida.service
```

/etc/systemd/system/pm2-uchida.service の作成方法

次のようになっている状態で、

```text
$ pm2 list
┌────┬────────────────────┬──────────┬──────┬───────────┬──────────┬──────────┐
│ id │ name               │ mode     │ ↺    │ status    │ cpu      │ memory   │
├────┼────────────────────┼──────────┼──────┼───────────┼──────────┼──────────┤
│ 0  │ ee01               │ fork     │ 0    │ online    │ 0%       │ 85.1mb   │
└────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘
```

```text
$ pm2 save
[PM2] Saving current process list...
[PM2] Successfully saved in /home/uchida/.pm2/dump.pm2
pm2 save
```

```text
$ pm2 delete 0
[PM2] Applying action deleteProcessId on app [0](ids: [ '0' ])
[PM2] [ee01](0) ✓
┌────┬────────────────────┬──────────┬──────┬───────────┬──────────┬──────────┐
│ id │ name               │ mode     │ ↺    │ status    │ cpu      │ memory   │
└────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘
Current process list running is not in sync with saved list. App ee01 differs. Type 'pm2 save' to synchronize.
```

```text
$ pm2 startup
[PM2] Init System found: systemd
[PM2] To setup the Startup Script, copy/paste the following command:
sudo env PATH=$PATH:/usr/local/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup systemd -u uchida --hp /home/uchida
```

画面に出てきたコマンドを実行

```bash
sudo env PATH=$PATH:/usr/local/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup systemd -u uchida --hp /home/uchida
```

/etc/systemd/system/pm2-uchida.service
が作成されます。
[React]dataタグを使って要素を特定

data-\*属性を付与すると["data-\*"]でアクセスできる
（data-\*のvalueは任意で問題ない）

```tsx
import React, { MouseEvent } from "react";

export function Component {
    const handleClick = (event: MouseEvent<HTMLButtonElement>) => {
        // eventから見て最初に見つかる「data-container」を含む親要素を取得
        const container = event.currentTarget.closest("[data-container]");
    }

    return <div data-container={"true"}>
        <div>
            ・・・
            <button onClick={handleClick}>
                ・・・
            </button>
        </div>
        <div>
            ・・・
        </div>
    </div>;
}

```
CodeBuildを使ってDocumentDBを操作する

# 概要
CodeBuildを使ってDocumentDBを操作（抽出、挿入、削除）する

方法の概略
1. DocumentDBと同じVPC内でCodeBuildを作成
2. `buildspec.yml` にDocumentDBを操作するためのコマンドを書く
3. CodeBuildを実行する

# 事前準備

* 「public/private subnet」があるVPCとDocumentDBを用意
 - NAT Gatewayを作成
 - private subnetにNAT Gatewayへのルートを設定
 - private subnet内にDcoumentDBを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/975289/7e2a0f56-50e4-af45-bbaa-4a446f5a859b.png)

* CodeBuildが読み取るコードの場所を用意
    * 一般的にはCodeCommitがよく利用される

# やってみる

#### 1. DocumentDBと同じVPC内でCodeBuildを作成
VPCにCodeBuildプロジェクトを作成する。
作成する時には以下のことに気をつける。

* 必ずprivate subnetに作成する
    * （参考：[Amazon Virtual Private Cloud で AWS CodeBuild を使用する](https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/vpc-support.html)）
* セキュリティグループを適切に設定


#### 2. `buildspec.yml` にDocumentDBを操作するためのコマンドを書く

```yml:buildspec.yml
version: 0.2

phases:
  install:
    commands:
      # mongo-shellをインストールする
      - echo -e "[mongodb-org-4.0] \nname=MongoDB Repository\nbaseurl=https://repo.mongodb.org/yum/amazon/2013.03/mongodb-org/4.0/x86_64/\ngpgcheck=1 \nenabled=1 \ngpgkey=https://www.mongodb.org/static/pgp/server-4.0.asc" | tee /etc/yum.repos.d/mongodb-org-4.0.repo 
      - yum install -y mongodb-org-shell
  build:
  	commands:
  	  # SSL接続のために公開鍵をダウンロードしておく
      - wget https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem
      # 対話シェルが使えないので、script.jsを読み込ませてる
      # TODO: ${}にはそれぞれ適当な値を入れること
  	  - mongo --ssl --host ${HOST} ${DB_NAME} --sslCAFile rds-combined-ca-bundle.pem --username ${USERNAME} --password ${PASSWORD} < script.js
```

script.jsのコード例（詳細説明は他の記事で）

```js:script.js
/* --------------------------------- */
/* コレクション一覧 */
/* --------------------------------- */
db.getCollectionNames();

/* --------------------------------- */
/* ドキュメント内容 */
/* --------------------------------- */
// collectionを参照。存在しない場合は勝手に作成される。
collection = db.getCollection(<collection_name>);
collection.find();

/* --------------------------------- */
/* データを挿入 */
/* --------------------------------- */
collection = db.getCollection(<collection_name>);

doc_1 = {
	name: "bar",
	favarite: "foo"
};
collection.insert(doc_1);

/* --------------------------------- */
/* データを削除 */
/* --------------------------------- */
collection = db.getCollection(<collection_name>);

collection.remove({name: "bar"});
```

一応、CodeCommitのフォルダ構成

```
./
 - buildspec.yml
 - script.js
```

#### 3. CodeBuildを実行
`buildspec.yml`の内容が実行される
そして、DocumentDBに対して`script.js`の操作が行われる
BootstrapVueでb-form-selectの中のoptionに個別にCSSをあてる

# はじめに
BootstrapVueを使用していて、プルダウンの中の色を条件によって変えたくなったけど方法がよくわからなかったので備忘録。

私の場合、個別にグレーアウトにしたくて、まず[公式リファレンス](https://bootstrap-vue.org/docs/components/form-select)を見たんですけど…

disabledには簡単にできるみたいですけど、私は色を変えたいだけなんですよ。
そんなことしたいと思わないですよね。うんうん。。
私はしたい。

こんなかんじに。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508560/90816572-f80d-70ec-a497-5e7146f08241.png)


# やり方
たぶん普通にプルダウンリストを出すと、こんな書き方するんじゃないかな～と思います。
簡潔でらくちんですよね。これにCSSあてられたらよかったんですけど…

    <b-form-select
        :options="testlist"
        value-field="testId"
        text-field="testNm"></b-form-select>

でもこれだと中身のoptionタグにクラスを持たせられないので、下記のようにoptionを分けてかきます。
そうするとclassをあてられるようになるので。
Vue.jsのガイドにある[これ](https://jp.vuejs.org/v2/guide/forms.html#%E9%81%B8%E6%8A%9E)ですね。

そう、べた書きです。

    <b-select>
        <option :class="{ 'select-option': changeColor(v.testId) }"
        :value="v.testId"
        v-for="(v, i) in testList"
        :key="i" >
        {{v.testNm}}
        </option>
    </b-select>

こう書いたらあとはあてたいCSSを書いて、


    .select-option {
        background-color: #e2e6ea;
        color: rgb(108, 117, 125);
    }

条件書いて（これはテスト用なので好きに書いてね）、

    changeColor(testId){
      if (testId == 2){
        return true;
      }
      return false;
    }

おしまい！
以下雑なテストデータ。適当に試してね。

    testList:[
        {testId: 0, testNm: ''},
        {testId: 1, testNm: '白'},
        {testId: 2, testNm: '灰'},
        {testId: 3, testNm: '白'},
        {testId: 4, testNm: '白'},
    ]
es5/es6 classの混在で起きる問題とその解決方法

classを拡張すると、Class constructor SuperClass cannot be invoked without 'new'と出る場合があります。特に、Babelのクラスを、typescriptでextendしたり、mixinしようとするとこの問題が起きます。

# 理由

es6のclass （ブラウザがネイティブでサポートしているclass）は、関数として呼び出すことができず、Class constructor SuperClass cannot be invoked without 'new'というエラーになります。

ところが、es5のclass（ブラウザ的にはただのfunction）を拡張する際には、constructorのsuperの呼び出しで、super classのコンストラクタを、newを付けない文脈で呼び出されます。このため、es6 classは、es5クラスで拡張できません。

typescriptユーザには関係ないと思う人もいるかもしれませんが、そうではありません。typescriptのclassは、常にes5 classです。このため、Babelのクラスを、typescriptでextendしようとすると、Class constructor SuperClass cannot be invoked without 'new'になります。

ちなみに、es5 classをes6 classで拡張する分には問題ありません。

# 発生する状況

単独のビルド環境でclassを使っている限り起きない問題ですが、以下の２つの状況で発生します。

1. es6 classを使ったライブラリで作られたclassを、ライブラリ外で拡張する場合
2. typescriptや、es5 classを使ったライブラリ内で、ライブラリ外から受け取って拡張する場合

# 解決方法

1はライブラリ内で、es6 classを使うのは禁止という理解で良いと思います。

2について言うと、 理想を言えば、ライブラリは、外部から受け取ったclassを拡張したりmixinしてはいけないということになると思いますが、class decoratorを作ったりする場合、この制限は厳しいものがあります。これが現実的ではない場合、呼び出す側のプロジェクトで、es6 classを使わないようにするしかありません。

typescriptを使っている場合は、自動的にes5 classが使われるので問題ありませんが、Babelの場合、以下のようにpreset-envにinclude指定することで、強制的にbabelにes5 classを使うように指示することができます。

```js:babel.config.rc
module.exports = {
  presets: [
    [
      "@babel/preset-env",
      {
        include: [
          // Force es5 class
          "@babel/plugin-transform-classes",
        ],
      },
    ],
  }
}
```
iOS StoryBoard 多言語対応後のラベル、ボタンの追加

- Swift 5
- Xcode Version 12.3

多言語対応については、こちらの記事を参照
https://i-app-tec.com/ios/localization.html

上記記事の中の、StoryBoardを、最初に英語版を作って、その後日本語へローカライズしたときの話題です。

ローカライズ完了した後に、機能追加などで、ラベル、ボタンをStoryBoardで追加しても、日本語ファイルであるMain.strings(Japanese)には反映されません。

ので、手動で反映させる方法のメモとなります。
ほんとにこんなことをやる必要があるのか？と未だに疑問なので、もっと良い方法をご存知の方がいらっしゃったら教えて頂きたいです！

## StoryBoardで対象のラベルやボタンのObject IDを調べる

1. 対象のラベルやボタンをクリック
2. Identity inspectorを開く。（左から４つめ）
3. Documentの項目にObject IDが表示されているので、選択してコピー

## Main.strings(Japanese) に追記

1. Main.string(japanese) を開く
2. 適当な行に `"[Object ID].normalTitle" = "テキスト"; ` の形式で記述
3. ボタンの場合は、normalTitle、ラベルの場合はtextなど、Main.stringの他の項目を参考に記述する

```
例）
"Ka7-a7-C3u.normalTitle" = "送信";
```
.firstについて

Swiftで.firstといった物を見かけることがある。

何をやっているかというと、最初の要素を取得する

ループの場合だと全て取得するが、firstの場合は最初の物をとるといったことをする

それだけ

ざっくりすぎるし、それでいいのかもあやふやなのでそのうちまた更新すると思う
Vue エラー　Below is a rendering of the page up to the first error.

Vue.jsを利用して＠clickを追加した後、このエラーが表示されました。
>This page contains the following errors:
error on line 46 at column 39: error parsing attribute name
Below is a rendering of the page up to the first error.

v-on:clickを利用して
>This page contains the following errors:
error on line 46 at column 61: Namespace prefix v-on for click on button is not defined
Below is a rendering of the page up to the first error.

ようなエラーが表示されました。

原因はファイルの拡張子は.xhtml。これはhtmlの規則によって厳しく検査します。ファイルの名称を.htmlに変更して解決しまた。
JavaScriptの基礎知識３

## JavaScriptの基礎３
アウトプット３回目です。

## 関数定義
rubyでいうメソッドのことを関数という。
functionを使って関数を定義する。


## JavaScriptの関数定義
関数宣言:今まで定義してきたかたち

```
function (引数){
  //処理
}
```

関数式:変数に代入するかたち

```
変数 = functuion(引数){
　//処理
}
```

違いは関数宣言は先に読み込まれるが、関数式は後から読み込まれる。

## 関数の種類
無名関数
関数名なしで定義することができる

```
//関数宣言
function (hello){
console.log('こんにちは')
}
//無名関数
const hello = function(){
console.log('こんにちは')
}
```
アロー関数
（）=>を使うことでfunction()を省略できる

```
const 変数名 = () => {
　　//処理
}
```

```:js
const countNum = (num) =>{
console.log(num)
}
countNum(5)
→5が出力される
```
## 最後に
JavaScriptでは文章の終わりに「;」をつける。
これにはルールがあり、変数の定義、無名関数、アロー関数にはつけるが、if文や関数宣言にはつけない

以上です。
WSL1 から WSL2への移行

# はじめに
自身の環境に WSL2 を導入したので備忘録としてその手順を書いていく。前提条件は WSL1 を使っていて、WSL2 は未インストールの状況である。

# windows のバージョン確認と機能確認
`windows` + `R` で `winver` を実行し、windows のバージョンを確認する。WSL2 の起動条件は「x64 システムの場合:バージョン 1903 以降、ビルド 18362 以上。」である。
![winver.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1077734/da9ce904-3583-2a02-f2a5-769521b108e3.png)
自身のバージョンは20H2、ビルドは19042.867なので問題無し。

次に「Linux 用 Windows サブシステム」と「仮想マシンプラットフォーム」の有効化が必要である。コントロールパネルの`Windowsの機能の有効化または無効化`でそれぞれにチェックボックスが入っていることを確認する。入ってない場合は、管理者権限で実行した PowerShell で以下のコマンドを実行する。

```powershell:PowerShell
#Linux 用 Windows サブシステム の有効化
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart

#仮想マシンプラットフォーム の有効化
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
```
![win1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1077734/9042f55c-25a9-cc6d-e0cf-40da09c4bc12.png)
![win2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1077734/74894e79-be6a-060f-aa4d-ad08306642a9.png)

自分の場合はどちらもチェックが入っていたため、次の手順に進む。

# Linux カーネル更新プログラムパッケージのダウンロードとインストール

[こちらのページ](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10)の手順４から最新のパッケージをダウンロードし実行する。

# インストール済みの Ubuntu を WLS2 で起動できるようにする。
まずデフォルトで WSL2 が動くようにする。以下を実行すると今後インストールする Linux パッケージは全て WSL2 で起動することになる。

```powershell:PowerShell
PS C:\Users\r_yamamoto> wsl --set-default-version 2
WSL 2 との主な違いについては、https://aka.ms/wsl2 を参照してください
```

次に現状インストールされているパッケージがどの WSL で起動するかを確認する。

```powershell:PowerShell
PS C:\Users\r_yamamoto> wsl --list --verbose
  NAME            STATE           VERSION
* Ubuntu-18.04    Stopped         1
```

Ubuntu-18.04 が WSL1 で起動される事が分かるので、これを WSL2 で起動するように設定する。

```powershell:PowerShell
PS C:\Users\r_yamamoto> wsl --set-version Ubuntu-18.04 2
変換中です。この処理には数分かかることがあります...
WSL 2 との主な違いについては、https://aka.ms/wsl2 を参照してください
```

ここで30分以上待つ。

```powershell:PowerShell
変換が完了しました。
```

このコマンドが通ったら再度確認。

```powershell:PowerShell
PS C:\Users\r_yamamoto> wsl --list --verbose
  NAME            STATE           VERSION
* Ubuntu-18.04    Stopped         2
```

以上より WSL2 に移行できた。

# 参考文献

- [WSL1からWSL2への移行](http://www.aise.ics.saitama-u.ac.jp/~gotoh/WSL1ToWSL2.html)
- [WSL をインストールし、WSL 2 に更新する](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10)
【JavaScript】空のオブジェクト/配列の判定方法

#はじめに
業務で空のオブジェクト/配列の判定をする必要があったが、方法が分からなかったので調べてみました。


#空配列の判定
空配列の判定は以下で判定することができます。
配列の要素が存在しない場合(つまり空配列の場合)は、trueを返します。

```ts:空配列の判定
const emptyArray = [];
!emptyArray.length;
// true
```


#空オブジェクトの判定
空オブジェクトの判定は以下で判定することができます。
``Object.keys()``でオブジェクトのプロパティを配列で取得し、その配列の要素が存在しない場合(つまり空配列の場合)、trueを返します。


```ts:空オブジェクトの判定
const emptyObject = {};

function isEmpty(obj) {
  return !Object.keys(obj).length;
}

isEmpty(emptyObject)
// true
```

#参考サイト
[JavaScriptで空配列かどうか判定する方法を解説！](https://qumeru.com/magazine/204)
[【JavaScript】オブジェクトが空かどうか判定する](https://www.deep-rain.com/programming/javascript/910)
Laravel assetヘルパ httpとhttpsの切り替え

検証環境・本番環境でSSL対応を行っていた際にassetヘルパでエラーが起きていたので備忘録として。

# assetヘルパ
`asset()`はよく使われていると思います。
第一引数のみを渡した場合は`http://~`が返り値になります。

```php:hoge.php

asset('hoge/hoge.jpg')    // http://~が返り値
```

これだとSSL対応を行っていた場合はエラーになってしまいます。

しかし、assetヘルパは第二引数に`true`を渡すと返り値が`https://~`になります。

```php:fuga.php

asset('fuga/fuga.jpg', true)    // https://~が返り値
```
これでSSL対応してても大丈夫です。
このように、一部のみSSL対応といった場合はassetヘルパの第二引数にtrueを渡すことで対応ができます。

プロジェクト全体が常時SSLの場合は`web.php`や`ServiceProvider`に`URL::forceScheme('https');`を記載することがベストプラクティスな気がします。
※調べるとたくさん記事が出てくるのでそちらを参照してください。

とはいえ、第二引数に`true`を指定するとローカル環境でも`https://~`になってしまうので、そこは動的に変えたほうが良さそうです。

```php:よく見るやつ
$is_production = env('APP_ENV') === 'production' ? true : false;

asset('hoge/hoge', $is_production);
```

## 余談
urlヘルパやredirectヘルパも引数にbooleanを渡すことで制御可能です。
詳しくはググったり、ソースを読んでみてください。

# 終わり
readoubleでヘルパを覗いても記載されてないので調べるまで知らなかった知識。
以前調べた際にに知った事ですが、忘れると勿体ないので記事にしました。
単体テストコードRspecでの.validか.valid?か

validをふと「？」マークをつけるつけないで気にせずコーディングしていると
落とし穴がありました。
ターミナル上で赤くエラーメッセージが出たので修正にかかりました。




```terminal
     5:         @user = FactoryBot.build(:user)
     6:       end
     7:   
     8:       it 'nameとemail、passwordとpassword_confirmationが存在すれば登録できること' do
     9:         
 => 10:         binding.pry
    11:         expect(@user).to be_valid ?
    12:       end
    13:   
    14:       it 'nameが空では登録できないこと' do


[1] pry(#<RSpec::ExampleGroups::User::Create>)> exit
    nameとemail、passwordとpassword_confirmationが存在すれば登録できること (FAILED - 1)
Failures:

  1) User#create nameとemail、passwordとpassword_confirmationが存在すれば登録できること
     Failure/Error: expect(@user).to be_valid?
       expected #<User id: nil, name: "Spinka", email: "denyse.franecki@yahoo.com", created_at: nil, updated_at: nil> to respond to `valid??`
     # ./spec/models/user_spec.rb:11:in `block (3 levels) in <top (required)>'
```


terminal上で<font color="Red"> (FAILED - 1)</font>と示され
さらにエラーはここだよ<font color="Red">  Failure/Error: expect(@user).to be_valid?</font>と示されました。
さらに

・user id:なし
・（登録用）name:Spinka(Fakerにて作成）
・(登録用)email:denyse.franecki@yahoo.com(Fakerにて作成）
・登録日時：なし
・更新：なし
以上をデータベースに登録しようとし（expect）てその期待の答え(response)が<font color="Red"> valid？</font>ってなにに部分が以下

```
expected #<User id: nil, name: "Spinka", email: "denyse.franecki@yahoo.com", created_at: nil, updated_at: nil> to respond to `valid??`
```

Rspecの記述に問題がありました。違いは１点だけ。
validの後の<font color="Red">？</font>の有無だけです。

【誤】

```ruby

      it 'nameの値が存在すれば登録できること' do
         expect(@room).to be_valid
      end
```

【正】

```ruby

      it 'nameの値が存在すれば登録できること' do
         expect(@room).to be_valid
      end
```

まとめ
正常系は<font color="Red">validに？</font>をつけない。
異常系は<font color="Red">validに？</font>をつける。
を学びました。

| 正常系 （〜できる・ある）| 異常系（〜ない） | 
|:-----------|------------:|
| to be_valid      |to be_valid?        |　
| valid       | valid?        |
備忘録(？)：ポートフォリオサイト作成の流れ

#どうやってサイト作成してるの？ということで・・・
こんにちは、またはこんばんは。
最近、情報交換会をしたときに<font color="blue">**「どのようにしてサイト作成してるんですか？」**</font>と質問を受けたので、
直近で作成した[ポートフォリオサイト](https://kiku-cha.github.io/portfolio/)を例に、流れをご紹介していきます。



##作業の流れについて
一応Photoshop触れるということもあって、
<font color="red">**Photoshopでデザイン作成　→　コーディング**</font> の流れで、サイト作成をしました。

..........................................

#### デザイン作成 - ラフ

ポートフォリオサイト用に予めラフを描いていたので、それを元にデザイン作成しました。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">今日の活動内容🤟😌<br>なんやかんやあり、モーダルウィンドウは作成し直しました🙌<br>問題なく設置できたので安心しました😌<br>コーディングは八割以上出来てるので、あとは個人制作物の内容入れるだけかと...😌<br>(2枚目の画像はフレームのラフ的なやつです、字が汚い😂)<a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a> <a href="https://t.co/njEtQVzrmq">pic.twitter.com/njEtQVzrmq</a></p>&mdash; Kiku (@kiku_dondokodon) <a href="https://twitter.com/kiku_dondokodon/status/1359847197156671498?ref_src=twsrc%5Etfw">February 11, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

↑の2枚目の画像ですが、清書したものを間違って捨ててしまったので
とても汚いですね・・・。
(余談ですが、使用している方眼紙は無印のものです。推しております！)

ちなみに、ラフの時点でマークアップやfont-sizeなども
ある程度決めております。

ラフの時点で決めておくと、デザイン作成もコーディングも少しは楽になるかと思います。


#### デザイン作成 - 作成
![img-photoshop01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1142450/605eaa64-e5af-51ba-0187-a0de1a996636.jpeg)
複数ページのサイトだったら、ページごとにデータを作成しますが、
今回はTOPだけなので、必要なものを全部まとめています。
(TOPデザイン、favicon、ogp、モーダルウィンドウ3種)

アートボードの横幅ですが、**シェア率が高いデスクトップサイズの1920px**にしています。
コンテンツ幅は無難な1000pxにして、ノートPCサイズでもちゃんと表示されるようにデザインを作成します。

ディスプレイサイズのシェア率、こちらを参考にしております。
[モニター解像度のシェアを調べてみた（2020年1月版） | webseeya](https://webseeya.com/display-resolution-2015/)

..........................................

#### コーディング

デザインが完成したら、コーディング作業に入ります。
今回時短も兼ねて、[Percolator](https://github.com/TsubasaHiga/Percolator)というテンプレートを使用しました。
Scssの圧縮とか楽ですし、head内の必要な情報とかも揃ってるのでオススメです。


コーディングですが、もちろん最初はマークアップ作業から行っていきます。
とてもざっくりですが、こんな感じでマークアップをしています。

    <body>
        <!-- ヘッダー -->
        <header id="header" class="l-header">〜</header>

        <!-- メイン -->
        <main>
       　　　<!-- MV -->
            <div class="mv-area">〜</div>
            
       　　　<!-- コンテンツ -->
            <div class="contents-area">
                <section id="コンテンツ名01" class="contents-box コンテンツ名01"></section>
                <section id="コンテンツ名02" class="contents-box コンテンツ名02"></section>
                <section id="コンテンツ名03" class="contents-box コンテンツ名03"></section>
                <section id="コンテンツ名04" class="contents-box コンテンツ名04"></section>
            </div>
        </main>


        <!-- フッター -->
        <footer id="footer" class="l-footer"></footer>
    </body>

マークアップを行う際、**パッと見てで把握できるようにする**ことを心がけているので、
idとclassは該当する内容の名前を入れるようにしています。
(コンテンツブロックの大枠なら、contents-areaが例になります。)

マークアップが終わったら、コーディング作業に入ります。

----------
## 大体こんな感じです

全体的にすっごくざっくりとした説明になりましたが、本当に大体こんな感じです。
マークアップに関しては、5年近くもやっていたのもあって、体に染み付いているという感じなので・・・。
慣れてなんぼ、な感じですね。
Next.js(TypeScript) × microCMS × VercelでJamstackなポートフォリオ・ブログサイトを作った

## 成果物
https://prism-cube.com/

![PrismCube.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486153/fa044149-d8be-ed24-54e2-ac5f2d4892c9.png)

## 動機
今までは、VPSを借りてDjango × MySQLでポートフォリオ・ブログサイトを運用していたが、Next.jsの学習を進めていく中でヘッドレスCMS・Jamstackを知り、便利そう！となったので移行する事にした。

## 効果
月々の費用が、約1100円 → 0円になった。最高
Gitにプッシュした時・microCMSでコンテンツを編集した時など、デプロイを自動で設定できる。最高

## 感想
SSG・ISG・ヘッドレスCMS・ホスティングサービスなどなど初めて知る技術が多くあって、もっとキャッチアップしていかないといけないなあと感じた。
不便だと感じた事はたいてい誰かがすでに解決しているので、便利なサービスは積極的に使用していくべき！
次はGAE/Goとか触りたいなあ。

## 参考
https://blog.microcms.io/microcms-next-jamstack-blog/

https://qiita.com/o3c9/items/2551820edc156704edba
vimエラー　E45: 'readonly' option is set (add ! to override)が出た時の解決方法


##〜解決方法〜
上書き保存しようとした際に,以下のようなエラーが起きてしまい、保存することができず困っていました。

```
E45: readonly' option is set (add ! to override)
```

そんな時にこの問題を解決してくれたのが、以下のコードです

```
:wq!
```
エラーが出た際に、このコードを入力すると上書き保存され無事解決しました！


##〜参考〜
No.2の回答者様の回答を参考させていただきました。
https://oshiete.goo.ne.jp/qa/2165788.html


##最後に
ありがとうございました！
疑問: href="#" は正しい表現か？

調査
----
まずhref の中身について許されるものはURL であるが"妥当なURL"についてHTML Living Standard(HTML の正統な最新の仕様書) を調べる。

妥当なURL とは？
https://triple-underscore.github.io/URL-ja.html#valid-url-string
>妥当な URL 文字列 は、次のいずれかでなければならない：
> - 素片付き相対 URL 文字列
> - 素片付き絶対 URL 文字列

素片とはフラグメント"#..." のことである。

今回調査したい"#"は # 文字の前後が空文字列である、"**空文字列1**#**空文字列2**" という形であり、空文字列1, 空文字列2 がこの場所にあり得るかを確認していく。

まず空文字列1 は相対パスの表現にあたる。
https://triple-underscore.github.io/URL-ja.html#path-relative-url-string
>パス相対 URL 文字列は、次をいずれも満たす文字列でなければならない：
>	- U+002F (/) で区切られた［0 個以上の URL パス区分文字列］からなる
>	- U+002F (/) から開始されていない

空文字列1 の場所に"" が許されていると読める。

次に空文字列2 を調べる。ここにはフラグメント名が入る。
https://triple-underscore.github.io/URL-ja.html#url-fragment-string
>URL 素片文字列 は、［ 0 個以上の URL 単位からなる並び ］でなければならない。 
	
フラグメント名は"" でよい。

**空文字列1** も**空文字列2** も妥当なURLであることが確認できた。

結論
----
href="#" の表現は正しい。（ブラウザで動作確認するとページトップへのジャンプになる)

補足
----
なお、ページ自身を示す時にはhref 自体を省略することで表現できる。
https://momdo.github.io/html/text-level-semantics.html#the-a-element
>サイトがすべてのページに一貫性のあるナビゲーションツールバーを使用する場合、通常ページ自身へリンクするリンクは、a要素を使ってマークアップできる：
>```
><nav>
> <ul>
>  <li> <a href="/">Home</a> </li>
>  <li> <a href="/news">News</a> </li>
>  <li> <a>Examples</a> </li> <!-- ここに注目. href 属性が省略されている. -->
>  <li> <a href="/legal">Legal</a> </li>
> </ul>
></nav>```

実験してみると、Examples をクリックしたあとページトップにジャンプし、URL の最後に"#" が追加される。なあんだ、href="#" と解釈されているのか。
PostgreSQLのセットアップ

## インストール
```bash
sudo apt install postgresql

# citext用
sudo apt install postgresql-contrib
```

## DBとユーザーの作成
```bash
$ sudo su postgres
$ psql
> create database db_name;
> create user k0kubun with password '*******';
> grant all privileges on database db_name to k0kubun;

$ psql db_name
> create extension citext;
```

## listenアドレスの変更
`/etc/postgresql/12/main/postgresql.conf` で以下のような設定を足す。

```conf 
#listen_addresses = 'localhost'
listen_addresses = '*'
```

## 接続元の設定
`/etc/postgresql/12/main/pg_hba.conf` に以下のような設定を足す。

```
host    all             all             123.321.123.321/32      md5
```

最後にpostgresqlをrestartする。
CypressでE2Eテストの基本情報

# Cypressとは

オールインワンのE2EテストフレームワークとSaaS。

[Cypress (公式サイト)](https://www.cypress.io/)

[E2EテストをSelenium Webdriver からCypress.io に移行した話](https://user-first.ikyu.co.jp/entry/2019/04/23/090000)

[Cypressで始めるReactのE2Eテスト-導入から実際にテストを書いてみよう！](https://microcms.io/blog/cypress-react-e2e/)

[打鍵テストをCIで回す：Cypress on GitHub Actions](https://future-architect.github.io/articles/20200115/)

# インストール
環境： macOS Catalina

```
$ cd /your/project/path
$ yarn add cypress --dev
yarn add v1.22.10
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...

・・・中略・・・

✨  Done in 9.50s.
```

# 起動
以下のコマンドでGUIアプリケーションが起動する。

```
$ npx cypress open
```

![Cypress-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41382/3e35ae56-fd4c-783c-e450-0ce7cea267ce.png)

起動すると以下のディレクトリとファイルが作成される。


```
cypress
   ├─fixtures
   │    └─examples　・・・テストに使用するデータ
   ├─integration
   │    └─examples　・・・サンプルのテストコード(jsファイル)
   ├─plugins
   └─support
cypress.json ・・・設定ファイル
```

# テスト実行
サンプルのファイル名(例：actions.spec.js)をクリックすると、[Cypressのサンプル用Webサイト](https://example.cypress.io)を使ったE2Eテストのサンプルが実行される。

画面左側がテストの記録、右側がテスト対象のWebサイト。テストに沿って自動で文字が入力されたり、ボタンがクリックされていく。
![テスト実行.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41382/c0bb043f-6e9e-47c6-68d8-d77deedda087.png)


# CLIで実行
以下のコマンドで、`ｃｙｐress/integration`ディレクトリ以下の全部のテストが実行される。

```
$ npx cypress run
```

# 特定ファイルのみCLI実行

```
$ npx cypress run --spec cypress/integration/mytest.spec.js
```


# Dashboard設定
https://dashboard.cypress.io/ でアカウントを作成する。
Organization作成、Project作成する。
そしてProjectのRecord Keyをゲット。


--keyでRecord Keyを渡すと、Cypressのクラウド(Dashboard)にデータが送信される。

```
$ npx cypress run --record --key ********-****-****-****-************
```

CYPRESS_RECORD_KEY

# Dashboardで閲覧
CLIで実行したテストの結果がクラウドのDashboardで閲覧できる。
有償サービスだがFreeプランでも1つのOrganizationで3ユーザー、500回/月の実行（Dashboardへの記録）が可能。

![Dashboard Overview](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41382/f68cc826-b9c3-7cfb-e71a-7d9c1082608f.png)

テストの様子を動画で確認できる。これは便利！
静止画のスクリーンショットを撮る機能もある。
![Dashboard Test Result Video.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41382/6864202c-802e-7c15-8f70-e0e026779599.png)

#CI
### 公式ドキュメント
https://docs.cypress.io/guides/guides/continuous-integration.html

### GitHub Action / Cypress Screenshot & Video Upload to Slack
https://github.com/marketplace/actions/cypress-screenshot-video-upload-to-slack
アロー演算子"->"とスコープ定義演算子"::"

##オブジェクト指向で見かける二つの演算子についてまとめ

改めてどういった違いがあるのか調べたので備忘録として残します。

### アロー演算子
`->`はインスタンスプロパティやインスタンスメソッドにアクセスする際に利用します。

```
<?php

class User
{
    private $name;
    private $email;

    public function __construct($name, $email)
    {
        $this->name = $name;
        $this->email = $email;
    }
    public function hello()
    {
        echo "Hello";
    }

    public function getEmail()
    {
        echo "あなたのメールアドレスは" . $this->email;
    }
}
```
上記のようなUserクラスがあった場合、

```
$taro = new User('taro', 'taro@dummy.com');
$taro->hello(); 
//出力結果 Hello

$taro->getEmail();
//出力結果 taro@dummy.com
```
インスタンスを作成し、`->`を利用してアクセスすることができます。
`$インスタンスを代入した変数名->呼び出したいインスタンスのプロパティorメソッド`と書きます。

インスタンスから呼び出す動的なインスタンスプロパティやインスタンスメソッドへアクセスする際には -> を利用します。

つまりインスタンス化していなければ、`->`プロパティとメソッドにはアクセスすることができません。

インスタンス化していない場合、プロパティとメソッドにアクセスするときには次のスコープ定義演算子`::`を利用します。

###スコープ定義演算子
クラス定数やstatic変数など静的なプロパティ、メソッドにアクセスする際に利用します。
静的なメソッドはインスタンスを作成せずとも利用でき、全てのインスタンスに共通して使うことができます。

```
<?php

class User
{
    public static $age;
    private $name;
    private $email;

    public function __construct($name, $email)
    {
        $this->name = $name;
        $this->email = $email;
    }
    public function hello()
    {
        echo "Hello";
    }

    public function getEmail()
    {
        echo "あなたのメールアドレスは" . $this->email;
    }

    public function goodBye()
    {
       echo "Goodbye";
    }
}
```

先ほどのクラスに`static`なプロパティとメソッドを追加しました。

```
User::$age;
User::hello();
//出力結果 Hello

User::goodBye();
//出力結果 Goodbye
```
このように`::`でアクセスすることができます。
`クラス名::呼び出したいクラスのプロパティorメソッド`と書きます。

クラスから呼び出すような静的なプロパティやメソッドにアクセスする際には`::`を利用します。

ちなみにインスタンスメソッド内からアクセスしたい場合には`$this`を利用します。

先ほどのUserクラスでは`$this->name`でnameプロパティにアクセスしていますが、
インスタンス作成時に引数で`taro`を渡し、コンストラクタで`name`を`taro`で初期化しています。
PowershellでIE操作する時の設定と関数


PowershellでIE操作する方法を整理。必要な設定や関数等。

```posh
#エラー防止のアセンブリ読み込み
[System.Reflection.Assembly]::LoadFrom("C:\Program Files (x86)\Microsoft.NET\Primary Interop Assemblies\Microsoft.mshtml.dll")

#保護モード考慮のDOM操作関数
function OverrideMethod ([mshtml.HTMLDocumentClass]$Document) {
    $doc = $Document | Add-Member -MemberType ScriptMethod -Name "getElementById" -Value {
        param($Id)
        [System.__ComObject].InvokeMember(
            "getElementById",
            [System.Reflection.BindingFlags]::InvokeMethod,
            $null,
            $this,
            $Id
        ) | ? {$_ -ne [System.DBNull]::Value}
    } -Force -PassThru

    $doc | Add-Member -MemberType ScriptMethod -Name "getElementsByClassName" -Value {
        param($ClassName)
        [System.__ComObject].InvokeMember(
            "getElementsByClassName",
            [System.Reflection.BindingFlags]::InvokeMethod,
            $null,
            $this,
            $ClassName
        ) | ? {$_ -ne [System.DBNull]::Value}
    } -Force

    $doc | Add-Member -MemberType ScriptMethod -Name "getElementsByTagName" -Value {
        param($TagName)
        [System.__ComObject].InvokeMember(
            "getElementsByTagName",
            [System.Reflection.BindingFlags]::InvokeMethod,
            $null,
            $this,
            $TagName
        ) | ? {$_ -ne [System.DBNull]::Value}
    } -Force

    return $doc
}

#IEでjavascript実行する関数
Function ExecJavaScript($ie, $jsCommand, [switch]$global)
{
    if (!$global) {
        $jsCommand = "document.body.setAttribute('PSResult', (function(){$jsCommand})());"
    }
    $document = $ie.document
    $window = $document.parentWindow
    $window.execScript($jsCommand, 'javascript') | Out-Null
    if (!$global) {
        return $document.body.getAttribute('PSResult')
    }
}

#JQueryの有無確認
Function CheckJQueryExists
{
    $result = ExecJavaScript $ie 'return window.hasOwnProperty("$");'
    return ($result -eq $true)
}
```

ネタ元
なにか作ってみるよ。: 【解決】PowerShellでInternetExplorerを操作するときにエラーが発生
https://nanitsuku.blogspot.com/2013/10/powershellinternetexplorer.html

PowershellでInternetExplorerを操作する - Qiita
https://qiita.com/flasksrw/items/a1ff5fbbc3b660e01d96

jquery - Powershell:InternetExplorer.Applicationを介したjQueryの使用 - ITツールウェブ
https://cloud6.net/so/jquery/1657650
$@に「”dir1/　dir2/”」 としたら$1に2つともディレクトリとしてちゃんと格納された

初めましてshoです。

”tarアーカイブしたものを別のサーバにコピーする”
というシェルスクリプト作成の際に初心者過ぎてこんなこと考えました。

「<font color="red">＄＠に複数のディレクトリもアーカイブファイル名も接続先のホスト名もIPもパスも全部入れたい。でもディレクトリが決まった個数ではない場合どうすればいいんだ・・・</font>」
※後日こんなに難しくしなくていいって言われました



調べてもそれっぽい記事が見つからなかったので試しに
”dir1 dir2”　と書いてみました。
結果、「＄１に二つともちゃんとディレクトリとして入ってる！」


もしかしたら普通に使われていること？
それともそもそもそんな使い方しない？

そこらへんはわかりませんがめっちゃ感動しました。


それでは以下私がテストした内容です。


（※学習記録やメモ書き目的で始めました。ほぼ初学者レベルなので理解が浅いところや誤りがあるかと思いますがよろしくお願いします。またアドバイス等コメントいただけるとすっごく嬉しいです。早く先輩方のお力になれるよう精進します。）

#テストした内容

* スクリプト実行時　「スクリプト名　”dir1/ dir2/ dir3/” file1 file2」として＄１〜＄３に格納しtarアーカイブする
* echo で＄１〜３を出力
* アーカイブされたものがちゃんと元のディレクトリか展開する


##シェルスクリプト

```

      1 #!/bin/sh
      2 
      3 echo '$1=' $1
      4 echo '$2=' $2
      5 echo '$3=' $3
      6 
      7 
      8 tar_name="$(date +%Y%m%d).tar"
      9 
     10 tar -cvf ${tar_name} $1
     11 
           
```

##テスト
**テストで使うディレクトリ、ファイル一覧**

```

# ls -FR
.:
dir1/  dir2/  dir3/  file1  file2  file3

./dir1:
file1  file2

./dir2:
file2  file3

./dir3:
file3
```


**シェルスクリプト実行と実行結果**

* スクリプト実行時　「スクリプト名　”dir1 dir2 dir3” file1 file2」として＄１〜＄３に格納しtarアーカイブする
* echo で＄１〜３を出力

```

# test-tar "dir1/ dir2/ dir3/" file1 file2
$1= dir1/ dir2/ dir3/
$2= file1
$3= file2
dir1/
dir1/file1
dir1/file2
dir2/
dir2/file2
dir2/file3
dir3/
dir3/file3

# ls
20210312.tar  dir1  dir2  dir3  file1  file2  file3 

```

**実行結果の確認**

* アーカイブされたものがちゃんと元のディレクトリか展開する

```

# rm -rf dir1  dir2  dir3  file1  file2  file3
# ls
20210312.tar
# tar xvf 20210312.tar
dir1/
dir1/file1
dir1/file2
dir2/
dir2/file2
dir2/file3
dir3/
dir3/file3
# ls
20210312.tar  dir1  dir2  dir3
# ls -RF
.:
20210312.tar  dir1/  dir2/  dir3/

./dir1:
file1  file2

./dir2:
file2  file3

./dir3:
file3 


```



改めて、こんな使われかたしているのか疑問、不安ですが、ちょっといい発見した気分です。

以上！
nextjsのapi routeをローカルでは問題が出ないのにvercelに置いた途端挙動不明になる場合

# 症状

こういう感じのPromise絡みの処理があり、最後にstatus:200を返してる。
これはローカルだと意外とすんなり動く。が、これをvercelすると途端に動いたり動かなかったり、エラーになったり、わけがわからない状態が続く。

```ts:ローカルだと問題がないパターン
import admin from "./my-firebase-admin"
import type { NextApiRequest, NextApiResponse } from "next"

class VeryComplicatedProcesses{
  process(){
    admin.firestore().collection("...").get().then((snapshot) => {
      if(snapshot.empty){
        // 処理 ... 
        // ローカルだとこれは意外と動く
      }
    })
  }
}

export default (req: NextApiRequest, res: NextApiResponse) => {
  const vcp = new VeryComplicatedProcesses()
  vcp.process()
  res.status(200).end()
}
```


# 問題

良くは調べてないが、多分ローカルだとサーバーは常駐しているので処理が途中で切られることはないが、vercel上だと常時サーバーを起動させている様子ではなく、必要最低限でサーバーが起動・停止を繰り返しているよう。
なので、Promiseを待たずにstatus:200を送ってると、その時点でサーバーが破棄される？とかで非同期処理が終わらないままになってしまう。

# 解決方法1

最初async/awaitをこういう感じ付けてやってみたが、意外とこれもコケたりコケなかったり挙動不審になる。使ってる非同期処理がfirestoreだったので初期起動とかに時間がかかる場合、どこかでタイムアウトになっている様子。

```ts
export default async (req: NextApiRequest, res: NextApiResponse) => {
  const vcp = new VeryComplicatedProcesses()
  await vcp.process()
  res.status(200).end()
}
```

# 解決方法2 - うまく行ってる

API route自体にPromiseをreturnで送りつけてやる（[参考][1]）。こうすることでサーバー側はPromiseの処理終わりで送られるstatus:200を受け取り、処理を終了することになる。

Promiseを最終的にroute側に返すために、自身の処理を見直して

1. どこでPromiseとして返すべきか
2. どこでasync/awaitを使えるのか
3. 処理内で複数のPromiseがある場合、Promise.allなどを使う必要があるか？

などをよく検討しないといけない。

```ts
class VeryComplicatedProcesses{
  process(): Promise<void>{
    return admin.firestore().collection("...").get().then((snapshot) => {
      if(snapshot.empty){
        // 処理 ... 
        // ローカルだとこれは意外と動く
      }
    })
  }
}

export default (req: NextApiRequest, res: NextApiResponse) => {
  const vcp = new VeryComplicatedProcesses()
  // promiseをそのまま渡してやる
  return vcp.process().then(() => {
    // 処理が全て終わった時点でstatus:200
    res.status(200).end()
  })
}
```


# デバック方法

ローカルで次のようにやってみると意外と視覚的にわかりやすかった。

最後に来るべきの`console.log('res.status(200).end():')`より後にログが出るのはおかしい。

```ts:適当に書いただけなので...
import admin from "./my-firebase-admin"
import type { NextApiRequest, NextApiResponse } from "next"

class VeryComplicatedProcesses{
  async process(): Promise<void>{
    const promises = [
      this.processA(),
      this.processB()
    ]

    // この中にPromiseが入っていることを確認
    // Typescriptなら戻り値の型宣言でチェックできるが、JSだとreturn漏れが起きやすい
    console.log('promises:', promises)
    
    await Promise.all(promises)
    console.log('Promise.all:')
  }

  processA(): Promise<YourGeneric> {
    // 何らかの非同期処理 promiseをそのまま返す
    return PromiseReturning.call()
  }
  
  processB() {
    // 何らかの非同期処理 promiseをそのまま返す
    return PromiseReturning.anotherCall(async (object) => {
      // この匿名関数の中だけでasync/awaitで同期処理
      await object.some()
      object.property
      console.log('object.property:', object.property)
    })
  }
}

export default (req: NextApiRequest, res: NextApiResponse) => {
  const vcp = new VeryComplicatedProcesses()
  return vcp.process().then(() => {
    console.log('res.status(200).end():')
    res.status(200).end()
  })
}
```

[1]: https://github.com/vercel/next.js/discussions/16698#discussioncomment-81790
Hololensとの戦いを始めました

「そもそもHololens2ってなに？」って人はとりあえず[こちら](https://www.microsoft.com/ja-jp/hololens/hardware)
## 体験は衝撃だった
とあるイベントでHololens2を被りましたが、個人的には衝撃でした。
（中身の話は機会があれば書きます）
そして『開発してみたい！』という衝動で買ってしまった。

## 買ったはいいが

問題はここから、筆者は3Dに関して全くの素人
「Unity?ゲームの最初に表示されるロゴだよね、プラットフォームでしょ？」
「3Dモデルとかどんなソフトで作ってるんだろう？」なレベルなこと。

デスクトップアプリケーション開発(C# + XAML)で仕事はしているが、
周りに聞ける人もいない（今後は開発コミュニティに参加はするが・・）状態なので、
普通はこの条件で撤退するでしょう。

## そうは言っても

買ってしまった以上はなにかしたい。
（というか形はどうあれ40万オーバーの機材買って収穫なしでは流石に後悔でメンタル削れます）
## そんなわけで

今後その立ち向かうさまを記事にして行く予定です。
その記事を読んで参入・撤退を決める参考にしていただければいいかなと。

こっそり「困った」記事のコメント欄に素晴らしい先輩諸氏が登場することを期待してたり・・・

それでは次の記事でお会いしましょう。
SourceTreeをコマンドラインから現在のディレクトリを指定して開く方法

## GUIから目的のレポジトリを開くのは面倒

 ①該当レポジトリでコマンドラインで作業中に、SourceTreeを開きたいと思う
 ②SourceTreeを開く
 ③レポジトリ一覧から目的のレポジトリを探す
 ④クリックする

と手数を3つも踏む必要がある。
何よりGUIは1手数に時間がかかってめんどくさい度が高い。
 
①でコマンドライン上で既に該当レポジトリにいるのだから、手数は1つで済むはず。
 
## コマンドラインから現在のレポジトリを開く
### 現在のレポジトリをSourceTreeで開くコマンド
```
open -a SourceTree .
```
### 手順
 ①該当レポジトリでコマンドラインで作業中に、SourceTreeを開きたいと思う
 ②上記コマンドを叩く
 完了！
かなりストレスが軽減される

## aliasを登録するともっと便利
```
alias st="open -a SourceTree ."
```
とaliasを登録しておけば、

```
st
```
と打つだけですぐに開ける。脳死で開けるようになる。

## 参考
https://stackoverflow.com/questions/19663202/how-do-you-open-sourcetree-from-the-command-line