如何正确实现Express + Node.js + Browserify 解决客户端require未定义错误
核心问题澄清
你完全不需要使用Browserify,你碰到的报错本质是服务端代码和客户端代码的职责混淆导致的:
- 根目录下的
app.js是纯服务端代码,本就运行在Node.js环境中,不需要做任何编译处理,也不会被浏览器加载 - 报错是因为你错误地在
site/js/app.js(会被浏览器加载的前端代码)中使用了仅Node环境支持的require语法
最优实现方案(无额外构建工具,远优于Browserify方案)
1. 调整文件内容
- 根目录
app.js保留你当前编写的服务端代码即可,不需要做任何修改,这个文件是用来启动Node服务的,永远不会被浏览器加载 - 清空
site/js/app.js中所有带require的服务端代码,仅保留前端交互逻辑
2. 修正package.json配置
将main字段指向服务端入口文件:
{ "name": "gaminggalaxy", "version": "1.0.0", "main": "app.js", // 仅修改这一行,其余配置保留 "dependencies": { "body-parser": "^1.19.0", "express": "^4.17.1", "node-fetch": "^2.6.6", "nodemon": "^2.0.15" }, "scripts": { "serve": "node app", "dev": "nodemon app" } // 其余配置保留 }
3. 编写前端交互逻辑(写入site/js/app.js)
如果需要无刷新提交表单,直接用浏览器原生API实现即可,不需要任何依赖加载:
const submitForm = document.querySelector('form'); submitForm.addEventListener('submit', e => { e.preventDefault(); const userEmail = document.getElementById('email').value; fetch('/subscribe', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: userEmail, js: true }) }).then(res => { if(res.ok) { alert('订阅成功'); submitForm.reset(); } else { alert('订阅失败,请重试'); } }).catch(err => alert('网络错误:' + err)); });
4. 启动服务
- 本地开发执行
npm run dev - 线上部署执行
npm run serve
不推荐使用Browserify的原因
Browserify的作用是把Node端的CommonJS模块打包成浏览器可识别的代码,但你用到的express、request等服务端依赖本身就不支持在浏览器环境运行,就算强行打包也会报错,完全不符合你的使用场景,只会徒增项目复杂度。
额外优化建议
request库已经停止维护,建议替换为node-fetch或Node内置的http模块- 不要将Mailchimp的API密钥硬编码在代码中,上线后建议通过环境变量读取,避免密钥泄露
- 可以删除package.json中冗余的
commonjs、prototype、requirejs等无用依赖,减少项目体积
内容的提问来源于stack exchange,提问作者Thomas Zbodula
相关产品推荐
相关产品推荐

