使用CommonJS导出JS文件引发浏览器module未定义错误求助
解决Node.js模块导出在浏览器中报错
module is not defined的问题 你遇到的问题根源在于module.exports是Node.js专属的CommonJS模块语法,浏览器环境中不存在module全局对象,因此会抛出引用错误。以下是几种兼容Node.js测试和浏览器运行的可行方案:
方法1:条件导出(最省心的兼容方案)
通过判断当前环境是否支持CommonJS,分别处理导出逻辑:Node环境用module.exports,浏览器环境把函数挂载到window对象上。
修改你的业务代码:
function getComputerChoice() { // 你的实现代码 } function playRound(playerSelection, computerSelection) { // 你的实现代码 } function game() { // 你的实现代码 } // 条件判断环境,分别处理导出 if (typeof module !== 'undefined' && module.exports) { // Node.js/测试环境 module.exports = { getComputerChoice, playRound, game, }; } else { // 浏览器环境,挂载到全局window window.RockPaperScissors = { getComputerChoice, playRound, game, }; }
- 测试用例无需修改,依然用
require导入 - 浏览器中可以通过
RockPaperScissors.playRound()直接调用函数
方法2:改用ES模块(现代标准方案)
ES模块(ESM)是浏览器和Node.js都支持的标准模块语法,适合现代项目。
第一步:修改业务代码为ES导出
// 命名导出 export function getComputerChoice() { // 你的实现代码 } export function playRound(playerSelection, computerSelection) { // 你的实现代码 } export function game() { // 你的实现代码 } // 或者用默认导出(二选一) // export default { getComputerChoice, playRound, game };
第二步:调整测试文件
如果使用Jest,需要确保项目支持ESM:
- 在
package.json中添加"type": "module" - 或者把测试文件后缀改为
.mjs
修改测试文件的导入语法:
// 命名导出的导入方式 import * as rockPaperScissors from '../rockPaperScissors.js'; // 如果是默认导出,用下面的方式 // import rockPaperScissors from '../rockPaperScissors.js'; test('Verify the case for tie', () => { expect(rockPaperScissors.playRound('rock', 'rock')).toBe('TIE'); }); test('Verify the case for win', () => { expect(rockPaperScissors.playRound('rock', 'scissors')).toBe('WIN'); }); test('Verify the case for lose', () => { expect(rockPaperScissors.playRound('rock', 'paper')).toBe('LOSE'); });
第三步:浏览器中引用模块
在HTML中引用脚本时,必须加上type="module":
<script type="module" src="rockPaperScissors.js"></script>
注意:ES模块在浏览器中遵循同源策略,本地打开HTML时建议用本地服务器(比如npx serve),否则会出现CORS错误。
方法3:IIFE封装(兼容旧浏览器方案)
如果需要兼容不支持ES模块的旧浏览器,可以用立即执行函数(IIFE)包裹代码,避免污染全局作用域,同时支持双向导出:
(function(window) { function getComputerChoice() { // 你的实现代码 } function playRound(playerSelection, computerSelection) { // 你的实现代码 } function game() { // 你的实现代码 } // 暴露给浏览器全局 window.RockPaperScissors = { getComputerChoice, playRound, game, }; // 支持Node.js测试环境导出 if (typeof module !== 'undefined' && module.exports) { module.exports = { getComputerChoice, playRound, game, }; } })(window);
这种方案兼容性极强,几乎支持所有浏览器,同时不影响Node.js测试。
内容的提问来源于stack exchange,提问作者bigeasy
相关产品推荐
相关产品推荐

