如何从独立文件向Node.js与前端JavaScript导出对象?
解决前后端共用Socket事件常量的几种实用方案
这问题我之前做Socket项目时也碰到过,刚好有几个靠谱的解决办法,给你列出来:
方案1:让utils.js同时兼容CommonJS和ES模块
这是最直接的方式,修改你的文件,让它能同时适配Node.js(CommonJS)和前端(ES模块/传统脚本):
const EVENTS = { CONNECTION: 'connection', MESSAGE: 'message' }; Object.freeze(EVENTS); // 适配Node.js的CommonJS导出 if (typeof module !== 'undefined' && module.exports) { module.exports = EVENTS; } // 适配前端ES模块 else if (typeof export !== 'undefined') { export default EVENTS; } // 适配前端非模块脚本(直接挂载到全局) else { window.EVENTS = EVENTS; }
- 后端使用:
const EVENTS = require('./utils.js') - 前端ES模块场景:
import EVENTS from './utils.js' - 前端传统脚本场景:直接用
window.EVENTS
方案2:用package.json统一模块类型(Node.js 12+适用)
如果你的Node.js版本在12以上,可以在项目根目录的package.json里添加一行配置,让Node.js默认识别ES模块:
{ "type": "module" }
然后把utils.js改成纯ES模块写法:
export const EVENTS = Object.freeze({ CONNECTION: 'connection', MESSAGE: 'message' });
这样前后端都可以用统一的ES模块语法导入:import { EVENTS } from './utils.js'。如果项目里还有遗留的CommonJS文件,只需要把它们的后缀改成.cjs,Node.js会自动识别为CommonJS模块。
方案3:借助构建工具自动转译(适合复杂项目)
如果你的前端已经在用Webpack、Vite这类构建工具,完全可以直接保留现有的CommonJS版本utils.js——构建工具会自动把CommonJS模块转译成前端能识别的格式。你只需要在前端代码里正常写:
import EVENTS from './utils.js'
构建过程中工具会帮你搞定兼容性问题,不用额外修改文件。
小提示
你已经用Object.freeze()把EVENTS设为不可变,这点非常棒!能有效避免前后端不小心修改事件名称导致的匹配错误,一定要保持这个习惯。
内容的提问来源于stack exchange,提问作者Yos
相关产品推荐
相关产品推荐

