require() vs import:Node.js 模块导入对比
require() vs importNode.js 模块导入对比理解两种导入方式的核心区别快速对比特性require()import加载方式运行时、同步编译时、静态模块系统CommonJSES Modules提升行为可在任意位置调用自动提升到顶部条件导入支持不支持文件扩展名可省略必须写.js基本语法require()// 导入整个模块constfsrequire(fs);// 解构导入const{readFile}require(fs);// 条件导入if(needFeature){constfeaturerequire(./feature);feature.init();}// 任意位置调用functionloadModule(){constmathrequire(./math);returnmath.add(1,2);}import// 导入整个模块import*asfsfromfs;// 解构导入import{readFile}fromfs;// 默认导入importexpressfromexpress;// 必须在文件顶部import{add}from./math.js;// 注意要写 .js// ❌ 不支持条件导入// if (needFeature) {// import { feature } from ./feature; // 错误// }// ✅ 动态导入返回 Promiseif(needFeature){const{feature}awaitimport(./feature.js);feature.init();}核心区别1. 加载时机// require - 运行时加载console.log(before require);constmathrequire(./math);// 执行到这里才加载console.log(after require);// import - 编译时加载代码执行前已完成console.log(before import);import{add}from./math.js;// 代码执行前已加载console.log(after import);2. 值拷贝 vs 动态引用// counter.js (CommonJS)letcount0;module.exports{count};count1;// 导出的值仍是 0// test.jsconst{count}require(./counter);console.log(count);// 0// counter.js (ES Modules)letcount0;export{count};count1;// 导出的值同步更新为 1// test.jsimport{count}from./counter.js;console.log(count);// 13. 提升行为// require - 没有提升console.log(add);// ReferenceErrorconst{add}require(./math);// import - 自动提升console.log(add);// ✅ 正常工作import{add}from./math.js;// 实际在文件顶部执行4. 条件导入// require - ✅ 支持条件导入letconfig;if(process.env.NODE_ENVproduction){configrequire(./config.prod);}else{configrequire(./config.dev);}// import - ❌ 不支持静态条件导入// ✅ 使用动态导入替代letconfig;if(process.env.NODE_ENVproduction){configawaitimport(./config.prod.js);}else{configawaitimport(./config.dev.js);}性能对比// require - 每次调用都执行模块代码constmath1require(./math);// 执行模块代码constmath2require(./math);// 使用缓存不重复执行// import - 只执行一次自动缓存import{add}from./math.js;// 执行并缓存import{subtract}from./math.js;// 使用缓存使用场景使用 require() 当需要条件导入动态加载模块兼容老项目编写简单脚本使用 import 当新项目开发需要 tree-shaking 优化使用现代框架React、Vue跨平台代码浏览器 Node.js迁移指南CommonJS → ES Modules// 之前 (CJS)constexpressrequire(express);const{join}require(path);constappexpress();module.exportsapp;// 之后 (ESM)importexpressfromexpress;import{join}frompath;constappexpress();exportdefaultapp;实用技巧动态导入替代条件 require// 根据环境动态加载constisDevprocess.env.NODE_ENV!production;if(isDev){const{hot}awaitimport(./hot.js);hot.enable();}两者互操作// 在 ESM 中导入 CJSimportexpressfromexpress;// ✅ 支持良好// 在 CJS 中导入 ESM需要动态导入asyncfunctionloadESM(){const{add}awaitimport(./math.mjs);returnadd(1,2);}快速参考// CommonJSconst{add}require(./math);module.exports{value:1};// ES Modulesimport{add}from./math.js;exportconstvalue1;总结require()灵活、动态适合复杂场景import现代、静态性能更好新项目优先使用 import享受更好的开发体验和工具支持