nw-react-scripts启动时node-main脚本未执行,如何让NW先启动Express服务?
我用create-nw-react-app和Sqlite开发桌面应用,因为NW.js编译原生模块难度极高,打算通过package.json的node-main特性在前端加载前启动Express服务器。但执行nw-react-scripts start时,node-main指定的脚本并未运行,单独启动Express服务器则正常工作。之前把start脚本改成concurrently "node api/server.js" "nw-react-scripts start"仅在开发环境有效,想知道怎么让NW在启动React应用前就把服务器跑起来?
我的package.json配置如下:
{ "name": "ultimo", "node-main": "api/server.js", "version": "0.1.0", "private": true, "dependencies": { "@testing-library/jest-dom": "^5.11.4", "@testing-library/react": "^11.1.0", "@testing-library/user-event": "^12.1.10", "@types/jest": "^26.0.15", "@types/node": "^12.0.0", "@types/nw.js": "^0.13.13", "@types/react": "^17.0.0", "@types/react-dom": "^17.0.0", "better-sqlite3": "^8.0.1", "body-parser": "^1.20.1", "cors": "^2.8.5", "express": "^4.18.2", "express-session": "^1.17.3", "nw-react-scripts": "4.0.4", "react": "^18.2.0", "react-dom": "^18.2.0", "typescript": "^4.1.2", "web-vitals": "^1.0.1" }, "scripts": { "start": "nw-react-scripts start", "build": "nw-react-scripts build", "test": "nw-react-scripts test", "eject": "nw-react-scripts eject" }, "eslintConfig": { "extends": [ "nw-react-app", "nw-react-app/jest" ] }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] }, "main": "index.html", "nwBuilder": { "//": "https://github.com/nwjs-community/nw-builder", "platforms": [ "osx64", "win32", "win64" ], "version": "latest", "flavor": "normal", "buildDir": "./build", "cacheDir": "./cache", "macIcns": "./src/logo.icns" }, "devDependencies": { "concurrently": "^7.6.0", "wait-on": "^7.0.1" } }
解决方案
1. 修复开发环境的启动顺序
nw-react-scripts start默认会忽略node-main配置,直接启动NW指向React开发服务器。可以通过拆分脚本+等待服务器就绪来解决:
修改package.json的scripts字段:
"scripts": { "start": "npm run start-server && npm run start-nw", "start-server": "node api/server.js", "start-nw": "wait-on http://localhost:3001 && nw-react-scripts start" }
注:替换
http://localhost:3001为你的Express服务器实际端口,wait-on会等服务器就绪后再启动NW,避免React提前加载导致请求失败。
2. 确保生产构建时node-main生效
生产环境下,nw-react-scripts build生成静态文件后,NW会读取node-main,但需要确保服务器脚本被打包:
在package.json中添加files字段,指定要包含的文件:
"files": [ "api/", "build/" ]
这样nw-builder打包时会把api目录和build目录都包含进去,保证node-main能找到脚本。
3. 直接在React入口启动服务器(通用方案)
如果不想依赖node-main,可以在React初始化前通过NW的Node API启动服务器,开发/生产环境都适用:
// src/index.tsx 或 src/index.js if (typeof nw !== 'undefined') { // 仅在NW环境下启动服务器 require('../api/server.js'); } // 正常渲染React应用 ReactDOM.render( <React.StrictMode> <App /> </React.StrictMode>, document.getElementById('root') );
这种方式无需额外配置,直接在前端入口触发服务器启动,避免了node-main的兼容性问题。
4. 验证node-main配置正确性
检查package.json中的node-main路径是否为相对路径,确保api/server.js存在且能独立运行。NW.js要求node-main和main字段需同时存在(main指向前端入口,node-main指向Node脚本)。
内容的提问来源于stack exchange,提问作者Luca Di Molfetta

