自分用のメモ。
先達のコードを読んでいて、何が違うのかと混乱した部分。
import { sample } as from './sample';
import * as sample from './sample';
import sample = require('./sample');
一番上は分かる。
下二つの違いがよくわからない。
調べるとimportとrequireについての使い分けは出てくる。
けれども同時に使う事例がない。
ならば実際に書いて挙動を確認しよう。
importのmoduleとして下記sample.tsがある場合で記述。
export interface firstParams {
id: string;
}
export const sampleNumber = "123";
それぞれの挙動結果を確認する。
1.import { firstParams } as from './sample';
の場合
sample.tsの中のfirstParamsのみを読み込む。
import { firstParams } as from './sample';
const sampleConst: firstParams[] = []; // firstParamsの型を付与
2.import * as sample from './sample';
の場合
sample.tsの中のexport全てを読み込む。
import * as sample from './sample';
const sampleConst: sample.firstParams[] = []; // firstParamsの型を付与
const sampleConst2 = sample.sampleNumber; // 123
3.import sample = require('./sample');
の場合
sample.tsの中のexport全てを読み込む。
import sample = require('./sample');
const sampleConst: sample.firstParams[] = []; // firstParamsの型を付与
const sampleConst2 = sample.sampleNumber; // 123
同じじゃないか?
では、単にimportするのとrequire()をかませて読み込むのとでの違いを考えればいいのか。
さらっと調べるとrequire()は推奨されてないことが多い。
敢えてそれを使って記述しているのは何故?
そんな中、素敵な先人の記事を発見。
Node.js: require()は同期型ロード、importは非同期型ロード
詳しくは上の記事をお読みいただきたいのだが、結論はタイトル通り。
require()は同期型ロード、importは非同期型ロードを行う。
つまり、今回の場合はimport先のmoduleが多数の処理をしていると、この設定が効いてくる。
同期的なロードをしたい場合にはrequire()をかませてimportをする必要があると。
なるほど結論
import * as sample from './sample'; // 非同期型のロード(CommonJS)
import sample = require('./sample'); // 同期型のロード(ES Modules)
表に見える挙動は同じでも、連鎖的に繋がっていることで変わる挙動がある。
連携先の挙動も踏まえた上で使うコードを選ばなければならないと、そういう話でした。
もし何か解釈が間違っているようだったら、是非ともご指摘いただきたい。
ありがとうございました。