require() vs import:Node.js 模块导入对比

require() vs import:Node.js 模块导入对比

理解两种导入方式的核心区别

快速对比

特性 require() import
加载方式 运行时、同步 编译时、静态
模块系统 CommonJS ES Modules
提升行为 可在任意位置调用 自动提升到顶部
条件导入 支持 不支持
文件扩展名 可省略 必须写 .js

基本语法

require()

javascript 复制代码
// 导入整个模块
const fs = require('fs');

// 解构导入
const { readFile } = require('fs');

// 条件导入
if (needFeature) {
  const feature = require('./feature');
  feature.init();
}

// 任意位置调用
function loadModule() {
  const math = require('./math');
  return math.add(1, 2);
}

import

javascript 复制代码
// 导入整个模块
import * as fs from 'fs';

// 解构导入
import { readFile } from 'fs';

// 默认导入
import express from 'express';

// 必须在文件顶部
import { add } from './math.js';  // 注意要写 .js

// ❌ 不支持条件导入
// if (needFeature) {
//   import { feature } from './feature';  // 错误
// }

// ✅ 动态导入(返回 Promise)
if (needFeature) {
  const { feature } = await import('./feature.js');
  feature.init();
}

核心区别

1. 加载时机

javascript 复制代码
// require - 运行时加载
console.log('before require');
const math = require('./math');  // 执行到这里才加载
console.log('after require');

// import - 编译时加载(代码执行前已完成)
console.log('before import');
import { add } from './math.js';  // 代码执行前已加载
console.log('after import');

2. 值拷贝 vs 动态引用

javascript 复制代码
// counter.js (CommonJS)
let count = 0;
module.exports = { count };
count = 1;  // 导出的值仍是 0

// test.js
const { count } = require('./counter');
console.log(count);  // 0

// counter.js (ES Modules)
let count = 0;
export { count };
count = 1;  // 导出的值同步更新为 1

// test.js
import { count } from './counter.js';
console.log(count);  // 1

3. 提升行为

javascript 复制代码
// require - 没有提升
console.log(add);  // ReferenceError
const { add } = require('./math');

// import - 自动提升
console.log(add);  // ✅ 正常工作
import { add } from './math.js';  // 实际在文件顶部执行

4. 条件导入

javascript 复制代码
// require - ✅ 支持条件导入
let config;
if (process.env.NODE_ENV === 'production') {
  config = require('./config.prod');
} else {
  config = require('./config.dev');
}

// import - ❌ 不支持静态条件导入
// ✅ 使用动态导入替代
let config;
if (process.env.NODE_ENV === 'production') {
  config = await import('./config.prod.js');
} else {
  config = await import('./config.dev.js');
}

性能对比

javascript 复制代码
// require - 每次调用都执行模块代码
const math1 = require('./math');  // 执行模块代码
const math2 = require('./math');  // 使用缓存,不重复执行

// import - 只执行一次,自动缓存
import { add } from './math.js';  // 执行并缓存
import { subtract } from './math.js';  // 使用缓存

使用场景

使用 require() 当:

  • 需要条件导入
  • 动态加载模块
  • 兼容老项目
  • 编写简单脚本

使用 import 当:

  • 新项目开发
  • 需要 tree-shaking 优化
  • 使用现代框架(React、Vue)
  • 跨平台代码(浏览器 + Node.js)

迁移指南

CommonJS → ES Modules

javascript 复制代码
// 之前 (CJS)
const express = require('express');
const { join } = require('path');
const app = express();

module.exports = app;

// 之后 (ESM)
import express from 'express';
import { join } from 'path';
const app = express();

export default app;

实用技巧

动态导入(替代条件 require)

javascript 复制代码
// 根据环境动态加载
const isDev = process.env.NODE_ENV !== 'production';

if (isDev) {
  const { hot } = await import('./hot.js');
  hot.enable();
}

两者互操作

javascript 复制代码
// 在 ESM 中导入 CJS
import express from 'express';  // ✅ 支持良好

// 在 CJS 中导入 ESM(需要动态导入)
async function loadESM() {
  const { add } = await import('./math.mjs');
  return add(1, 2);
}

快速参考

javascript 复制代码
// CommonJS
const { add } = require('./math');
module.exports = { value: 1 };

// ES Modules
import { add } from './math.js';
export const value = 1;

总结

  • require():灵活、动态,适合复杂场景
  • import:现代、静态,性能更好

新项目优先使用 import,享受更好的开发体验和工具支持!

相关推荐
码云之上10 小时前
上下文工程实战:解决多轮对话中的"上下文腐烂"问题
前端·node.js·agent
奔跑的呱呱牛16 小时前
前端/Node.js操作Excel实战:使用@giszhc/xlsx(导入+导出全流程)
前端·node.js·excel·xlsx·sheetjs
Southern Wind17 小时前
AI Skill Server 动态技能中台
前端·后端·mysql·node.js
米丘19 小时前
Vite 代理跨域全解析:从 server.proxy 到请求转发的实现原理
javascript·node.js·vite
CyrusCJA20 小时前
Nodejs自定义脚手架
javascript·node.js·js
AI视觉网奇1 天前
pnpm 安装笔记
node.js
奔跑的呱呱牛1 天前
xlsx 已停止维护且存在漏洞!推荐一个可直接替代的 npm 库
前端·npm·node.js·xlsx·sheetjs
码云之上1 天前
从一个截图函数到一个 npm 包——pdf-snapshot 的诞生记
前端·node.js·github
Kel1 天前
Pi Monorepo Stream Event Flow 深度分析
人工智能·架构·node.js
米丘2 天前
Connect 深度解析:Node.js 中间件框架的基石
javascript·http·node.js