commonjs不能直接在浏览器运行,需通过打包工具注入运行时、手动实现最小运行环境或使用browserify等兼容层;注意避开node原生模块不可用、动态require不支持及import/require混用等陷阱。

CommonJS 本身不能直接在非 Node 环境(比如浏览器)中运行,因为浏览器缺少 require、module、exports 和 __filename 等核心运行时变量,也没有同步读取本地文件的能力。但可以通过“模拟运行时”或“构建转换”两种主流方式让它在浏览器等环境中工作。
用打包工具注入 CommonJS 运行时
这是最常用、最可靠的方式。Webpack、Rollup、Parcel 等现代打包工具会在构建阶段:
- 静态分析
require()和module.exports语句 - 将所有模块合并为一个或多个 bundle 文件
- 自动注入一段轻量级的 CommonJS 模块加载器(类似 IIFE 包裹 + 模块缓存对象)
- 把
require('./math')替换为对内部模块注册表的查找调用
例如 Webpack 生成的代码里会有一个 __webpack_require__ 函数,它模拟了 Node 的模块查找、执行和缓存逻辑。你无需手动写,只要配置好入口和 target(如 target: 'web'),就能让 CommonJS 代码正常运行。
手动提供最小 CommonJS 运行环境
如果不想用打包工具,也可以自己实现极简版运行时。关键是要提供四个变量:
-
module:带exports属性的对象 -
exports:初始指向module.exports -
require:一个能根据路径查找并执行模块的函数 -
__filename和__dirname(可选,部分模块依赖它们)
示例(仅限简单场景):
const modules = {};
function require(path) {
if (modules[path]) return modules[path].exports;
const exports = {};
const module = { exports };
// 手动执行模块代码(需提前加载好源码)
eval(`(function(module, exports) { ${getModuleCode(path)} })(module, exports)`);
modules[path] = module;
return module.exports;
}
这种方式适合学习原理或超轻量实验,但不推荐用于生产——没有路径解析、无缓存策略、不支持循环引用、无法处理二进制或 JSON 模块。
用兼容层库桥接(如 Browserify)
Browserify 是专为浏览器设计的 CommonJS 工具。它把项目中所有 require() 语句静态分析后,递归打包成单个 JS 文件,并内置一套与 Node 高度兼容的模块系统(包括 fs、path 等核心模块的浏览器适配版)。使用方式很简单:
- 安装:
npm install -g browserify - 打包:
browserify main.js -o bundle.js - 在 HTML 中引入
bundle.js即可运行
它的优势是零配置、Node API 兼容性好;缺点是包体积略大,且不支持动态 require()(即字符串拼接路径)。
注意避开常见陷阱
即使挂载成功,也要留意几个限制:
-
fs、net、child_process等 Node 原生模块在浏览器里不可用,必须用 polyfill 或替换为对应浏览器 API(如fetch代替http) - CommonJS 是同步加载,而浏览器资源加载本质是异步的——打包工具通过预编译解决这个问题,但无法支持真正的运行时动态
require('xxx'+Math.random()) - 不要混用
import和require在同一文件中(尤其未启用双重模块支持时),容易引发解析错误
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











