お知らせ

現在サイトのリニューアル作業中のため、全体的にページの表示が乱れています。
投稿日:
ソフトウェア::VSCode言語::TypeScript

新しくセットアップしたTypeScriptのプロジェクトでauto-importが機能しなかったので原因を調べた。

ここ数年ちまちま起きて、そろそろイラついて我慢の限界を覚えたので…。

確認環境

Env Ver
VSCode 1.83.0
typescript 4.8.4

再現方法

再現用のサンプルリポジトリsrc/index.tsの下図コードに対してauto-importが発動する操作を行う。

auto-importに失敗し、利用可能なコードアクションはありませんと出る

発生条件

恐らく以下を全て満たすときにauto-import操作をしようとした時に発生する。地味にややこしい。

node_modules配下に存在し、@types/モジュールを持たないものでかつ、同一プロジェクト内でimportされておらず、package.jsondependenciesに書かれていない。

因みにhoge/piyo/fugaのようなモジュールはhogeだけがdependenciesにいてもauto-importが動かない。これを全部package.jsondependenciesに書いていくのは目眩がするので正直auto-importを諦めて自分でimportを調べて書くのが無難だと思う。

発生原因

TypeScript 4.0で実装されたSmarter Auto-Importsのせい。

node_modulesをクロールすると重すぎるので@types/だけ読み込んで、あとはpackage.jsondependenciesも見るようにしたよという内容らしい。

解消方法

package.jsondependenciesに全部のモジュールを書いていくというのが解決方法になるが、気が遠くなるので諦めた方がいい。初回だけは苦痛でもimportパスをどうにかして調べて手動で書いて、あとはauto-importされるのを期待するのが良いだろう(そんな何度もimportしないと思うが…)

取り敢えず基本npm iで入れて行き、スラッシュ区切りのやつは諦めるくらいがちょうどいいだろう。

再現用のサンプルリポジトリではpackage.jsondependencies"firebase/app": "^10.4.0"を追加することでsrc/index.tsinitializeAppに対しauto-importが発動する様になるはずだ。

あとがき

早い話、node_modules配下にあって@types/を持たないものはTypeScriptに対応する気がないんだな程度に思っておくのが良いだろうが、TS化で@types/を廃止したライブラリがある当たり、すごく微妙な感じがある。ちょっとなんとかしてほしい。

そもそもpackage.jsondependenciesはnpm packageを公開する時に動作するために必要な依存関係を登録する場所で、型の補助をする場所ではなかったはずだ。

少なくともnpmjsのdevDependenciesには以下の記述がある。つまりモジュールを配布する時に動作に不要な依存関係を含まないようにするためにdevDependenciesがあるということだ。つまりdependenciesには動作に必要なものだけを入れるべきで、モジュールを配布しない場合、このフィールドは不要になるはずである。

If someone is planning on downloading and using your module in their program, then they probably don't want or need to download and build the external test or documentation framework that you use.

In this case, it's best to map these additional items in a devDependencies object.

ただTypeScriptがdependenciesに書かないとauto-importが失敗すると言っているので使うものはdependenciesに入れるというのが良いのだろう。(配布しないモジュールだとしても)

ただそれにしてもauto-importを動かすためだけに、dependenciesに同一モジュールのスラッシュ違いを大量に入れていくのはバカバカしいと思う。

  "dependencies": {
    "firebase": "^10.4.0",
    "firebase/app": "^10.4.0",
    "firebase/database": "^10.4.0",
    "firebase/analytics": "^10.4.0",
    ...
  }

かといってinitializeAppfirebase/appにあるなんて知らんわけで、全部のパスに総当りしていくのも嫌だし、一々リファレンス漁るのも面倒だし、なんかもうちょっといい具合になって欲しい…。

Web開発をしていると取り敢えずHTTPリクエストが取れる雑なモックサーバーが欲しくなることがあるので、その作り方。

確認環境

Env Ver
OS Windows 11 Pro
WSL2 -
Distoribution Ubuntu 20.04.4 LTS
PHP 8.0.29
nginx 1.18.0

作り方

  1. Windows側の hosts127.0.0.1 mock-server.test を追加
  2. /etc/nginx/conf.d に以下の設定ファイルを置く
server {
  listen       80;
  client_max_body_size 100m;
  server_name  mock-server.test;
  access_log   /var/log/nginx/mock-server.access.log;
  error_log    /var/log/nginx/mock-server.error.log;


  location ~ ^/.*$ {
    rewrite ^/.*$ / break;
    # リクエストパスの確認用
    proxy_set_header X-Request-Path $request_uri;
    proxy_pass  http://127.0.0.1:8888;
  }
}
  1. sudo service nginx restart
  2. モックサーバーのコードを書いて適当な場所に置く
