2022/05/15

[typescript] 複数のimportするファイルを何とかしたい

タイトルだと全然わからんのでちゃんと説明をします......

 

発端は gRPC クライアントアプリを JavaScript で作っていたので TypeScript にしようと考えたことだった。
いままで TypeScript のことを調べはしたものの、 1ファイルで終わるような内容であれば JavaScript で済ませていたのだが、大きくなりそうな気配があったので TypeScript にしておこうとしたのだ。

--init で tsconfig.json を作り、ちょっとだけ変更して、拡張子を js から ts にリネームし、プリミティブ型以外のところは any で逃げてコンパイルというかトランスパイルというか、ともかく JavaScript にして node.js で実行するところまではできた。

次の段階は any を何かの型に置き換える作業だろうと思って進めていた。
作っていた JavaScript の中では特に Object を作るようなことはしていなかったのだが、 gRPC のリクエストとレスポンスは proto ファイルに由来する型を使っていた。

では proto ファイルから型を作る何かがあるだろうと調べて出てきたのがこれだった。

Generating TypeScript types
https://github.com/grpc/grpc-node/tree/master/packages/proto-loader#generating-typescript-types

npx proto-loader-gen-types を実行すると、proto ファイルを読み込んで型情報を持つ ts ファイルを作ってくれた。
そこまでは良かったのだが、proto ファイルに記述されている message ごとに ts ファイルを作るようだった。使う予定の proto ファイルにはたくさん message があり、大量の ts ファイルが生成された。

これを import すれば使えそうなのだが、その前に「この大量のファイルを import するということ自体を何とかできんだろうか、と考えたのだ。


まず考えたのがワイルドカード。
import もモジュールといいつつファイル名みたいなもんだから from のところに './proto/*' みたいな書き方をすればよいんじゃないの?と思うのは仕方あるまい。

結果としてダメだった。
まあ、同じディレクトリにあるだけで読み込まれるってのはさすがに危険すぎるな。

 

dynamic import というやり方も見つけたのだが、別に静的で良いのだ。
単に import 文をたくさん書きたくないだけなのだよ。
いや、書いても良いけど import だけで何十行もあるような状況が嫌なのだよ。

 

というわけで次に思いついたのが、別の ts ファイルに import だけ詰め込んで それを import するような手段が執れないだろうか、ということだった。

import - JavaScript | MDN
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/import

JavaScript だろうと TypeScript だろうと import は import のはずだから MDN の説明でよいと思う。
ただね、読む前に想像すると、そんなことはできないんじゃないかと思うのだ。
まあ、やらんとわからん。

 

image

image

>node index.mjs
aaa=30
bbb=20
ccc=10

TypeScript ではないが、まあよかろう。
これが基本形だ。

 

ダメだったワイルドカード。

import * as aaa from './files/*.js';

console.log(`aaa=${aaa.A}`);
console.log(`bbb=${aaa.B}`);
console.log(`ccc=${aaa.C}`);

Cannot find module になる。
ワイルドカードと見ずに "*.js" というモジュール名として処理するからだろう。

 

a.js, b.js, c.js は変更しないとして files/index.mjs を追加してみた。
まあ、ダメなんだけどね。

image

>node index.mjs
aaa=undefined
bbb=undefined
ccc=undefined

import でモジュール名しか指定していない場合は import はしないのだね。。。

副作用のためだけにモジュールをインポートする
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/import#import_a_module_for_its_side_effects_only

それに、もし import できていたとしても export していないから参照できないだろう。
これなら動いた。

image

>node index.mjs
30
20
10

export {a.A} みたいな書き方をすれば total.A で参照できるかと思ったがダメだった。 export {a.A as A} もダメだ。
再export すればいける。

image

export from という書き方もあるそうだ。

export
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/export

image

これくらいだったら bash で機械的に作れるんじゃないかな。