commit 9dec174a2bf61d30704a926b51314913b42a49c6
parent 0100de4d409437ab52c104600af8bcd90a358099
Author: Pablo Murad <pablo@pablomurad.com>
Date: Wed, 6 May 2026 18:33:03 -0300
responsividade
Diffstat:
7 files changed, 34 insertions(+), 12 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -9,6 +9,7 @@ lerna-debug.log*
node_modules
dist
+dist-server
dist-ssr
*.local
diff --git a/README.md b/README.md
@@ -41,6 +41,8 @@ npm run build
SERVE_STATIC=true npm run start
```
+Production runs **compiled JavaScript** (`node dist-server/server/index.js`), not `tsx`. Dev still uses `tsx watch server/index.ts` for the API hot reload.
+
Or use **PM2** (from this folder, after `npm run build`):
```bash
@@ -121,7 +123,8 @@ Messages such as **“The kernel '…' for backend 'cpu' / 'webgl' is already re
|-------------------|--------------------------------------------------|
| `npm run dev` | Vite + API with hot reload |
| `npm run build` | Production frontend build |
-| `npm run start` | API (`tsx server/index.ts`); use `SERVE_STATIC=true` to also serve `dist/` |
+| `npm run start` | API (`node dist-server/server/index.js` — run `npm run build` first); `SERVE_STATIC=true` also serves `dist/` |
+| `npm run build:server` | Compile API + `config/ports` to `dist-server/` (included in `npm run build`) |
| `npm run pm2:prod`| `npm run build` then PM2 with `ecosystem.config.cjs` |
## Logo
diff --git a/ecosystem.config.cjs b/ecosystem.config.cjs
@@ -6,8 +6,7 @@ module.exports = {
{
name: "mymusics",
cwd: __dirname,
- script: "node_modules/tsx/dist/cli.mjs",
- args: "server/index.ts",
+ script: "dist-server/server/index.js",
instances: 1,
exec_mode: "fork",
autorestart: true,
diff --git a/eslint.config.js b/eslint.config.js
@@ -6,7 +6,7 @@ import tseslint from 'typescript-eslint'
import { defineConfig, globalIgnores } from 'eslint/config'
export default defineConfig([
- globalIgnores(['dist']),
+ globalIgnores(['dist', 'dist-server']),
{
files: ['**/*.{ts,tsx}'],
extends: [
diff --git a/package.json b/package.json
@@ -8,10 +8,11 @@
"dev:api": "tsx watch server/index.ts",
"dev:web": "vite",
"dev:vite": "vite",
- "build": "tsc -b && vite build",
+ "build:server": "tsc -p tsconfig.server.json",
+ "build": "npm run build:server && tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview",
- "start": "tsx server/index.ts",
+ "start": "node dist-server/server/index.js",
"pm2:prod": "npm run build && pm2 start ecosystem.config.cjs --env production"
},
"dependencies": {
diff --git a/server/index.ts b/server/index.ts
@@ -1,6 +1,5 @@
import fs from "node:fs";
import path from "node:path";
-import { fileURLToPath } from "node:url";
import cors from "@fastify/cors";
import fastifyStatic from "@fastify/static";
@@ -14,9 +13,10 @@ import {
} from "./metadata.js";
import { resolveApiPort } from "../config/ports.js";
-const __dirname = path.dirname(fileURLToPath(import.meta.url));
+/** App root — same as PM2 `cwd` / where you run `npm start` (not the compiled file path). */
+const PROJECT_ROOT = process.cwd();
-dotenv.config({ path: path.join(__dirname, "..", ".env") });
+dotenv.config({ path: path.join(PROJECT_ROOT, ".env") });
function resolvePath(p: string): string {
return path.isAbsolute(p) ? p : path.resolve(process.cwd(), p);
@@ -24,7 +24,7 @@ function resolvePath(p: string): string {
const PORT = resolveApiPort(process.env);
/** Resolved path to data/metadata.tsv next to the app (independent of METADATA_TSV env). */
-const BUNDLED_METADATA_TSV = path.join(__dirname, "..", "data", "metadata.tsv");
+const BUNDLED_METADATA_TSV = path.join(PROJECT_ROOT, "data", "metadata.tsv");
/** If METADATA_TSV points to a missing file but the bundled copy exists, use bundled (VPS typo self-heal). */
function resolveEffectiveMetadataTsv(): {
@@ -55,7 +55,7 @@ let METADATA_ENV_REQUESTED: string | null = null;
let METADATA_USED_FALLBACK = false;
function applyMetadataPathsFromEnv() {
- dotenv.config({ path: path.join(__dirname, "..", ".env") });
+ dotenv.config({ path: path.join(PROJECT_ROOT, ".env") });
const m = resolveEffectiveMetadataTsv();
METADATA_TSV = m.path;
METADATA_ENV_REQUESTED = m.envRequested;
@@ -74,7 +74,7 @@ function hintForMetadataNotFound(message: string): string {
}
const IA_ITEM_ID = process.env.IA_ITEM_ID?.trim() || IA_DRAGON_HOARD_ID;
-const distDir = path.join(__dirname, "..", "dist");
+const distDir = path.join(PROJECT_ROOT, "dist");
const distIndexPath = path.join(distDir, "index.html");
const distExists = fs.existsSync(distIndexPath);
diff --git a/tsconfig.server.json b/tsconfig.server.json
@@ -0,0 +1,18 @@
+{
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.server.tsbuildinfo",
+ "target": "ES2023",
+ "lib": ["ES2023"],
+ "module": "NodeNext",
+ "moduleResolution": "NodeNext",
+ "types": ["node"],
+ "outDir": "./dist-server",
+ "rootDir": ".",
+ "skipLibCheck": true,
+ "verbatimModuleSyntax": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "sourceMap": true
+ },
+ "include": ["server/**/*.ts", "config/ports.ts"]
+}