TypeScriptのimportの仕組み
はじめに
これは自分宛ての備忘録です。
きっかけ
どの言語でもプログラム書いてたら出会うimport文。
定義ジャンプしたら中身見れるので意識してなかったが、importの仕組みを把握してないなと思ったので、まとめてみる。
以下を例に話を進める。
import admin from "firebase-admin";
admin.initializeApp({
credential: admin.credential.applicationDefault(),
});
importの流れを見ていく
1. node_modules配下にある firebase-adminを見に行く
admin.initializeApp({
credential: admin.credential.applicationDefault(),
});
adminは自分たちで定義した変数ではないので、ライブラリを見に行く。
import admin from "firebase-admin";
adminはfirebase-adminディレクトリからimportされると書かれているので、 node_modules/firebase-adminディレクトリを見に行く。
2. package.jsonを読む
node_modules/firebase-adminディレクトリに行った後はpackage.jsonのexportsを見に行く。
import admin from "firebase-admin";と書かれてるので、"./lib/index.js"を見に行く。※1
3. 対象ファイルを見に行く
githubにはtsの方しかないので、jsのコードも適度に省略しながら書いていく。
./lib/index.js
const firebase = require("./default-namespace");
...
module.exports = firebase;
./default-namespaceをexportsしてるので、見に行く。
./lib/default-namespace.js
const firebase_namespace_1 = require("./app/firebase-namespace");
...
module.exports = firebase_namespace_1.defaultNamespace;
./app/firebase-namespaceをexportsしてるので、見に行く。
./app/firebase-namespace.js
initializeApp(options, appName) {
const app = this.appStore.initializeApp(options, appName);
return extendApp(app);
}
initializeAppあったので、extendsApp(app)が返却される。
おわりに
一回理解してしまったら忘れない気がするが、念の為残しておく。
githubの方にはjsファイルないから、読みにくいなぁ。
Appendix
※1 importについて
import app from "firebase-admin/app";なら "./app"の方を見に行く。
types, require, importとあるが、
tsで以下のように書かれていればtypesを見る。(型を見てくれる。)
import { initializeApp } from "firebase-admin/app";
CommonJsでrequireされたらrequireを見る。
const app = require("firebase-admin/app");
ES Moduleならimportを見る。
import { initializeApp } from "firebase-admin/app";
Discussion