chore: upgrade to Node.js 25.2.1

- Update .nvmrc to Node 25
- Update all Dockerfiles to use node:25-alpine
- Update package.json engines to >=25.0.0
- Update CI/CD workflows for Node 25
- Update @types/node in packages
- Fix ESLint config to use ES module syntax
- Update OpenTelemetry imports for compatibility

All services tested and working with Node.js 25.2.1
This commit is contained in:
Ho Ngoc Hai
2026-01-07 17:15:25 +07:00
parent 9c74b86837
commit 63f5b10fe2
21 changed files with 1226 additions and 1504 deletions

View File

@@ -41,7 +41,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
node-version: '25'
cache: 'pnpm'
- name: Install dependencies

View File

@@ -24,7 +24,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
node-version: '25'
cache: 'pnpm'
- name: Install dependencies

View File

@@ -24,7 +24,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
node-version: '25'
cache: 'pnpm'
- name: Install dependencies

View File

@@ -21,7 +21,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
node-version: '25'
cache: 'pnpm'
- name: Install dependencies

View File

@@ -20,7 +20,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
node-version: '25'
cache: 'pnpm'
- name: Install dependencies

View File

@@ -18,7 +18,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
node-version: '25'
cache: 'pnpm'
- name: Install dependencies

1
.nvmrc Normal file
View File

@@ -0,0 +1 @@
25

View File

@@ -1,4 +1,4 @@
FROM node:20-alpine AS base
FROM node:25-alpine AS base
RUN apk add --no-cache libc6-compat
WORKDIR /app

View File

@@ -20,7 +20,7 @@
"axios": "^1.6.5",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"lucide-react": "^0.344.0",
"lucide-react": "^0.562.0",
"next": "^14.1.0",
"next-intl": "^4.7.0",
"react": "^18.2.0",
@@ -28,7 +28,7 @@
"react-hook-form": "^7.49.3",
"recharts": "^2.10.3",
"zod": "^3.22.4",
"zustand": "^4.4.7"
"zustand": "^5.0.9"
},
"devDependencies": {
"@goodgo/eslint-config": "workspace:*",

View File

@@ -1,4 +1,4 @@
FROM node:20-alpine AS base
FROM node:25-alpine AS base
RUN apk add --no-cache libc6-compat
WORKDIR /app

View File

@@ -31,7 +31,7 @@
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"framer-motion": "^12.23.26",
"lucide-react": "^0.344.0",
"lucide-react": "^0.562.0",
"next": "^14.1.0",
"next-intl": "^4.7.0",
"react": "^18.2.0",
@@ -41,7 +41,7 @@
"react-hook-form": "^7.49.3",
"react-stately": "^3.43.0",
"zod": "^3.22.4",
"zustand": "^4.4.7"
"zustand": "^5.0.9"
},
"devDependencies": {
"@axe-core/react": "^4.11.0",

View File

@@ -19,15 +19,15 @@
"typecheck": "pnpm -r typecheck"
},
"devDependencies": {
"@types/node": "^20.11.0",
"typescript": "^5.3.3",
"prettier": "^3.2.4",
"@types/node": "^25.0.0",
"eslint": "^8.56.0",
"turbo": "^1.11.2"
"prettier": "^3.7.4",
"turbo": "^1.11.2",
"typescript": "^5.9.3"
},
"engines": {
"node": ">=20.0.0",
"node": ">=25.0.0",
"pnpm": ">=8.0.0"
},
"packageManager": "pnpm@8.15.0"
}
}

View File

