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