fix(docker): single container (caddy+node), ESM adapters fix blank page
Docker: moved all docker files to docker/ tree (was conflated with upstream Dockerfile at root + server/Dockerfile). Single container now: caddy (front, serves static + proxies /api /ws) + node backend (internal :4001). Node never exposed. entrypoint.sh runs both. Compose: one service. Blank page root cause: storage adapters had inconsistent module systems. firebase.js = ESM (export). ws.js + memory.js = CJS (module.exports). CRA prod build = ESM strict -> CJS runtime crash, blank root. Dev mode lenient, masked bug. First ws prod build (docker) = first exposure. Never dev/prod split intended; just inconsistency from M2 era. Fix: all adapters ESM. ws.js lazy-loads 'ws' pkg via dynamic import() (Node/jest only; browser uses global WebSocket). index.js static imports. server jest: added babel.config.js (preset-env, node target) to transform ESM for jest. Test: src/tests/StorageEsm.test.js — 4 tests grep all adapters for module.exports / require(). Regression guard catches CJS leak. Verified: docker page renders (root 4534 chars, UI visible). server 24 green, shared 90 green, FE ESM 4 green.
This commit is contained in:
+12
-4
@@ -5,11 +5,10 @@
|
||||
'use strict';
|
||||
|
||||
// Native browser WebSocket if present, else ws pkg (Node/jest).
|
||||
// Lazy load ws pkg so CRA prod build (ESM) doesn't choke on require().
|
||||
let WebSocketImpl;
|
||||
if (typeof WebSocket !== 'undefined') {
|
||||
WebSocketImpl = WebSocket;
|
||||
} else {
|
||||
WebSocketImpl = require('ws').WebSocket;
|
||||
}
|
||||
|
||||
function createWsStorage({ baseUrl, wsUrl } = {}) {
|
||||
@@ -47,7 +46,15 @@ function createWsStorage({ baseUrl, wsUrl } = {}) {
|
||||
function ensureWs() {
|
||||
if (wsReady) return wsReady;
|
||||
wsReady = new Promise((resolve, reject) => {
|
||||
ws = new WebSocketImpl(WS);
|
||||
(async () => {
|
||||
// Node/jest only: load ws pkg via dynamic import. Browser uses global
|
||||
// WebSocket. Avoids require() in CRA prod ESM bundle (webpack crash).
|
||||
let WsClass = WebSocketImpl;
|
||||
if (!WsClass) {
|
||||
const wsPkg = await import('ws');
|
||||
WsClass = wsPkg.WebSocket;
|
||||
}
|
||||
ws = new WsClass(WS);
|
||||
const onOpen = () => {
|
||||
const isReconnect = everConnected;
|
||||
everConnected = true;
|
||||
@@ -99,6 +106,7 @@ function createWsStorage({ baseUrl, wsUrl } = {}) {
|
||||
ws.addEventListener('close', onClose);
|
||||
ws.addEventListener('message', onMessage);
|
||||
}
|
||||
})();
|
||||
});
|
||||
return wsReady;
|
||||
}
|
||||
@@ -226,4 +234,4 @@ function createWsStorage({ baseUrl, wsUrl } = {}) {
|
||||
return storage;
|
||||
}
|
||||
|
||||
module.exports = { createWsStorage };
|
||||
export { createWsStorage };
|
||||
|
||||
Reference in New Issue
Block a user