chore(next): upgrade preview and isolate dev services
This commit is contained in:
1 parent
ac73b9d891
commit
4ca0b747bb
9 files changed
+1651
-1437
No files matched your search
@@ -14,8 +14,8 @@ This guide will help you set up your development environment to start contributi
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- **Node.js (lts)**: You can download it from the [official website](https://nodejs.org/).
|
||||
- **pnpm (latest)**: You can install it by running `npm install -g pnpm`.
|
||||
- **Node.js 24.18 or newer**: You can download it from the [official website](https://nodejs.org/).
|
||||
- **Corepack**: Run `corepack enable` so the repository selects its pinned pnpm version.
|
||||
- **Git**: You can download it from the [official website](https://git-scm.com/).
|
||||
- **Docker or Docker Desktop**: You can download it from the [official website](https://www.docker.com/).
|
||||
- **A GitHub account**: You can create one on the [official website](https://github.com/).
|
||||
@@ -48,7 +48,11 @@ This guide will help you set up your development environment to start contributi
|
||||
|
||||
#### During development
|
||||
|
||||
- `pnpm dev`: Start the development server.
|
||||
- `pnpm dev`: Start Next.js, the task runner, and the WebSocket server as separate development processes.
|
||||
- `pnpm -F nextjs dev`: Start only the Next.js UI when background services are not needed.
|
||||
- `pnpm dev:benchmark`: Run the local authenticated-board benchmark. Set `DEV_BENCHMARK_BOARD_URL` and
|
||||
`DEV_BENCHMARK_STORAGE_STATE`; readiness-only measurements require the explicit `--smoke` flag and are not
|
||||
suitable for performance claims.
|
||||
- `pnpm cli`: Run cli commands.
|
||||
- `pnpm db:migration:sqlite:run`: Run the migrations to create or update the sqlite db file.
|
||||
- `pnpm db:migration:sqlite:generate`: Generate a new migration file for the sqlite db. Also works with `mysql`.
|
||||
@@ -63,6 +67,7 @@ This guide will help you set up your development environment to start contributi
|
||||
- `pnpm typecheck`: Run the typescript type checker.
|
||||
|
||||
#### Building the project
|
||||
|
||||
- `pnpm build`: Build the project for production.
|
||||
- `docker build -t homarr .`: Build a docker image for the project.
|
||||
- `docker run -p 7575:7575 -e SECRET_ENCRYPTION_KEY='your_64_character_hex_string' homarr:latest`: Run the created docker image.
|
||||
- `docker run -p 7575:7575 -e SECRET_ENCRYPTION_KEY='your_64_character_hex_string' homarr:latest`: Run the created docker image.
|
||||
+21
-11
@@ -1,4 +1,6 @@
|
||||
// Importing env files here to validate on build
|
||||
import path from "node:path";
|
||||
|
||||
import "@homarr/auth/env";
|
||||
import "@homarr/core/infrastructure/db/env";
|
||||
import "@homarr/common/env";
|
||||
@@ -13,7 +15,21 @@ const withNextIntl = createNextIntlPlugin({
|
||||
requestConfig: "../../packages/translation/src/request.ts",
|
||||
});
|
||||
|
||||
const getDevelopmentServiceAliases = () => {
|
||||
if (process.env.NODE_ENV !== "development") {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
"@homarr/tasks": "./src/instrumentation-noop.ts",
|
||||
"@homarr/websocket": "./src/instrumentation-noop.ts",
|
||||
};
|
||||
};
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
// Next previews otherwise create agent instruction files in the application
|
||||
// directory during development.
|
||||
agentRules: false,
|
||||
env: {
|
||||
HOMARR_VERSION: process.env.HOMARR_VERSION ?? "unknown",
|
||||
},
|
||||
@@ -30,19 +46,13 @@ const nextConfig: NextConfig = {
|
||||
serverExternalPackages: ["dockerode", "isomorphic-dompurify", "jsdom", "better-sqlite3"],
|
||||
experimental: {
|
||||
optimizePackageImports: ["@mantine/core", "@mantine/hooks", "@tabler/icons-react"],
|
||||
turbopackFileSystemCacheForDev: true,
|
||||
webpackMemoryOptimizations: true,
|
||||
useTypeScriptCli: true,
|
||||
},
|
||||
turbopack: {
|
||||
// ponytail: known Turbopack NFT warning from path.join(process.cwd(), …) in
|
||||
// src/app/api/backup/{route,shared}.ts. No working placement in 16.2.x
|
||||
// (see vercel/next.js#95125). Suppress until upstream fix lands.
|
||||
ignoreIssue: [
|
||||
{
|
||||
path: "**/*",
|
||||
title: "Encountered unexpected file in NFT list",
|
||||
},
|
||||
],
|
||||
root: path.resolve(import.meta.dirname, "../.."),
|
||||
// Development runs tasks and WebSocket as separate processes. These aliases
|
||||
// keep their production-only instrumentation imports out of the dev graph.
|
||||
resolveAlias: getDevelopmentServiceAliases(),
|
||||
},
|
||||
transpilePackages: ["@homarr/ui", "@homarr/notifications", "@homarr/modals", "@homarr/spotlight", "@homarr/widgets"],
|
||||
images: {
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
// Development runs background services as separate processes. The aliases in
|
||||
// next.config.ts keep production-only instrumentation imports out of the graph.
|
||||
export const instrumentationNoop = true;
|
||||
@@ -0,0 +1,55 @@
|
||||
// @vitest-environment node
|
||||
|
||||
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
|
||||
|
||||
const registerAsync = async (nodeEnv: string, nextRuntime: string) => {
|
||||
const tasksStarted = vi.fn();
|
||||
const websocketStarted = vi.fn();
|
||||
vi.stubEnv("NODE_ENV", nodeEnv);
|
||||
vi.stubEnv("NEXT_RUNTIME", nextRuntime);
|
||||
vi.doMock("@homarr/tasks", () => {
|
||||
tasksStarted();
|
||||
return {};
|
||||
});
|
||||
vi.doMock("@homarr/websocket", () => {
|
||||
websocketStarted();
|
||||
return {};
|
||||
});
|
||||
|
||||
const { register } = await import("./instrumentation");
|
||||
await register();
|
||||
return { tasksStarted, websocketStarted };
|
||||
};
|
||||
|
||||
describe("Next instrumentation", () => {
|
||||
beforeEach(() => {
|
||||
vi.resetModules();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.doUnmock("@homarr/tasks");
|
||||
vi.doUnmock("@homarr/websocket");
|
||||
vi.unstubAllEnvs();
|
||||
});
|
||||
|
||||
test("embeds background services in the production Node runtime", async () => {
|
||||
const { tasksStarted, websocketStarted } = await registerAsync("production", "nodejs");
|
||||
|
||||
expect(tasksStarted).toHaveBeenCalledOnce();
|
||||
expect(websocketStarted).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
test("does not embed background services in the development server", async () => {
|
||||
const { tasksStarted, websocketStarted } = await registerAsync("development", "nodejs");
|
||||
|
||||
expect(tasksStarted).not.toHaveBeenCalled();
|
||||
expect(websocketStarted).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test("does not embed Node services in the edge runtime", async () => {
|
||||
const { tasksStarted, websocketStarted } = await registerAsync("production", "edge");
|
||||
|
||||
expect(tasksStarted).not.toHaveBeenCalled();
|
||||
expect(websocketStarted).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -1,6 +1,7 @@
|
||||
export async function register() {
|
||||
if (process.env.NEXT_RUNTIME === "nodejs") {
|
||||
await import("@homarr/tasks");
|
||||
await import("@homarr/websocket");
|
||||
}
|
||||
if (process.env.NEXT_RUNTIME !== "nodejs") return;
|
||||
if (process.env.NODE_ENV !== "production") return;
|
||||
|
||||
await import("@homarr/tasks");
|
||||
await import("@homarr/websocket");
|
||||
}
|
||||
+3
-2
@@ -19,7 +19,8 @@
|
||||
"db:migration:sqlite:run": "pnpm -F db migration:sqlite:run",
|
||||
"db:push": "pnpm -F db push:sqlite",
|
||||
"db:studio": "pnpm -F db studio",
|
||||
"dev": "pnpm -F nextjs dev",
|
||||
"dev": "concurrently \"pnpm -F nextjs dev\" \"pnpm -F @homarr/tasks dev\" \"pnpm -F @homarr/websocket dev\"",
|
||||
"dev:benchmark": "node --experimental-strip-types scripts/benchmarks/dev-board.mts",
|
||||
"dev:docs": "pnpm -F @homarr/docs dev",
|
||||
"docker:dev": "docker compose -f ./development/development.docker-compose.yml up",
|
||||
"format": "turbo format --continue -- --check",
|
||||
@@ -30,7 +31,7 @@
|
||||
"release": "semantic-release",
|
||||
"scripts:update-bug-report-template": "tsx ./scripts/update-bug-report-template.mts",
|
||||
"scripts:update-readme-integrations": "tsx ./scripts/update-integration-list.mts",
|
||||
"start": "concurrently \"pnpm with-env node apps/tasks/tasks.cjs\" \"pnpm with-env node apps/websocket/wssServer.cjs\" \"pnpm -F nextjs start\"",
|
||||
"start": "pnpm -F nextjs start",
|
||||
"test": "cross-env NODE_ENV=development CI=true vitest run --exclude e2e --coverage.enabled ",
|
||||
"test:e2e": "cross-env NODE_ENV=development CI=true vitest e2e",
|
||||
"test:ui": "cross-env NODE_ENV=development CI=true vitest --exclude e2e --ui --coverage.enabled",
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
"tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json"
|
||||
},
|
||||
"include": ["."],
|
||||
"exclude": ["node_modules"]
|
||||
"exclude": ["node_modules", "migrations/*/migrate.cjs"]
|
||||
}
|
||||
Generated
+1551
-1413
File diff suppressed because it is too large.
Load diff
+3
-2
@@ -146,7 +146,7 @@ catalog:
|
||||
mcp-handler: ^1.1.0
|
||||
maria2: ^0.4.1
|
||||
mysql2: 3.22.6
|
||||
next: 16.2.10
|
||||
next: 16.3.0-preview.9
|
||||
next-auth: 5.0.0-beta.31
|
||||
next-intl: 4.13.1
|
||||
node-loader: ^2.1.0
|
||||
@@ -177,7 +177,7 @@ catalog:
|
||||
tsdav: ^2.3.0
|
||||
tsx: 4.20.4
|
||||
turbo: ^2.10.4
|
||||
typescript: "npm:@typescript/typescript6@^6.0.2"
|
||||
typescript: 7.0.2
|
||||
vite: ^8.1.4
|
||||
undici: 7.28.0
|
||||
use-deep-compare-effect: ^1.8.1
|
||||
@@ -201,6 +201,7 @@ minimumReleaseAge: 4320
|
||||
minimumReleaseAgeExclude:
|
||||
- next
|
||||
- "@next/*"
|
||||
- "typescript@7.0.2"
|
||||
- "@immich/sdk@3.0.0"
|
||||
# Renovate security update: turbo@2.9.14
|
||||
- turbo@2.9.14
|
||||
|
||||
Reference in new issue
Block a user