Expressを読み込んだ際に express is not a function
と出たので原因と解決策を共有します。
あとついでに export =
と import = require()
についてです。
環境
import側はJavaScript、トランスパイルとかは一切なし。
node: v14.1.0
package.json
{
...
"type": "module",
"dependencies": {
"express": "^4.17.1",
...
},
...
}
再現VTR
index.js
import*asexpressfrom"express";constapp=express();
node ./index.js
実行すると
const app = express();
^
TypeError: express is not a function
エラー発生。
因みに、USAGEに従っていた。1
@types/express/index.d.ts
/* =================== USAGE ===================
import * as express from "express";
var app = express();
=============================================== */
原因
CommonJSとESModulesdでの返却される値に違いがあった。
import*asexpressfrom"express";console.log(typeofexpress);// => object
constexpress=require("express");console.log(typeofexpress);// => function
import
default: [Function: createApplication] { ... }
require
[Function: createApplication] { ... }
つまり、返却値がdefault exportとなっているため参照エラーを起こしていた。
対応策
こうする。
importexpressfrom"express";constapp=express();
または、
import*asexpressfrom"express";constapp=express.default();
そもそもトランスパイルもせずに使うなら、CommonJSモジュールならCommonJSのインポート (const express = require("express");
) で読み込むのがベターっていうツッコミは覚悟してます!
以降おまけ
export =
名前は「エクスポート代入」。
Expressの型定義ファイルを覗くとこうなっている。
@types/express/index.d.ts
.../**
* Creates an Express application. The express() function is a top-level function exported by the express module.
*/declarefunctione():core.Express;...export=e;
CommonJSとAMDを考慮せずにエクスポートできる便利機能。
言い換えればこれは、CommonJSまたはAMDのモジュールだよ。っていう印。
import = require()
名前は「インポート代入」。
エクスポート代入(export =
)を使用してエクスポートされたモジュールをインポートする際に使われていたらしい。
今ではあえて使う理由はなさそう。
インポート代入、インポート代入の使用例
// export側functionhoge(){return'hoge';}constfuga='fuga';export={hoge,fuga};// import側importhogefuga=require('./export');console.log(hogefuga);// => { hoge: [Function: hoge], fuga: 'fuga' }
感想
地味に時間を溶かしたため記事にしてやったぜ。。
何かご指摘等あればコメントいただけると幸いです。