📦

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を見に行く。

https://github.com/firebase/firebase-admin-node/blob/v13.6.0/package.json#L120-L126

import admin from "firebase-admin";と書かれてるので、"./lib/index.js"を見に行く。※1

3. 対象ファイルを見に行く

githubにはtsの方しかないので、jsのコードも適度に省略しながら書いていく。

./lib/index.js

const firebase = require("./default-namespace");
...
module.exports = firebase;

https://github.com/firebase/firebase-admin-node/blob/master/src/index.ts#L18-L38

./default-namespaceをexportsしてるので、見に行く。

./lib/default-namespace.js

const firebase_namespace_1 = require("./app/firebase-namespace");
...
module.exports = firebase_namespace_1.defaultNamespace;

https://github.com/firebase/firebase-admin-node/blob/master/src/default-namespace.ts#L18-L31

./app/firebase-namespaceをexportsしてるので、見に行く。

./app/firebase-namespace.js

initializeApp(options, appName) {
    const app = this.appStore.initializeApp(options, appName);
    return extendApp(app);
}

https://github.com/firebase/firebase-admin-node/blob/master/src/app/firebase-namespace.ts#L64-L67

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