Nodejs 项目导入的时候提示 Consider using a default import or import require here instead

最近在开发 NodeJS 项目的时候有下面的错误提示信息:

Type originates at this import. A namespace-style import cannot be called or constructed, and will cause a failure at runtime. Consider using a default import or import require here instead.

问题和解决

我们在 tsconfig.json 的配置文件中添加了 "esModuleInterop": true, 这个配置选项。

这个配置选项将会导致上面的问题。

正是因为上面的配置,我们需要将导入的方法

import * as cors from "cors";

修改为:

import cors from "cors";

有类型声明文件

  • 使用import cjs = require(‘cjs’)方法的导入
  • 使用import * as cjs from 'cjs’方法的导入,此时cjs相当于exports变量(虽然这能够正常工作,但其实不符合es模块规范,es 模块规范规定 cjs 这个命名空间只能是一个纯对象,但是不能够直接调用)
// 不符合规范的导入方式
import * as Koa from 'koa';
const app = new Koa();

// 编译后的结果
const Koa = require("koa");
const app = new Koa();

那怎么才能使用 import cjs from ‘cjs’ 的语法呢?

首先你需要去除类型检查(允许从没有设置默认导出的模块中默认导入),这可以使用allowSyntheticDefaultImports 配置项做到。

其次你的导出需要有 default 属性,因为 allowSyntheticDefaultImports 只是帮你去掉类型检查,但是并不会影响编译后的代码输出,假设没有 default 属性,虽然可以正常编译,但是在运行时还是会报错的,这就需要 esModuleInterop 配置帮你完成了,因为对于大对数模块而言,并没有default属性。

简单点来说 esModuleInterop 的这个配置选项能够允许从没有设置默认导出的模块中默认导入。这并不影响代码的输出,仅为了类型检查。