5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[JavaScript] express() で "express is not a function" ついでに TS の "export =" と "import = require()"

Posted at

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 * as express from "express";
const app = express();
node ./index.js

実行すると

const app = express();
            ^
TypeError: express is not a function

エラー発生。
因みに、USAGEに従っていた。:thinking: 1

@types/express/index.d.ts
/* =================== 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
import
default: [Function: createApplication] { ... }
require
[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の型定義ファイルを覗くとこうなっている。

@types/express/index.d.ts
...
/**
 * 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()

  1. ある時点のソース https://github.com/dfrankland/DefinitelyTyped/blob/06002c2c495359eb97c48f71f3f6bcbac25c7225/types/express/index.d.ts

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?