如何在 Node 16 应用程序中使用命名模块导出?

How Can I Use Named Module Exports in Node 16 App?

我正在使用 Node 16.3.0Express 4.17.1(尽管我的 Node 版本很灵活)

我有一个 session.js 文件是这样的:

// session.js

exports.fetchUserId = async function(token){
  ...
}

exports.save = async function(userId){
  ...
}

然后在我的 app.js 文件中,我尝试这样做:

// app.js

import session from './session.js'

我收到以下错误:

import session from './session.js'
       ^^^^^^^
SyntaxError: The requested module './session.js' does not provide an export named 'default'

...然后我想像这样在 app.js 中使用 session

let userId = await session.fetchUserId(req.body.token)

我尝试了以下方法,但没有成功:

  1. "type": "module" 添加到 package.json
  2. 通过 npm i esm
  3. 使用nodemon --experimental-modules app.js

我的代码在 NuxtJS 项目中使用时工作正常,但我正在尝试普通 Node/Express 应用程序并且命名的导出不起作用。

知道我做错了什么吗?

您的代码中的问题是您将 ES 模块与 CommonJS 模块混合在一起。

默认情况下,node 将每个 javascript 文件视为一个 CommonJS module,但在 package.json 文件中包含以下内容

"type": "module"

你告诉节点将每个 javascript 文件视为一个 Ecmascript module 但在 session.js 文件中,你正在使用 CommonJS 模块语法导出函数。

解决方案

您可以使用以下选项之一解决您的问题:

  • session.js 文件的扩展名更改为 .cjs。 (不要忘记也更改 app.js 文件中导入语句的扩展名)。

    将扩展名更改为 .cjs 将告诉节点将 session.cjs 文件视为 CommonJS 模块。

  • 只需使用 ES 模块并更改 session.js 文件中的导出,如下所示:

    export const fetchUserId = async function(token){ ... }
    
    export const save = async function(userId) { ... }
    

    并将 app.js 文件中的导入语句更改为:

    import * as session from "./session.js";