64、js 中require和import有何区别?
在 JavaScript 中,require 和 import 都是用于模块导入的语法,但它们属于不同的模块系统,具有显著的区别:
1. 模块系统不同
require
属于 CommonJS 模块系统(Node.js 默认使用)。
语法:const module = require(‘./module’)
- 动态加载:在代码运行时同步加载模块。
- 可以导入任何类型的文件(.js、.json 等)。
- 模块导出是对象(module.exports 或 exports)。
import
属于 ES6 模块系统(ECMAScript 2015+ 标准)。
语法:import module from ‘./module.js’
- 静态加载:在代码解析阶段(编译时)确定依赖关系。
- 默认支持 .js、.mjs 或通过 package.json 的 “type”: “module” 标记的文件。
- 模块导出是只读的静态绑定(导出值在编译时确定)。
2. 加载时机
require
- 同步加载:模块在代码执行到 require 时才会加载,可能阻塞后续代码。
- 支持条件导入(如 if (condition) { require(…) })。
import
- 静态加载:模块依赖在代码解析阶段确定,无法动态导入(但可通过 import() 动态导入)。
- 必须写在顶层作用域(不能在条件语句或函数内使用,除非用 import())。
3. 语法差异
require
const fs = require('fs'); // 导入整个模块
const { readFile } = require('fs'); // 解构导入
import
import fs from 'fs'; // 默认导入
import { readFile } from 'fs'; // 命名导入
import * as fs from 'fs'; // 导入所有命名导出
import fs from 'fs/promises'; // 导入子模块(路径需完整)
4. 动态导入
require
直接内联使用,无需额外语法。
import
通过 import() 函数实现动态导入(返回 Promise):
const module = await import('./module.js');
5. 顶层 this 行为
require
模块中的 this 指向 module.exports。
import
模块中的 this 是 undefined(严格模式)。
6. 使用环境
require
主要用于 Node.js 环境(传统项目),或通过 Babel/Webpack 转译的浏览器代码。
import
现代浏览器原生支持(需声明 type=“module”),Node.js 从 v12 开始也支持 ES 模块(需文件后缀 .mjs 或 package.json 配置)。
7. 缓存机制
require
模块首次加载后会被缓存,后续 require 直接读取缓存。
import
同样有缓存,但行为更严格(静态分析时确定依赖)。
如何选择?
- Node.js 项目:传统项目用 require,现代项目可用 import(需配置 “type”: “module”)。
- 浏览器项目:优先使用 import(配合打包工具如 Webpack/Rollup)。
- 动态加载:require 更灵活,ES 模块用 import()。
如果需要兼容性,Babel/TypeScript 可以将 import 转译为 require。