Node.js中不支持require和import两种导入模块的混用

news/2025/2/23 2:11:43

最近在整理Node.js相关的知识点,发现通过Node.js支持的两个模块导入语句require和import在同时使用时会发生错误,而且错误非常诡异。
例如,在先使用require导入模块,在使用import导入模块时,出现require无法识别,
在先使用import导入模块,在使用require导入模块时,同样出现了require无法识别,建议使用import代替。

ReferenceError: require is not defined in ES module scope, you can use import instead
const readFile = require('fs').readFile;
                 ^

ReferenceError: require is not defined in ES module scope, you can use import instead
    at file:///d:/Software/Electron/JavaScript/LearnProject/NodeJsProject/BasicModules/FileOperation.js:10:18
    at ModuleJob.run (node:internal/modules/esm/module_job:271:25)
    at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:547:26)
    at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:116:5)

Node.js v22.13.1
'use strict'
//const {randomInt} = require('node:crypto');
import {randomInt} from 'node:crypto';
const n = randomInt(0,100);
console.log('BasicModules.js: randomInt:', n);



//import {readFile} from 'node:fs';
const readFile = require('fs').readFile;
console.log("BasicModules.js: readFile start");

readFile('BasicModules.js', 'utf-8', (err, data)=>{
    if (err) {
        console.log('BasicModules.js: readFile error:', err);
    } else {
        console.log('BasicModules.js: readFile data:', data);
    }
});

console.log("BasicModules.js: readFile End");

Node.js 中无法同时使用 require 和 import 的根本原因在于两种模块系统的设计差异。以下是具体原因和解决方案的总结:

模块系统差异

  1. CommonJS(require)
    Node.js 原生支持的模块系统,同步加载模块,适用于服务端开发。
    通过 module.exports 导出,require() 导入,本质是运行时加载。
  2. ES 模块(import/export)
    官方标准化模块系统,异步加载,支持静态分析,适用于浏览器和现代 Node.js 环境。
    通过 export 导出,import 导入,编译时确定依赖关系。

报错原因分析

当文件被识别为 ES 模块 时(文件中使用了import就会自动识别为ES模块)

Node.js 默认禁用 require,因为 ES 模块设计上要求代码静态化,而 require 是动态的[[1][3]6。
错误 ReferenceError: require is not defined in ES module scope 表明当前文件被识别为 ES 模块,但尝试使用了 CommonJS 语法。

1. 解决方案

1.1 统一模块类型

方法一:显式声明模块类型
在 package.json 中添加 “type”: “module”,所有 .js 文件默认视为 ES 模块;使用 .cjs 扩展名表示 CommonJS 模块。

方法二:动态兼容
在 ES 模块中通过 createRequire 引入 require:

import { createRequire } from 'module';
const require = createRequire(import.meta.url); 
// 之后可使用 require()

此方式允许在 ES 模块中局部使用 CommonJS 语法[[1][7]10。

1.2 模块互操作

导入 CommonJS 模块到 ES 模块
使用 import 导入时,CommonJS 模块会被包装为默认导出:

import fs from 'fs';  // 等同于 require('fs').default 

导入 ES 模块到 CommonJS
需使用动态 import():

const loadModule = async () => {
  const esModule = await import('./es-module.mjs'); 
};

1.3 环境配置

Node.js 版本要求
确保版本 ≥ 14,并启用实验性 ES 模块支持(旧版本需添加 --experimental-modules 标志)。

文件扩展名
ES 模块建议使用 .mjs,CommonJS 使用 .cjs,避免解析歧义。

2. 最佳实践

项目级统一规范
新项目优先使用 ES 模块,老项目逐步迁移,避免混用。
工具链适配
使用 Babel 或 TypeScript 编译代码,兼容不同模块系统。

3. 总结

Node.js 中 require 和 import 的冲突源于模块系统的底层差异。通过统一模块类型、动态兼容或工具链适配,可解决这一问题。建议根据项目需求选择合适的模块方案,并遵循 Node.js 官方文档的模块互操作指南。


本文参考以下文献:
网站建设涉及的标准
网站建设报价单 文库
优秀网站建设排名公司
郑州冬青街 嘉兴网站建设公司就找嘉乐网络
网站建设需要备案
企智网络山东省建设厅特种作业证查询网站

http://www.niftyadmin.cn/n/5862909.html

相关文章

从网络延迟到纯净IP,TikTok直播运营专线如何提升直播体验

随着TikTok在美国市场的全面恢复,越来越多的企业开始关注如何通过TikTok直播实现业务增长。然而,跨境直播运营中常常面临网络延迟、IP限制等问题,这直接影响直播效果和用户体验。针对这一痛点,TikTok直播运营专线应运而生&#xf…

Linux 内核中关于 CPU 编号和拓扑管理

CPU 拓扑结构定义 // topology.h struct cpu_topology {int thread_id; // SMT IDint core_id; // 核心 IDint package_id; // 物理 CPU IDint die_id; // Die IDcpumask_t thread_sibling; // SMT 线程掩码cpumask_t core_sibling; // 核心掩码 };CPU 在线…

php session数据存储位置选择

PHP session 数据的存储位置可以通过配置文件或者代码来进行设置。默认情况下,session 数据是存储在服务器的文件系统中的。你可以将 session 数据存储在其他地方,例如数据库、缓存等。 基础概念 PHP session默认情况下将数据存储在服务器端的临时文件中…

DEMF模型赋能多模态图像融合,助力肺癌高效分类

目录 论文创新点 实验设计 1. 可视化的研究设计 2. 样本选取和数据处理 3. 集成分类模型 4. 实验结果 5. 可视化结果 图表总结 可视化知识图谱 在肺癌早期筛查中,计算机断层扫描(CT)和正电子发射断层扫描(PET)作为两种关键的影像学手段,分别提供了丰富的解剖结构…

细分数字货币钱包的不同种类

文章目录 一、中心化钱包1.1 中心化钱包架构1.2 中心化钱包业务细节流程 二、去中心化钱包(HD 钱包)2.1 去中心化钱包架构2.2 去中心化钱包细节业务流程 三、硬件钱包3.1 硬件钱包架构3.2 硬件钱包细节业务流程 四、MPC 托管钱包五、多签钱包 中心化钱包 :钱包私钥一…

contes服务器配置IP地址

第一步: nmcli device status插入和拔出网线执行上面的命令,找出插入网线的网口(enp26s0f0) 第二步: 比如配置的操作如下: IP:10.218.231.84 子网掩码:255.255.255.0 网关&#xff…

一些时间方法

1.禁用之前的时间 <el-date-picker:picker-options"disableBeforePicker"disableBeforePicker: {disabledDate(time) {return time.getTime() < Date.now() - 8.64e7;}, }, 2.选择开始时间之后&#xff0c;结束时间为开始时间之后的120分钟&#xff0c;他们的…

(网络安全)渗透测试

1、渗透测试种类 2、网络安全渗透测试分类 1&#xff09;网络安全渗透测试&#xff0c; 根据事先对测试目标系统信息的了解程度&#xff0c;可以分为 a.黑盒测试&#xff1a; 只知道要测试的目标系统&#xff0c;但系统内部的任何信息&#xff0c;都不清楚。这种测试最真实&am…