JavaScript模块化通过export/import实现封装复用,ES6模块(ESM)为标准方式,支持静态分析与默认/命名导出导入;CommonJS(CJS)在Node.js中仍常用,使用module.exports/require动态加载;二者路径规则、扩展名处理及互操作性存在差异。
JavaScript模块化通过export和import实现代码的封装与复用,让不同文件能明确声明“提供什么”和“需要什么”,避免全局污染和依赖混乱。
现代浏览器和Node.js(v14+默认启用)都支持原生ES模块。它基于静态分析,在代码编译阶段就确定依赖关系,不支持条件导入或动态路径拼接(除非用import()动态导入)。
export声明变量、函数、类;可默认导出一个(export default),也可命名导出多个(export const a = 1)import加载模块;默认导入写法为import xxx from './module.js';命名导入需用大括号import { a, b } from './module.js'
type="module"(HTML中)或以.mjs结尾 / "type": "module"(package.json中),否则Node.js按CommonJS处理Node.js早期采用CommonJS规范,使用module.exports和require(),属于运行时动态加载,支持条件判断和拼接路径。
module.exports = {...} 或 exports.xxx = ...(后者是前者引用)const mod = require('./module'),返回的是整个module.exports对象import cjs from './cjs-module'),但不能直接解构命名导入(import { x } from './cjs'会报错)导入路径决定了模块查找逻辑:
./utils、../config):从当前文件所在目录开始查找/src/index.js):从文件系统根开始(浏览器不支持,Node.js需注意权限)lodash):从node_modules中按包入口(package.json的main或exports字段)定位.js(或.mjs),CJS可省略(Node.js会依次尝试.js、.json、.node)
增强灵活性静态import必须在模块顶层,而import()是返回Promise的函数,可在条件语句、循环或异步函数中调用:
if (needChart) { const { Chart } = await import('chart.js'); }top-level await,允许模块在初始化时等待异步资源(如配置加载),其他模块导入它时也会等待完成