お知らせ

現在サイトのリニューアル作業中のため、全体的にページの表示が乱れています。
投稿日:
ジャンル::雑記

ここ最近ホッテントリなどで文化とは何かみたいな話を見る機会が増えたので、個人的な文化論みたいなのを書いてみる。

文化としてよく言われるのはポップカルチャーや芸術だろう。例えば東京が文化的な都市と言われるのはライブやフェスなどのイベントが多かったり、写真展や芸術展みたいなのが多く開かられるからだと私は認識している。

勿論それも文化の一つだと思う。しかし、それだけが文化だとも思わない。

個人的には人々の立ち振る舞いや、そこにある物の様式も一つの文化だと思う。つまり地域や個人の慣習みたいなものも文化だと考えている。

以前、塚口サンサン劇場というミニシアターで、来客のオバちゃんがトイレに行く際、こともあろうことか、ハンドバッグをグッズ売り場のショーケースの上に乗せて行くのを見たことがある。

普通に考えればトイレに持っていくべきだし、そんなところに置いて盗まれたらどうするのかとか、ショーケースの上に置かれたら他の人の邪魔になるだろうとか、色々浮かぶとは思うが、私はこれは一つの文化だと思う。

何故ならオバちゃんにとってはそれが当たり前で日常なのだ、つまりそれはもう文化と言える。そんなところに置いても盗まれないし、文句を言われることもまずないし、言われたところで気にしないのかもしれない。盗まれても「仕方ないわねぇ」とか、あっけらかんとして済ませるのかも知れない。

このような景色は東京の都心部みたいなところでは見かけることが余りないだろう、実に放牧的で平和な光景だ。映画のワンシーンにできるかもしれない。

そういった地方のミニシアターならではの光景も文化だと思う。同様に田舎で行われているお祭りや、今となっては人権侵害行為だったり、暴力的な事柄も、それもそこにある一つの文化だと思う。

個人的に文化を受容する上で思うのは東京だけが文化の発信地で、地方に文化はないみたいな考えより、地方には東京にない文化があり、それは東京のポップカルチャーなどと同じように尊く、愛すべきもので、また推せると言う考えをしている。

だからこそ私は神戸や兵庫、関西、そして日本を愛し、推している。だからこそ地産地消をしたり、できる限り地域のものを大切にするようにしている。私がふるさと納税をしない理由の一つも神戸市に税金を落とすためだ。

投稿日:
言語::TypeScript

五年くらい公私ともにTypeScriptを書いているが、なんか最近限界を感じたので吐露していく。半分くらいNode.jsに対する不満かもしれない。内容としてはただの書きなぐりの愚痴。

非同期制御多すぎ

asyncawaitを書く面倒さや、それが漏れた時のふるまいの微妙さ。

例えば終わらないJestというのは日常的に見る光景だと思うし、実務をしていてPromiseの例外ハンドリングをしていなかったからサーバーがクラッシュしたというのも聞いたことがある。

これはチーム開発において、チームの意識や技術レベルが低いと容易に引き起こされる問題であり、その面で考えると非常に微妙な言語仕様だと思う。

なんだかんだC10K問題はコンテナ大量起動で回避する世界線になってしまっている気がするので、標準が非同期である必要性はあんまないよねみたいな感触は抱いている。C10K問題回避のために非同期にしてるんだよね?そうだよね?(正直非同期にしたいのであればユーザー側がPromiseに包めばいいと思う)

Node.jsのLTS短すぎ

GitHubやAWSですら最新版への追従は遅れがちなくらいLTSが短い。2年くらいしかない。2年ごとにフルリグレッションなんてやってられない。不可能だ。

しかも破壊的変更を平気で入れてくるし、v16は予定より早くサポートが打ち切られた。正気とは思えない。

実行環境多すぎ

Node.js + 各種トランスパイラにDenoにBunに…他にも最近なんか出ていた気がするが忘れた。なんでこんなにあるのか…。

TypeScriptの型パズルに疲れた

型パズルするために開発してるんじゃないんだよ…。

型が信用できない

実務だと意図しているのか、していないのか型を騙している光景を多々見るが、これによって型が信用できない状態になっていることが往々にしてあり、割と殺意を覚える。なにも信用できない。何のためにこの言語使ってるんだっけ…?ナウいから?

CLI作る時のハマりどころが多い

nvmのようなバージョン管理システムを使っているとグローバルインストールが通常ユーザーとスーパーユーザーで別れる問題があり、sudo実行が前提のCLIで誤った動作確認をしてしまいやすい。

他にもnpmjsで公開しているパッケージをnpm installしたものと、開発中に実行するのでは、意識してないと実行方式が変わってしまい、上手く動かないことがある。気を付ければいいのはそうだが、割とムカつく。

具体的にはshebang書いて無くて動いてなかったとかそういうやつ。基本的にjsファイルを直に叩いて動かす文化ないじゃん…。

ビルド工程が面倒くさい

ビルドに関してtscやswc、esbuildのように様々なトランスパイラが存在するほか、webpackやvite, esbuildといったバンドラの存在があり、バージョンアップで振る舞いが変わるので面倒くさい。TypeScript開発は膨大なパッケージに依存しがちで、何か不具合が起きた時に原因の特定が困難だが、根幹に破壊的変更が来ると割と精神的にきつい。

先ほどswcでビルドしたところ/dist/index.jsとして出てくるはずのものが、/dist/src/index.jsになっていた。正直こんなのはデグレードだ。ありえない。

もちろんこれはfix: pass in --strip-leading-paths to swc when buildingで対応されているのだが、正直しんどい。

