ページ
▼
2020-12-21
tmuxで複数の開発サーバーを一括で起動する
Next.jsを複数動かす必要があったり、SPAをwatchしつつバックエンドも起動しておく、みたいな開発環境の場合、ひとつひとつ立ち上げるのは手間なので、tmuxで一括起動するスクリプトを作った。バックエンドは左にでかく、フロント達は右に、みたいなのは考慮せず、縦に並べるだけ。
2020-07-16
Lian-Li PC-Q21B + ASRock J4105-ITX で PC を組んだ
MSI N3150I ECO と Ubuntu 14.04.3 の罠 で書いたPCが壊れてしまった(おそらく電源がいかれた)ので、PCを組んだ。ROCK64 / Raspberry Pi 4 との戦いにつかれた。
構成は以下の通り。用途によっては良い構成だと思うので、後々の参考のためメモ。
以前のIW-BM639が(W)112mm x (H)264mm x (D)230mmなのに対し、PC-Q21Bは(W)149mm x (H)257mm x (D)224mmなので幅がだいぶ大きい感じ。でも、汎用のSFX電源が積めてフルハイトのPCI-Expressボードが入るとなると、妥当じゃない?という感じで、結構気に入っている。かわいいし。DVDドライブの部分がスロットイン限定ならなくてよくない?というのはいまいちだけど。
サンワサプライのワットモニター(TAP-TST8N)を買ってみたので測ってみると消費電力は15Wほど。RasPi4 (+HDD)が5Wほどなので、さすがと思いつつまぁ15WはPCとして見たらいいんじゃないかな。
構成は以下の通り。用途によっては良い構成だと思うので、後々の参考のためメモ。
M/B(CPU) | ASRock J4105-ITX (Celeron J4105) | |
メモリ | Kingston KVR26S19S6/4 (SODIMM DDR4 PC4-21300 4GB) | |
HDD | TOSHIBA MQ04ABF1 (1TB 5400rpm 2.5") | |
ケース | Lian-Li PC-Q21B | |
電源 | SilverStone SST-ST30SF V2 | |
ケースファン | アイネックス Omega Typhoon G 120mm CFZ-120GLA | |
ケース内USBケーブル | サンワサプライ USBケーブル 0.4m TK-USB2 |
以前のIW-BM639が(W)112mm x (H)264mm x (D)230mmなのに対し、PC-Q21Bは(W)149mm x (H)257mm x (D)224mmなので幅がだいぶ大きい感じ。でも、汎用のSFX電源が積めてフルハイトのPCI-Expressボードが入るとなると、妥当じゃない?という感じで、結構気に入っている。かわいいし。DVDドライブの部分がスロットイン限定ならなくてよくない?というのはいまいちだけど。
サンワサプライのワットモニター(TAP-TST8N)を買ってみたので測ってみると消費電力は15Wほど。RasPi4 (+HDD)が5Wほどなので、さすがと思いつつまぁ15WはPCとして見たらいいんじゃないかな。
2020-07-05
emotionの内部構造(CSS-in-JSの裏側)
書いたスタイルがどうなるかという観点でemotion(emotion-js) v10の内部構造を調べたので図にした。styled-componentsもざっと見たけど、だいたい同じような感じ。
emotionをReactと組み合わせて使う場合、基本的には以下の動きをする(SSRが入るとちょっと違う)
Reactでない他の枠組みと統合するときは、以下を作ることになるかなという感じ。
emotionをReactと組み合わせて使う場合、基本的には以下の動きをする(SSRが入るとちょっと違う)
- css`` あるいは styled.hoge`` が、SerializedStyles (ほぼ書いたとおりの状態のスタイルを表現するオブジェクト)を作る。ハッシュ+ラベルでnameがつく。
- ラップするための「jsx」関数か「styled」のコンポーネントが、React Contextを使ってEmotionCacheを探し出して、SerializedStylesをinsertStyles()する。
- EmotionCacheが、stylisでSerializedStylesを加工する(実際に使われるスタイルはここでできる)。
- stylisプラグインが、StyleSheetオブジェクトを経由して、containerに指定された要素(デフォルトではdocument.head)にstyle要素を挿入する。
- 「jsx」関数か「styled」コンポーネントが、スタイル適用された要素をclassNameを渡すことで作る。
Reactでない他の枠組みと統合するときは、以下を作ることになるかなという感じ。
- cacheをつくるところ
- (SerializedStyleを作るところ→css`` をそのまま使うのでもあり)
- cacheを見つけてinsertするところ
2020-06-30
virt-install + cloud-initでUbuntu 20.04をインストールする
Ubuntu 20.04 (focal)のVMをいつもの通りvirt-installと--locationを使ってセットアップしていたら、WARNINGに遭遇したので、気になっていたcloud-initでインストールしてみたところうまくいったのでまとめる。
今回の主な設定内容は以下の通り。
ファイルにするとこんな感じ。 ここで注意すべきなのは、networkは別ファイルだということと、disk_setupに罠があるということ。
examplesによく出てくるdisk_setupのlayout: Trueは ドキュメントを読むと、
設定ファイルが並ぶ感じになると思うので、gitで並べる用のテンプレートを作った。hosts/{hostname}以下にconfigファイルを書いて./build-images.shするとbuild/にできる。 https://github.com/sunnyone/cloud-init-configs
sudo virt-install (略) --location 'http://ftp.jaist.ac.jp/pub/Linux/ubuntu/dists/focal/main/installer-amd64/' --extra-args 'console=ttyS0,115200n8 serial' WARNING Using legacy d-i based installer, that has been deprecated and will be removed in the future. https://discourse.ubuntu.com/c/server
概要
Ubuntu 20.04 ServerのVM「cloudtest」をUbuntu Cloud Imagesのイメージを使って、virt-installでセットアップする。 ディスクは、"vg0"というLVM volume groupにroot用, swap用のvolumeを作成して利用する。LVMでボリュームの作成
lvcreateでボリュームを作る。$ sudo lvcreate -n cloudtest-root -L 8G vg0 $ sudo lvcreate -n cloudtest-swap -L 4G vg0
イメージのダウンロードと展開
cloud-images.ubuntu.comからイメージをダウンロードする。QCOW2 Image (v2)形式らしいので、qemu-img convertを使って、rawイメージに変換しつつLVM volumeに流し込む。$ wget https://cloud-images.ubuntu.com/releases/20.04/release/ubuntu-20.04-server-cloudimg-amd64.img $ sudo qemu-img convert ubuntu-20.04-server-cloudimg-amd64.img -O raw /dev/vg0/cloudtest-root
cloud-init用の設定ファイルの作成
Ubuntu Cloud Imagesでは、インストーラでの設定入力ではなく、cloud-initで初期設定を行う。 NoCloudデータソースでは、設定内容をイメージから読んでくれるので、それを使う。そのイメージのための設定ファイルをまず用意する。 (詳しくは第561回 ローカルインストール時もcloud-initを活用する:Ubuntu Weekly Recipeを参照)今回の主な設定内容は以下の通り。
- ホスト名
- ユーザー名・初期パスワード
- パーティションテーブルの作成
- ファイルシステムの作成
- マウントポイントの設定
- ネットワーク
ファイルにするとこんな感じ。 ここで注意すべきなのは、networkは別ファイルだということと、disk_setupに罠があるということ。
examplesによく出てくるdisk_setupのlayout: Trueは ドキュメントを読むと、
The layout option specifies how partitions on the device are to be arranged. If layout is set to true, a single partition using all the space on the device will be created.とのことだが、新しめの環境とmbrでは機能しないので、Trueと同じように100%の領域を使いたい場合は以下のように指定する。
disk_setup: /dev/vdb: table_type: 'mbr' layout: - [100] overwrite: False詳しくはBug #1851438 “cloud-init disk_setup fails to partition disk for ...” : Bugs : cloud-initを参照。
設定ファイルが並ぶ感じになると思うので、gitで並べる用のテンプレートを作った。hosts/{hostname}以下にconfigファイルを書いて./build-images.shするとbuild/にできる。 https://github.com/sunnyone/cloud-init-configs
cloud-init用のイメージの作成
cloud-init用のイメージの作成にはcloud-localdsコマンドが便利なので、cloud-image-utilsパッケージをインストールして使う。$ sudo apt install cloud-image-utils $ cloud-localds --network-config network-config.yaml user-data.img user-data
virt-installの実行
これで準備できたので、virt-installを実行してVMを作る。sudo virt-install \ --name cloudtest --ram 512 --arch x86_64 --vcpus 1 \ --os-type linux --os-variant ubuntu20.04 \ --disk path=/dev/vg0/cloudtest-root \ --disk path=/dev/vg0/cloudtest-swap \ --disk path=$PWD/user-data.img,device=cdrom \ --network bridge=br0,model=virtio \ --graphics none --serial pty --console pty \ --importしばらくしたら設定が完了して、sshでログインできる。
cloud-init設定のデバッグ
インストーラと違って対話的でないので、うまくいかないときは積極的なデバッグが必要。 基本的にはログを見ると良くて、ログは以下の場所にある。- /var/log/cloud-init-output.log
- /var/log/cloud-init.log
$ sudo rm -rf /var/lib/cloud/*
cloud-init用のイメージのeject
最後にuser-data.imgを外してあげておしまい。$ sudo virsh change-media cloudtest sda --eject --config
2020-06-16
AWS Lambda + TypeScript の構成メモ
AWS Lambda の関数を Node.js + TypeScriptで書くとき、どのような構成にすると便利かまとめたメモ。デプロイにはAWS SAMを使うことを想定。
ディレクトリ構造
src/ts/functions/(スタック名)/(関数名).ts をwebpackのエントリポイントとして、以下のようなディレクトリ構造にする。src/ templates/ # CloudFormationテンプレート ts/ functions/ (スタック名)/ (関数名).ts # エントリポイント cli/ (関数).ts # コマンドラインでの動作確認 lib/ # 共通コード群(AWS Lambdaのランタイムに依存しない部分) foo/ bar.tsスタック名があるのは、デプロイパッケージ(zip)をスタック単位にすることを想定。デプロイツールの都合でここは調整したほうがいいかも。
コマンドラインで動作確認できるようにする
AWSのリソースを操作する系のLambda関数を実装する場合、その処理をコマンドラインで実行できるようにしておくと便利。 cli/にコードを配置し、ts-nodeを使ってpackage.jsonの"scripts"で呼び出せるようにしておく。"scripts": { "cli:my-operation": "ts-node src/ts/cli/my-operation.ts", }コードとしては、yargsでコマンドライン引数を解析して、関数に渡すだけのイメージ。
$ yarn cli:my-operation -a my-arg
webpack設定
node_modulesを持っていけば動くのだが、productionのみにしたりと面倒なので、webpackする。 例としては、こんな感じ。 ポイントは、externals: ["aws-sdk"]。標準のものやLambda Layerで提供しているものはここで除外する。ネイティブモジュールは、Lambda Layerで提供すると良いと思う。minimize: falseはコンソールで読む用。どっちでもいい。tsconfig.json
Node v12のときはtarget: es2019。moduleはcommonjs。source-map-supportを入れる
webpackするとスタックトレースが不便になるので、source-map-supportを入れる。yarn add -D source-map-support @types/source-map-supportして、各エントリポイントファイルの先頭で
import "source-map-support/register";する感じで。
必要に応じてnpm moduleにしてシェア
CloudFormation templateと、ビルドしたjsをnpm moduleにしてnpm registryにpublishしておくと、同一構成を作りやすくて便利。2020-05-29
Drawio Desktop を使ってコマンドラインで図を画像に変換する
Webブラウザで使えるオープンソースのドローツールdraw.ioは便利なのだけど、図を描いたあと他フォーマットに変換のがちょっと面倒なので変換する話。
ヘルプを見るとこんな感じ。
drawio-desktopをインストールする
draw.ioにはブラウザ版の他に、Electronで作られたdrawio-desktopというのがある。まずこれをインストールする。snapだと簡単。# snap install drawio
drawioコマンドで変換する
drawio-desktopの実体であるdrawioコマンドには、コマンドラインオプションを指定すると指定フォーマットでエクスポートする機能がついているので、これを使って変換する。$ drawio -x -f png *.drawioシェルスクリプトにしておくと便利。ちなみにデフォルトはpdfらしい。
ヘルプを見るとこんな感じ。
$ drawio --help Usage: drawio [options] [input file/folder] Options: -V, --version output the version number -c, --create creates a new empty file if no file is passed -k, --check does not overwrite existing files -x, --export export the input file/folder based on the given options -r, --recursive for a folder input, recursively convert all files in sub-folders also -o, --output
2020-02-27
yalcを使って開発中のnpmパッケージを手元で確認する
ライブラリとして分離したnpmパッケージを作るときは、シンプルなものであればyarn linkでローカルファイルを参照しながら動作確認ができるのだけど、依存によってはややこしい問題が起きたりする。
例えばReactを使うライブラリだとこんなエラーが起きたりする。
そこで登場するのがyalcというツール。yarn linkはざっくり言うとライブラリ側のディレクトリへのシンボリックリンクをアプリ側のnode_modules以下に配置するのに対して、yalcを使うとローカル(~/.yalc)にpublishしてそこをpackage.jsonで見る形にできるので、npm registryにpublishされたものを使うのに近い状態にすることができる。
例えばReactを使うライブラリだとこんなエラーが起きたりする。
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: 1. You might have mismatching versions of React and the renderer (such as React DOM) 2. You might be breaking the Rules of Hooks 3. You might have more than one copy of React in the same app See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.
そこで登場するのがyalcというツール。yarn linkはざっくり言うとライブラリ側のディレクトリへのシンボリックリンクをアプリ側のnode_modules以下に配置するのに対して、yalcを使うとローカル(~/.yalc)にpublishしてそこをpackage.jsonで見る形にできるので、npm registryにpublishされたものを使うのに近い状態にすることができる。
使い方
1. yalcのインストール
yalc自体をインストールする。$ yarn global add yalc
2. publish
ライブラリ側でyalc publishする。$ cd ~/proj/mylib $ yarn build とか $ yalc publish
3. パッケージ追加
アプリ側でyalc addする。$ cd ~/proj/myapp $ yalc add @myorg/mylib $ yarnこれで使えるようになる。package.jsonにはこんな感じのエントリが追加されている。
"@myorg/mylib": "file:.yalc/@myorg/mylib",
4. 内容更新
中身を変えたら publish と update をする。$ cd ~/proj/mylib $ yarn build とか $ yalc publish $ cd ~/proj/myapp $ yalc update
5. yalc remove
yalc remove --allしておしまい。$ cd ~/proj/myapp $ yalc remove --all $ yarn詳しくはyalcのGitHub (https://github.com/whitecolor/yalc)を参照。
2020-02-12
tslint:disable を eslint-disable にするツールを雑に作った
[2021/7/8追記] tslint-to-eslint-configの作者さんから直々にコメントに対応した旨連絡頂いたので、このツールは役目を終えました。 https://github.com/sunnyone/tslint-comment-to-eslint/issues/1
TSLintからESLintに移行するには、// tslint:disable-next-line:no-floating-promisesなんかのコメントを、
// eslint-disable-next-line @typescript-eslint/no-floating-promisesなんかに変える必要があるのだけど、ある程度機械的にできるんじゃないかと思って作った。
https://github.com/sunnyone/tslint-comment-to-eslint
使い方
使い方はこんな感じ。直接置き換えるのでgitなりできれいな状態にして実行を。$ yarn global add tslint-comment-to-eslint $ tslint-comment-to-eslint 'src/**/*.ts'