@@ -11,14 +11,14 @@
},
"dependencies": {
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/sdk-node": "^0.57.0",
"@opentelemetry/instrumentation": "^0.57.0",
"@opentelemetry/instrumentation-http": "^0.57.0",
"@opentelemetry/auto-instrumentations-node": "^0.67.3",
"@opentelemetry/exporter-trace-otlp-http": "^0.208.0",
"@opentelemetry/instrumentation": "^0.208.0",
"@opentelemetry/instrumentation-express": "^0.57.0",
"@opentelemetry/auto-instrumentations-node": "^0.52.0",
"@opentelemetry/resources": "^1.29.0",
"@opentelemetry/semantic-conventions": "^1.29.0",
"@opentelemetry/exporter-jaeger": "^1.28.0"
"@opentelemetry/instrumentation-http": "^0.208.0",
"@opentelemetry/resources": "^2.2.0",
"@opentelemetry/sdk-node": "^0.208.0",
"@opentelemetry/semantic-conventions": "^1.38.0"
},
"devDependencies": {
"@goodgo/tsconfig": "workspace:*",

View File

@@ -1,8 +1,6 @@
import { NodeSDK } from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { JaegerExporter } from '@opentelemetry/exporter-jaeger';
import { Resource } from '@opentelemetry/resources';
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
/**
* EN: Configuration interface for distributed tracing setup
@@ -11,15 +9,15 @@ import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'
export interface TracingConfig {
/** EN: Name of the service for trace identification / VI: Tên service để xác định trace */
serviceName: string;
/** EN: Jaeger collector endpoint URL / VI: URL endpoint Jaeger collector */
jaegerEndpoint?: string;
/** EN: OTLP collector endpoint URL (default: http://localhost:4318/v1/traces) / VI: URL endpoint OTLP collector (mặc định: http://localhost:4318/v1/traces) */
otlpEndpoint?: string;
/** EN: Enable/disable tracing (default: true) / VI: Bật/tắt tracing (mặc định: true) */
enabled?: boolean;
}
/**
* EN: Initialize OpenTelemetry distributed tracing with Jaeger exporter
* VI: Khởi tạo OpenTelemetry distributed tracing với Jaeger exporter
* EN: Initialize OpenTelemetry distributed tracing with OTLP exporter
* VI: Khởi tạo OpenTelemetry distributed tracing với OTLP exporter
*
* @param config - Tracing configuration / Cấu hình tracing
* @returns NodeSDK instance or null if tracing is disabled / Instance NodeSDK hoặc null nếu tracing bị tắt
@@ -31,21 +29,17 @@ export const initTracing = (config: TracingConfig): NodeSDK | null => {
return null;
}
// EN: Create Jaeger exporter if endpoint is provided
// VI: Tạo Jaeger exporter nếu endpoint được cung cấp
const jaegerExporter = config.jaegerEndpoint
? new JaegerExporter({
endpoint: config.jaegerEndpoint,
})
: undefined;
// EN: Create OTLP exporter with configured endpoint
// VI: Tạo OTLP exporter với endpoint được cấu hình
const traceExporter = new OTLPTraceExporter({
url: config.otlpEndpoint || 'http://localhost:4318/v1/traces',
});
// EN: Initialize OpenTelemetry NodeSDK with auto-instrumentations
// VI: Khởi tạo OpenTelemetry NodeSDK với auto-instrumentations
const sdk = new NodeSDK({
resource: new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: config.serviceName,
}),
traceExporter: jaegerExporter,
serviceName: config.serviceName,
traceExporter,
instrumentations: [getNodeAutoInstrumentations()],
});

2628
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@
# EN: Base stage with security updates
# VI: Base stage với security updates
FROM node:20-alpine AS base
FROM node:25-alpine AS base
# EN: Install security updates and required packages
# VI: Cài đặt security updates và packages cần thiết

View File

@@ -21,7 +21,7 @@ import { correlationMiddleware } from './middlewares/correlation.middleware';
if (process.env.TRACING_ENABLED === 'true') {
initTracing({
serviceName: process.env.SERVICE_NAME || 'microservice',
jaegerEndpoint: process.env.JAEGER_ENDPOINT,
otlpEndpoint: process.env.OTLP_ENDPOINT,
enabled: true,
});
}

View File

@@ -1,4 +1,9 @@
module.exports = {
ignorePatterns: ['.eslintrc.js'],
extends: ['@goodgo/eslint-config'],
root: true,
parserOptions: {
tsconfigRootDir: __dirname,
project: './tsconfig.json',
},
};

View File

@@ -3,9 +3,9 @@
# EN: Base stage with security updates
# VI: Base stage với security updates
# EN: Base stage with security updates (Node 22)
# VI: Base stage với security updates (Node 22)
FROM node:22-alpine AS base
# EN: Base stage with security updates (Node 25)
# VI: Base stage với security updates (Node 25)
FROM node:25-alpine AS base
# EN: Install security updates and required packages
# VI: Cài đặt security updates và packages cần thiết

View File

@@ -56,7 +56,7 @@
"speakeasy": "^2.0.0",
"swagger-jsdoc": "^6.2.8",
"swagger-ui-express": "^5.0.1",
"uuid": "^9.0.1",
"uuid": "^13.0.0",
"zod": "^3.22.4"
},
"devDependencies": {
@@ -72,7 +72,7 @@
"@types/ioredis": "^5.0.0",
"@types/jest": "^29.5.11",
"@types/jsonwebtoken": "^9.0.5",
"@types/node": "^20.11.0",
"@types/node": "^22.19.3",
"@types/node-cache": "^4.2.5",
"@types/opossum": "^8.1.9",
"@types/passport": "^1.0.16",

View File

@@ -19,7 +19,7 @@ import { createRouter } from './routes';
if (process.env.TRACING_ENABLED === 'true') {
initTracing({
serviceName: process.env.SERVICE_NAME || 'microservice',
jaegerEndpoint: process.env.JAEGER_ENDPOINT,
otlpEndpoint: process.env.OTLP_ENDPOINT,
enabled: true,
});
}