てかNode.js系のパッケージって息を吸うようにデグレ起こすような気がするのは私だけだろうか。以前はNewRelicがプリフェッチしまくるバグとかあった気がするし、Jestのモックが正常に動かないケースにも遭遇したことがある。

エコシステムが壊れかかっている

TypeScriptでLintをするとなればESLintがデファクトスタンダードだと思うが、v8で導入されたFlat configがあまりにも不案内で、v9.7が出た今でさえ対応できていないPluginがゴロゴロある。むしろできてるほうが珍しい。

私も三日くらい格闘したが、いずれかのプラグインが不整合を起こすか、不整合を起こさなくなったと思ったら無視設定が機能しなかったり、今度はLint機能そのものが死んだりで手に負えないのであきらめた。v9に上げると使えなくなるプラグインもあるので、v8.57.0で旧式の設定を使うのがきっと無難だと思うが、これがいつまで続くのかという話だ。恐らく追従できないプラグインはサポートのやる気をなくすだろう。

Prettierも破壊的変更を繰り返しフォーマットをガタガタにしてくる困りものだ。こいつもv3が出て一年たった今でもVSCodeの公式拡張機能がv3に対応していない。一応ローカルにv3を入れれば最低限動くが、ネイティブで動いてほしいケースもあるので、そういう場合は運用に難儀する。過去に対応させようと手を付けてみたが、最新版はテストが落ちる状態になっていて、もはや救いがなかったので投げた。

正直ESLintとPrettierが死にかけている現状を見るに、もうなんというか駄目じゃないかという気がしてくる。

Biome.jsなんてのもあるが、あれはMarkdownのフォーマットができないとか、ESLintのプラグインをサポートしてないとかで使い勝手がいまいちよくないのだ。まぁ、MarkdownのフォーマットだけPrettier使うとかはアリか。

あとがき

とはいえ、フロントエンド開発において、ブラウザではJavaScriptしか動かないのでTypeScriptをの利用はやむを得ない側面もある。やむを得ないのだ。ただ、それ以外ではもう使う必要ないんじゃないかなと思うし、正直Node.js界隈が魔境というか地獄過ぎて、あんまり関わり合いになりたくないという思いが日に日に強くなっている今日この頃だ。

WSL上のUbuntuで動作するnginxでHTTPSに対応したサーバーを作る方法。実機でも同様の手順でいける

確認環境

Env Ver
nginx nginx/1.18.0 (Ubuntu)
mkcert v1.4.4
Ubuntu 20.04.6 LTS
Windows 11 22621.3880

手順

  1. Windows側にmkcertを入れる
  2. mkcertで証明書を作る
    • mkcert sandbox.test
  3. 以下のpemファイルが生成される
    • sandbox.test.pem
    • sandbox.test-key.pem
  4. 生成されたpemファイルを/etc/nginx/conf.d/ssl/に移動する
  5. /etc/nginx/conf.d/sandbox.test.confを作成し、以下のような記述をする

    server {
        listen       443 ssl;
        client_max_body_size 100m;
        server_name  sandbox.test;
    
        ssl_certificate     conf.d/ssl/sandbox.test+1.pem;
        ssl_certificate_key conf.d/ssl/sandbox.test+1-key.pem;
    
        access_log   /var/log/nginx/sandbox.access.log;
        error_log    /var/log/nginx/sandbox.error.log;
    
        # ファイルホスト用
        #  location / {
        #    root /usr/share/nginx/html/sandbox;
        #    index index.html;
        #    try_files $uri /index.html =404;
        #  }
    
        # APサーバーへのリバプロ用
        location ~ ^/.*$ {
            rewrite ^/.*$ / break;
            proxy_set_header X-Request-Path $request_uri;
            proxy_set_header X-Host $host;
            proxy_pass  http://127.0.0.1:9999;
        }
    
        # fastcgi用
        location ~ \.php$ {
            root  /usr/share/nginx/html/sandbox;
            fastcgi_pass unix:/run/php/php8.0-fpm.sock;
            fastcgi_index index.php;
            include fastcgi_params;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        }
    }
    
  6. nginxを再起動する
    • sudo service nginx restart

他の端末に証明書を撒く方法

mkcertのRoot CAをエクスポートして他の端末に突っ込めば、他の端末でもpemが流用できる

投稿日:
言語::PHP

あると何かと便利だよねというので。

確認環境

Env Ver
PHP 8.0.29

サンプルコード

取り敢えずファイルをアップロードするだけのコード

<?php
if ($_FILES['image']) {
    move_uploaded_file($_FILES['image']['tmp_name'], 'files/'. $_FILES['image']['name']);
} else {
?>
<html>
<body>
<form action="upload.php" enctype="multipart/form-data" method="POST">
    <input type="file" name="image">
    <button>upload</button>
</form>
</body>
</html>
<?php
}

ブラウザのタブがバックグラウンド状態になっているとJSの実行が止まることがあり、そうするとsetInterval()が死ぬので、これを回避する技。

結論としてはWeb Worker APIのWorkerインターフェースを使うことで解決できる。

確認環境

Env ver
Microsoft Edge 126.0.2592.87

サンプルコード

/**
 * @param {() => void} cb 実行するコールバック
 * @param {number} interval 実行間隔
 * @returns 停止用の関数
 * */
const createWorkerInterval = (cb, interval) => {
  const src = "self.addEventListener('message', (msg) => { setInterval(() => self.postMessage(null), msg.data) })";
  const wk = new Worker(`data:text/javascript;base64,${btoa(src)}`);

  wk.onmessage = () => cb();
  wk.postMessage(interval);

  return wk.terminate;
}