TypeScript+webpack環境を作る - babel使う版
TypeScriptをはじめてみる - コピペコードで快適生活 の続き
必要なライブラリをインストール
npm install --save-dev webpack webpack-cli typescript babel-loader @babel/core @babel/preset-typescript
- webpack:
- モジュールバンドラー。
- JavaScript等の複数のファイルを1つにまとめる。
- loaderを組み込むことで、まとめる前に変換処理(ES2015→ES5など)を加えることができる。
- webpack-cli:
- webpackのcli
- babel-loader:
- webpackにbabelの変換処理を組み込むloader
- babelは古いブラウザで動くJavaScriptに変換するツール群
- @babel/core:
- babelのコア機能
- @babel/preset-typescript
- TypeScript→JavaScriptの変換を行う
- babelでの変換処理本体は、プラグインとして提供される
- @babel/preset-env は最新のJavaScriptからの変換を行う
${APP_DIR}/package.json
の更新
scriptsにビルドコマンドを追加する
{ "scripts": { "watch": "webpack --watch", "build": "webpack --mode production" }, "devDependencies": { "@babel/core": "^7.14.8", "@babel/preset-typescript": "^7.14.5", "babel-loader": "^8.2.2", "typescript": "^4.3.5", "webpack": "^5.45.1", "webpack-cli": "^4.7.2" } }
${APP_DIR}/tsconfig.json
の作成
TypeScriptをどのように変換するかを設定する
{ "compilerOptions": { "sourceMap": true, "target": "ES5", // TSはECMAScript 5に変換 "module": "ES2015" // TSのモジュールはES Modulesとして出力 } }
- CommonJSのモジュール:
- require/module.exportsで外部JSファイルを扱う
- Node.jsが採用している
- tsconfig.jsonのデフォルト
- ES Modules:
- import/exportで外部JSファイルを扱う
- ES2015が採用している
- webpackのTree Shaking(未使用のimportを振り落とす)が効く
${APP_DIR}/webpack.config.js
の作成
webpackのバンドル設定を行う
const path = require('path') module.exports = { // production: 改行やインデントを削除してJSファイル出力 // development: ソースマップ有効でJSファイル出力 // ただし `webpack --mode production` したときは production が有効になる mode: 'development', // 入力元の指定 entry: { index: path.join(__dirname, '/src/index.ts'), }, // 出力先の指定 output: { path: path.join(__dirname, 'dist'), filename: '[name].js', }, module: { rules: [ { test: /\.ts$/, // 拡張子 .ts のファイルを loader: 'babel-loader', // babelでトランスパイルする options: { presets: ['@babel/preset-typescript'] }, exclude: /node_modules/, // ただし外部ライブラリは除く }, ], }, // import './MyLib.ts' が // import './MyLib' の書き方でOKになる resolve: { extensions: [ '.ts', '.js', ], }, };
tsファイルを書いてみる
${APP_DIR}/src/index.ts
import { Animal } from './Animal'; let animal = new Animal("cat", "pipimi"); animal.say();
${APP_DIR}/src/Animal.ts
export class Animal { animaltype: string; name: string; constructor(animalType: string, name: string) { this.animaltype = animalType; this.name = name; } say() { console.log(`Hello. I am ${this.name} of ${this.animaltype}.`); } }
ビルドする
npm run build
参考
TypeScriptをはじめてみる
TypeScriptの雰囲気を掴むために、5分でできるチュートリアルをやってみる。
環境の準備
PC環境は汚したくないので、dockerで環境を作る。
#{APP_DIR}/docker-compose.yml
に以下を書く
version: '3' services: node: image: node volumes: - "./:/var/app" tty: true
コンテナを起動してログインする
docker-compose up docker-compose exec node /bin/bash
TypeScriptをインストール
cd /var/app npm install -g typescript
TypeScriptを書いていく
#{APP_DIR}/greeter.ts
を書いていく
// クラスの定義 class Student { // プロパティの宣言 fullName: string; // コンストラクタ // "引数名: 型" で引数の型指定ができる // 引数にpublicをつけることでプロパティとなる constructor(public firstName: string, public middleInitial: string, public lastName: string) { this.fullName = firstName + " " + middleInitial + " " + lastName; } } // インターフェースの定義 interface Person { firstName: string; lastName: string; } function greeter(person: Person) { return "Hello, " + person.firstName + " " + person.lastName; } // let user = { firstName: "Jane", lastName: "User"}; let user = new Student("Jone", "M.", "User"); document.body.innerHTML = greeter(user);
トランスパイルする
以下のコマンドでトランスパイルできる。 同じディレクトリにjsファイルができる。
tsc greeter.ts
参考:
Kubernetesの設定ファイルの書き方キホン
確認できる環境(minikube)の準備
$ brew install kubectl $ kubectl version --client $ brew install minikube $ minikube version
minikube コマンド
minikube start # 起動(デフォルトはDockerで起動) minikube status # 状態表示 minikube ssh # ホストOSにログイン minikube stop # 停止
※minikubeを起動すると、~/.kube/config
がよしなに変更されて、kubectlコマンドでminikube環境への接続が可能になる。
Pod
- 1個以上のコンテナの集まり
- 1Podに1コンテナ配置することが多い。
- 複数のコンテナでストレージを共有するようなケースでは1Podに複数コンテナを配置する
- Deploymentとセットで定義することが多いが、Pod単体を設定を書くこともできる。
- https://kubernetes.io/ja/docs/concepts/workloads/pods/pod-overview/
Deployment
- Podをどこにいくつ配置するかを管理するもの
- PodはDeploymentと紐付けられてデプロイされる
- Deploymentの設定ファイルの中にPodの設定(Podテンプレート)を含む
- https://kubernetes.io/ja/docs/concepts/workloads/controllers/deployment/
Deploymentの設定ファイル
apiVersion: apps/v1 # 固定値 kind: Deployment # 固定値 metadata: name: nginx-deployment # Deployment名 labels: app: nginx # Podテンプレートと同じ値 spec: # レプリカ数 replicas: 3 # デプロイメントの履歴数 # デフォルト値は10 revisionHistoryLimit: 5 # このDeployamentが管理するPodをどう見つけるかの定義 # 基本はPodテンプレートの`labels`と同じにすれば良い selector: matchLabels: app: nginx # Podテンプレート template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80 # コンテナが開けるポート
Deploymentの作成・確認・削除
$ kubectl apply -f nginx-deployment.yml # 設定をもとにオブジェクトを作成する $ kubectl get deployment # オブジェクトの一覧を表示する $ kubectl describe deployment nginx-deployment # オブジェクトの詳細情報を表示する $ kubectl delete -f nginx-deployment.yml # オブジェクトを削除する
Service
- Podにアクセスするためのゲートウェイ
- Pod自体は壊れたり作成される度にIPアドレスが変わるので、仲立してくれるService経由でアクセスする。
- https://kubernetes.io/ja/docs/concepts/services-networking/service/
Serviceの設定ファイル
kind: Service # 固定値 apiVersion: v1 # 固定値 metadata: # Serviceの名前 # 他のPodから `http://nginx-service` でアクセス可 name: nginx-service spec: # 接続タイプ # - ClusterIP クラスタ内部のみ接続可能(デフォルト値) # - NodePort クラスタ外から接続可能 type: NodePort # どのPodを対象にするか selector: app: nginx # 公開するポート ports: - name: http # 複数ポートを指定するときはname必須 protocol: TCP port: 80 # 受け口ポート targetPort: 80 # 転送先ポート - name: https protocol: TCP port: 443 # 受け口ポート targetPort: 443 # 転送先ポート
Serviceの作成・確認・削除
$ kubectl apply -f nginx-service.yml # 設定をもとにオブジェクトを作成する $ kubectl get service # オブジェクトの一覧を表示する $ kubectl describe service nginx-service # オブジェクトの詳細情報を表示する $ kubectl delete -f nginx-service.yml # オブジェクトを削除する
アクセスできるURLの確認
$ minikube service nginx-service --url http://192.168.64.2:32599
コンテナにログインする
以下のコマンドでPod一覧を表示する。
$ kubectl get pod NAME READY STATUS RESTARTS AGE nginx-deployment-5d59d67564-2gzp2 1/1 Running 2 2d1h nginx-deployment-5d59d67564-4mvjs 1/1 Running 2 2d1h nginx-deployment-5d59d67564-wlglr 1/1 Running 2 2d1h
で、NAME値を指定してkubecltコマンドを実行することで、sshログインができる。
kubectl exec --stdin -tty nginx-deployment-5d59d67564-2gzp2 -- /bin/bas
参考
シェルで古いファイルを一括で消す
バックアップスクリプトでよくやるのだけど、毎回書き方を忘れているのでメモ。
# -execオプションを使う版 # {} が対象のファイルパスに置換されて実行される。 # -mtime +3 => 最終更新日時が、過去〜4(3+1)日前のファイルを表示する find ${TARGET_DIR} -type f -mtime +3 -exec rm -f {}; # xargsを使う版 # こっちのほうが-execオプションより速い find ${TARGET_DIR} -type f -mtime +3 | xargs rm -f
バックアップ数の世代制限を超えたら消す場合はこんな
cd ${BACKUP_DIR}; REVISION_COUNT=`ls | wc -l`; if [ ${REVISION_COUNT} -gt 10 ]; then ls | head -1 | xargs -Rf rm fi
シェルスクリプトのアタマに添えるおまじない
シェルスクリプトを書くときに、アタマに添えるおまじないをメモ。
#!/bin/sh # set -e # スクリプトの実行中にエラー(exit 0以外)が発生すると、そこでスクリプトが終了させる。 # というかつけてないと、エラーしても次の処理に進むから怖い。 # # set -u # 未定義の変数を使用すると、そこでスクリプトが終了させる。 # # set -o pipefail # パイプの途中でエラーが起きた場合もエラーが発生させる。 set -euo pipefail # どのパスから実行しても、スクリプトのあるディレクトリにcdしてから実行する。 cd `dirname $0` # 以下、メイン処理を書く
参考
proxy先がTCPコネクションを切ったときブラウザには何が返るか
ブラウザ → proxy(nginx) → origin(apache)
の通信経路で、originがTCPコネクションを切った場合、proxyは50xを返す。proxy(nginx)にはこんなログが出る。
proxy_1 | 2021/07/01 13:15:38 [error] 25#25: *2 upstream prematurely closed connection while reading response header from upstream, client: 172.20.0.1, server: localhost, request: "GET /php/ HTTP/1.1", upstream: "http://172.20.0.2:80/", host: "localhost" proxy_1 | time:01/Jul/2021:13:15:38 +0000 remote_addr:172.20.0.1 host:localhost scheme:http req:GET /php/ HTTP/1.1 status:502 size:494 response_time:5.655referer:- agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36 upstream_addr:172.20.0.2:80 upstream_cache_status:- upstream_response_time:5.656
ブラウザで、ERR_CONNECTION_CLOSEDが出る場合は、ブラウザとproxy間の通信が切れたもの。
MySQLのバッファプール使用状況を確認する
ダーティページの使用状況を確認したかったので。
mysql> SHOW GLOBAL STATUS LIKE 'InnoDB\_buffer\_pool%'; +-----------------------------------+---------------+ | Variable_name | Value | +-----------------------------------+---------------+ | Innodb_buffer_pool_pages_data | 464754 | # バッファプール内のデータ合計 | Innodb_buffer_pool_pages_dirty | 0 | # ダーティページ | Innodb_buffer_pool_pages_flushed | 51792309 | # ディスクフラッシュしたページ数 | Innodb_buffer_pool_pages_free | 0 | # バッファプールの空き | Innodb_buffer_pool_pages_misc | 59534 | | Innodb_buffer_pool_pages_total | 524288 | # バッファプール内のページ数 | Innodb_buffer_pool_read_ahead_rnd | 82900402 | | Innodb_buffer_pool_read_ahead_seq | 41051358 | | Innodb_buffer_pool_read_requests | 2642185748634 | # バッファプールから読んだページ数 | Innodb_buffer_pool_reads | 1272273714 | # ディスクからバッファプールにロードしたページ数 | Innodb_buffer_pool_wait_free | 0 | | Innodb_buffer_pool_write_requests | 320720943 | # バッファプールに書いたページ数 +-----------------------------------+---------------+ 12 rows in set (0.00 sec) mysql> SHOW GLOBAL STATUS LIKE 'Innodb\_pages%'; +----------------------+------------+ | Variable_name | Value | +----------------------+------------+ | Innodb_pages_created | 1073458 | # バッファプールに作成したページ数 | Innodb_pages_read | 6795625969 | | Innodb_pages_written | 51793282 | # ディスクフラッシュしたページ数 +----------------------+------------+ 3 rows in set (0.00 sec)