diff --git a/package.json b/package.json index 18ddbd1c81b..bd8048a0fb6 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,8 @@ "scripts": { "start": "yarn start:browser", "start:server": "yarn workspace @actual-app/sync-server start", + "start:server-monitor": "yarn workspace @actual-app/sync-server start-monitor", + "start:server-dev": "NODE_ENV=development BROWSER_OPEN=localhost:5006 yarn npm-run-all --parallel 'start:server-monitor' 'start'", "start:desktop": "yarn rebuild-electron && npm-run-all --parallel 'start:desktop-*'", "start:desktop-node": "yarn workspace loot-core watch:node", "start:desktop-client": "yarn workspace @actual-app/web watch", diff --git a/packages/desktop-client/vite.config.mts b/packages/desktop-client/vite.config.mts index fd0b9acb1a4..69ddbb80003 100644 --- a/packages/desktop-client/vite.config.mts +++ b/packages/desktop-client/vite.config.mts @@ -103,6 +103,8 @@ export default defineConfig(async ({ mode }) => { ]; } + const browserOpen = env.BROWSER_OPEN ? `//${env.BROWSER_OPEN}` : true; + return { base: '/', envPrefix: 'REACT_APP_', @@ -139,7 +141,7 @@ export default defineConfig(async ({ mode }) => { ? ['chrome', 'firefox', 'edge', 'browser', 'browserPrivate'].includes( env.BROWSER, ) - : true, + : browserOpen, watch: { disableGlobbing: false, }, diff --git a/packages/sync-server/package.json b/packages/sync-server/package.json index d5de6102a71..9b8f9b63e1e 100644 --- a/packages/sync-server/package.json +++ b/packages/sync-server/package.json @@ -6,6 +6,7 @@ "type": "module", "scripts": { "start": "node app", + "start-monitor": "nodemon app", "lint": "eslint . --max-warnings 0", "lint:fix": "eslint . --fix", "build": "tsc", @@ -57,7 +58,9 @@ "@typescript-eslint/parser": "^5.51.0", "eslint": "^8.33.0", "eslint-plugin-prettier": "^4.2.1", + "http-proxy-middleware": "^3.0.3", "jest": "^29.3.1", + "nodemon": "^3.1.9", "prettier": "^2.8.3", "supertest": "^6.3.1", "typescript": "^4.9.5" diff --git a/packages/sync-server/src/app.js b/packages/sync-server/src/app.js index 78bde184e5f..42d333a8259 100644 --- a/packages/sync-server/src/app.js +++ b/packages/sync-server/src/app.js @@ -5,6 +5,7 @@ import cors from 'cors'; import express from 'express'; import actuator from 'express-actuator'; import rateLimit from 'express-rate-limit'; +import { createProxyMiddleware } from 'http-proxy-middleware'; import * as accountApp from './app-account.js'; import * as adminApp from './app-admin.js'; @@ -24,14 +25,17 @@ process.on('unhandledRejection', reason => { app.disable('x-powered-by'); app.use(cors()); app.set('trust proxy', config.trustedProxies); -app.use( - rateLimit({ - windowMs: 60 * 1000, - max: 500, - legacyHeaders: false, - standardHeaders: true, - }), -); +if (process.env.NODE_ENV !== 'development') { + app.use( + rateLimit({ + windowMs: 60 * 1000, + max: 500, + legacyHeaders: false, + standardHeaders: true, + }), + ); +} + app.use(bodyParser.json({ limit: `${config.upload.fileSizeLimitMB}mb` })); app.use( bodyParser.raw({ @@ -67,9 +71,25 @@ app.use((req, res, next) => { res.set('Cross-Origin-Embedder-Policy', 'require-corp'); next(); }); -app.use(express.static(config.webRoot, { index: false })); +if (process.env.NODE_ENV === 'development') { + console.log( + 'Running in development mode - Proxying frontend routes to React Dev Server', + ); + + app.use( + createProxyMiddleware({ + target: 'http://localhost:3001', + changeOrigin: true, + ws: true, + logLevel: 'debug', + }), + ); +} else { + console.log('Running in production mode - Serving static React app'); -app.get('/*', (req, res) => res.sendFile(config.webRoot + '/index.html')); + app.use(express.static(config.webRoot, { index: false })); + app.get('/*', (req, res) => res.sendFile(config.webRoot + '/index.html')); +} function parseHTTPSConfig(value) { if (value.startsWith('-----BEGIN')) { diff --git a/upcoming-release-notes/4372.md b/upcoming-release-notes/4372.md new file mode 100644 index 00000000000..fe0bd325863 --- /dev/null +++ b/upcoming-release-notes/4372.md @@ -0,0 +1,6 @@ +--- +category: Enhancements +authors: [lelemm] +--- + +Sync server development mode with react fast refresh diff --git a/yarn.lock b/yarn.lock index f8fb5e7d118..0c6ecd67aee 100644 --- a/yarn.lock +++ b/yarn.lock @@ -110,9 +110,11 @@ __metadata: express-rate-limit: "npm:^6.7.0" express-response-size: "npm:^0.0.3" express-winston: "npm:^4.2.0" + http-proxy-middleware: "npm:^3.0.3" jest: "npm:^29.3.1" jws: "npm:^4.0.0" migrate: "npm:^2.0.1" + nodemon: "npm:^3.1.9" nordigen-node: "npm:^1.4.0" openid-client: "npm:^5.4.2" prettier: "npm:^2.8.3" @@ -6363,6 +6365,15 @@ __metadata: languageName: node linkType: hard +"@types/http-proxy@npm:^1.17.15": + version: 1.17.16 + resolution: "@types/http-proxy@npm:1.17.16" + dependencies: + "@types/node": "npm:*" + checksum: 10/a054ac8f5301acfcfdcec3a775f52dc371180bbe60037906534312f10cceb3799b4a16e46c56c22f9925d078e11dcda1723c38f1ddd124be8169a4cccca69c8c + languageName: node + linkType: hard + "@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.0, @types/istanbul-lib-coverage@npm:^2.0.1": version: 2.0.4 resolution: "@types/istanbul-lib-coverage@npm:2.0.4" @@ -8935,6 +8946,25 @@ __metadata: languageName: node linkType: hard +"chokidar@npm:^3.5.2": + version: 3.6.0 + resolution: "chokidar@npm:3.6.0" + dependencies: + anymatch: "npm:~3.1.2" + braces: "npm:~3.0.2" + fsevents: "npm:~2.3.2" + glob-parent: "npm:~5.1.2" + is-binary-path: "npm:~2.1.0" + is-glob: "npm:~4.0.1" + normalize-path: "npm:~3.0.0" + readdirp: "npm:~3.6.0" + dependenciesMeta: + fsevents: + optional: true + checksum: 10/c327fb07704443f8d15f7b4a7ce93b2f0bc0e6cea07ec28a7570aa22cd51fcf0379df589403976ea956c369f25aa82d84561947e227cd925902e1751371658df + languageName: node + linkType: hard + "chownr@npm:^1.1.1": version: 1.1.4 resolution: "chownr@npm:1.1.4" @@ -9889,7 +9919,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:^4.3.7": +"debug@npm:^4, debug@npm:^4.3.6, debug@npm:^4.3.7": version: 4.4.0 resolution: "debug@npm:4.4.0" dependencies: @@ -11729,7 +11759,7 @@ __metadata: languageName: node linkType: hard -"eventemitter3@npm:^4.0.1": +"eventemitter3@npm:^4.0.0, eventemitter3@npm:^4.0.1": version: 4.0.7 resolution: "eventemitter3@npm:4.0.7" checksum: 10/8030029382404942c01d0037079f1b1bc8fed524b5849c237b80549b01e2fc49709e1d0c557fa65ca4498fc9e24cff1475ef7b855121fcc15f9d61f93e282346 @@ -12315,7 +12345,7 @@ __metadata: languageName: node linkType: hard -"follow-redirects@npm:^1.15.6": +"follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.15.6": version: 1.15.9 resolution: "follow-redirects@npm:1.15.9" peerDependenciesMeta: @@ -13277,6 +13307,31 @@ __metadata: languageName: node linkType: hard +"http-proxy-middleware@npm:^3.0.3": + version: 3.0.3 + resolution: "http-proxy-middleware@npm:3.0.3" + dependencies: + "@types/http-proxy": "npm:^1.17.15" + debug: "npm:^4.3.6" + http-proxy: "npm:^1.18.1" + is-glob: "npm:^4.0.3" + is-plain-object: "npm:^5.0.0" + micromatch: "npm:^4.0.8" + checksum: 10/32f58c29288ca63e109909fb998bd0f6f50eb15a98dec9487eac07dfc4f09d8507dbfa00b44442d868bafa904bd633c8bbd55686bb13b4d4af4f5c5b3bbca430 + languageName: node + linkType: hard + +"http-proxy@npm:^1.18.1": + version: 1.18.1 + resolution: "http-proxy@npm:1.18.1" + dependencies: + eventemitter3: "npm:^4.0.0" + follow-redirects: "npm:^1.0.0" + requires-port: "npm:^1.0.0" + checksum: 10/2489e98aba70adbfd8b9d41ed1ff43528be4598c88616c558b109a09eaffe4bb35e551b6c75ac42ed7d948bb7530a22a2be6ef4f0cecacb5927be139f4274594 + languageName: node + linkType: hard + "http2-wrapper@npm:^1.0.0-beta.5.2": version: 1.0.3 resolution: "http2-wrapper@npm:1.0.3" @@ -13423,6 +13478,13 @@ __metadata: languageName: node linkType: hard +"ignore-by-default@npm:^1.0.1": + version: 1.0.1 + resolution: "ignore-by-default@npm:1.0.1" + checksum: 10/441509147b3615e0365e407a3c18e189f78c07af08564176c680be1fabc94b6c789cad1342ad887175d4ecd5225de86f73d376cec8e06b42fd9b429505ffcf8a + languageName: node + linkType: hard + "ignore@npm:^5.1.1, ignore@npm:^5.2.0, ignore@npm:^5.3.1": version: 5.3.2 resolution: "ignore@npm:5.3.2" @@ -16864,7 +16926,7 @@ __metadata: languageName: node linkType: hard -"micromatch@npm:^4.0.4, micromatch@npm:~4.0.7": +"micromatch@npm:^4.0.4, micromatch@npm:^4.0.8, micromatch@npm:~4.0.7": version: 4.0.8 resolution: "micromatch@npm:4.0.8" dependencies: @@ -17420,6 +17482,26 @@ __metadata: languageName: node linkType: hard +"nodemon@npm:^3.1.9": + version: 3.1.9 + resolution: "nodemon@npm:3.1.9" + dependencies: + chokidar: "npm:^3.5.2" + debug: "npm:^4" + ignore-by-default: "npm:^1.0.1" + minimatch: "npm:^3.1.2" + pstree.remy: "npm:^1.1.8" + semver: "npm:^7.5.3" + simple-update-notifier: "npm:^2.0.0" + supports-color: "npm:^5.5.0" + touch: "npm:^3.1.0" + undefsafe: "npm:^2.0.5" + bin: + nodemon: bin/nodemon.js + checksum: 10/7c01ddfa30815f4147006f5b7c015a1f75017118cf398ee8c4ba3ac904667f4555b91cca6b7b191e0f6ccf5072727aa20224a1456d5446f3f6053e15132068a2 + languageName: node + linkType: hard + "noms@npm:0.0.0": version: 0.0.0 resolution: "noms@npm:0.0.0" @@ -18542,6 +18624,13 @@ __metadata: languageName: node linkType: hard +"pstree.remy@npm:^1.1.8": + version: 1.1.8 + resolution: "pstree.remy@npm:1.1.8" + checksum: 10/ef13b1b5896b35f67dbd4fb7ba54bb2a5da1a5c317276cbad4bcad4159bf8f7b5e1748dc244bf36865f3d560d2fc952521581280a91468c9c2df166cc760c8c1 + languageName: node + linkType: hard + "pump@npm:^3.0.0": version: 3.0.0 resolution: "pump@npm:3.0.0" @@ -20251,7 +20340,7 @@ __metadata: languageName: node linkType: hard -"simple-update-notifier@npm:2.0.0": +"simple-update-notifier@npm:2.0.0, simple-update-notifier@npm:^2.0.0": version: 2.0.0 resolution: "simple-update-notifier@npm:2.0.0" dependencies: @@ -20974,7 +21063,7 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^5.3.0": +"supports-color@npm:^5.3.0, supports-color@npm:^5.5.0": version: 5.5.0 resolution: "supports-color@npm:5.5.0" dependencies: @@ -21413,6 +21502,15 @@ __metadata: languageName: node linkType: hard +"touch@npm:^3.1.0": + version: 3.1.1 + resolution: "touch@npm:3.1.1" + bin: + nodetouch: bin/nodetouch.js + checksum: 10/853e763a1f4903302c5654ed353f84ad85baf757dac62c2d37ab67e0477cfd271e8c64771fcfad42310aff7c9d284ddb435ee5ca13ff36d0f3693fedd8e971d1 + languageName: node + linkType: hard + "tough-cookie@npm:^4.0.0": version: 4.1.4 resolution: "tough-cookie@npm:4.1.4" @@ -21907,6 +22005,13 @@ __metadata: languageName: node linkType: hard +"undefsafe@npm:^2.0.5": + version: 2.0.5 + resolution: "undefsafe@npm:2.0.5" + checksum: 10/f42ab3b5770fedd4ada175fc1b2eb775b78f609156f7c389106aafd231bfc210813ee49f54483d7191d7b76e483bc7f537b5d92d19ded27156baf57592eb02cc + languageName: node + linkType: hard + "underscore.string@npm:~3.3.4": version: 3.3.6 resolution: "underscore.string@npm:3.3.6"