<?php

$server_json = json_encode($_SERVER);

file_put_contents('log', "$server_json\n", FILE_APPEND);
  1. php -S localhost:8888
  2. http://localhost:8888/hoge にアクセスしログファイルに追記されることを確認
  3. おわり

おまけ

$_SERVER の中身をフィルタしたい時

<?php

$ignoreKeys = [
    'DOCUMENT_ROOT',
    'REMOTE_ADDR',
    'REMOTE_PORT',
    'SERVER_SOFTWARE',
    'SERVER_PROTOCOL',
    'SERVER_NAME',
    'SERVER_PORT',
    'REQUEST_URI',
    'SCRIPT_NAME',
    'SCRIPT_FILENAME',
    'PHP_SELF',
    'HTTP_HOST',
    'HTTP_CONNECTION',
    'HTTP_UPGRADE_INSECURE_REQUESTS',
    'HTTP_USER_AGENT',
    'HTTP_ACCEPT',
    'HTTP_ACCEPT_ENCODING',
    'HTTP_ACCEPT_LANGUAGE',
    'HTTP_CACHE_CONTROL',
    'REQUEST_TIME_FLOAT',
    'REQUEST_TIME'
];

$buff = array_filter($_SERVER, function($key) use($ignoreKeys) {
    return !in_array($key, $ignoreKeys);
}, ARRAY_FILTER_USE_KEY);

$server_json = json_encode($buff);

file_put_contents('log', "$server_json\n", FILE_APPEND);

TypeScriptやJavaScriptだとコマンド一発で見れるコードカバレッジですが、C#.NETの開発ではちょっと手こずったので導入方法を記録しておく。

確認環境

Env Ver
Visual Studio 2022 Community Version 17.5.1
.NET Framework 6.0

導入手順

  1. C#.NETで開発用のプロジェクトを作成
  2. 作成したプロジェクトのソリューションにxUnitテストプロジェクトを追加
  3. 何かしらの実装と、それに対するテスト実装を作成
  4. Fine Code CoverageをVisual Studioにインストール
  5. ソリューションエクスプローラからxUnitテストプロジェクトを右クリックしてテストの実行
    1. xUnitテストプロジェクトを右クリックしてテストの実行
  6. 下部トレイにあるFine Code Coverageタブを選択
    1. Fine Code Coverageタブを選択
    2. 表示されていない場合は表示 → その他のウィンドウ → Fine Code Coverageで表示出来る
      1. 表示されていない場合は表示 → その他のウィンドウ → Fine Code Coverageで表示出来る
  7. コードカバレッジが表示される
    1. vs2022-easy-code-coverage.jpg

疑問

Visual Studio 2022にもなって標準でコードカバレッジも取れないの?

今どきそんな事あるか?思って調べてみたところ、どうやらEnterpriseであればコードカバレッジを取る機能がついている模様。

Community版では標準でカバレッジが取れない

まぁ無料版だから仕方ないねということで諦めるしかないでしょう。Professional版にもないけど…w。VisualStudioの便利機能は以前から有料機能に組み込まれる傾向があるので仕方がない気もしますが、取り敢えず今回は有志が便利なツールを作っていてくれて助かりました。

因みにコードカバレッジ自体は無料版でも取れます。ただこれはXMLのカバレッジレポートを吐くだけなので、可視化するには別途ここからHTMLを生成する必要があり面倒なので、なんかもっと楽な方法はないかなと思って見つけたのが今回のFine Code Coverageでした。

しかしFine Code Coverage便利なのにそこまで利用されているように見えないのは、やはりテストに関心がある人が少ないのか、公式にあるカバレッジHTMLを吐く方法で納得しているのか、その辺りが気になりました。自前でFine Code Coverageの様な物を作っている人もいるでしょうが、それは少数派だと思いますし。

この方法で取れるカバレッジは正しいものか?

GitHubのREADMEを読む限り、組み込みのカバレッジレポーターのAPIを叩いて取ってきたものを表示しているだけに見えるので、恐らく正しいデータが出ているのではないかと思います。

少なくとも単純なコードのUnit testingを書いた感じではテストケースを増減することでカバレッジも連動して増減していたのと、組み込みのレポーターがそのくらいはやってくれている筈で、これはその内容を表示しているだけなので恐らく大丈夫なのではないかと考えています。