Skip to content

Commit 09e3d5f

Browse files
committed
refactor: update env config
1 parent cf8404f commit 09e3d5f

File tree

8 files changed

+341
-22
lines changed

8 files changed

+341
-22
lines changed

.env

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,4 @@ DB_DATABASE=reactpress
99
CLIENT_SITE_URL=http://localhost:3001
1010

1111
# Server Config
12-
SERVER_SITE_URL=http://localhost:3002
13-
SERVER_PORT=3002
14-
SERVER_API_PREFIX=/api
12+
SERVER_SITE_URL=http://localhost:3002

client/bin/reactpress-client.js

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* ReactPress Client CLI Entry Point
5+
* This script allows starting the ReactPress client via npx
6+
*/
7+
8+
const path = require('path');
9+
const fs = require('fs');
10+
const { spawn, spawnSync } = require('child_process');
11+
const url = require('url');
12+
13+
// Get command line arguments
14+
const args = process.argv.slice(2);
15+
const usePM2 = args.includes('--pm2');
16+
const showHelp = args.includes('--help') || args.includes('-h');
17+
18+
// Show help if requested
19+
if (showHelp) {
20+
console.log(`
21+
ReactPress Client - Next.js-based frontend for ReactPress CMS
22+
23+
Usage:
24+
npx @fecommunity/reactpress-client [options]
25+
26+
Options:
27+
--pm2 Start client with PM2 process manager
28+
--help, -h Show this help message
29+
30+
Examples:
31+
npx @fecommunity/reactpress-client # Start client in development mode
32+
npx @fecommunity/reactpress-client --pm2 # Start client with PM2
33+
npx @fecommunity/reactpress-client --help # Show this help message
34+
`);
35+
process.exit(0);
36+
}
37+
38+
// Get the directory where this script is located
39+
const binDir = __dirname;
40+
const clientDir = path.join(binDir, '..');
41+
42+
// Change to the client directory
43+
process.chdir(clientDir);
44+
45+
// Try to load configuration
46+
let port = 3001;
47+
let clientSiteUrl = 'http://localhost:3001';
48+
49+
try {
50+
const { config } = require('@fecommunity/reactpress-config');
51+
52+
// Extract port from CLIENT_SITE_URL or use CLIENT_PORT
53+
if (config.CLIENT_SITE_URL) {
54+
try {
55+
const parsedUrl = url.parse(config.CLIENT_SITE_URL);
56+
if (parsedUrl.port) {
57+
port = parseInt(parsedUrl.port, 10);
58+
} else if (parsedUrl.protocol === 'https:') {
59+
port = 443;
60+
} else {
61+
port = 80;
62+
}
63+
clientSiteUrl = config.CLIENT_SITE_URL;
64+
} catch (err) {
65+
console.warn('[ReactPress Client] Failed to parse CLIENT_SITE_URL, using default port 3001');
66+
}
67+
} else if (config.CLIENT_PORT) {
68+
port = parseInt(config.CLIENT_PORT, 10);
69+
}
70+
} catch (err) {
71+
console.warn('[ReactPress Client] Failed to load configuration, using default settings');
72+
}
73+
74+
// Function to check if PM2 is installed
75+
function isPM2Installed() {
76+
try {
77+
require.resolve('pm2');
78+
return true;
79+
} catch (e) {
80+
// Check if PM2 is installed globally
81+
try {
82+
spawnSync('pm2', ['--version'], { stdio: 'ignore' });
83+
return true;
84+
} catch (e) {
85+
return false;
86+
}
87+
}
88+
}
89+
90+
// Function to install PM2
91+
function installPM2() {
92+
console.log('[ReactPress Client] Installing PM2...');
93+
const installResult = spawnSync('npm', ['install', 'pm2', '--no-save'], {
94+
stdio: 'inherit',
95+
cwd: clientDir
96+
});
97+
98+
if (installResult.status !== 0) {
99+
console.error('[ReactPress Client] Failed to install PM2');
100+
return false;
101+
}
102+
103+
return true;
104+
}
105+
106+
// Function to start with PM2
107+
function startWithPM2() {
108+
// Check if PM2 is installed
109+
if (!isPM2Installed()) {
110+
// Try to install PM2
111+
if (!installPM2()) {
112+
console.error('[ReactPress Client] Cannot start with PM2');
113+
process.exit(1);
114+
}
115+
}
116+
117+
// Check if the client is built
118+
const nextDir = path.join(clientDir, '.next');
119+
if (!fs.existsSync(nextDir)) {
120+
console.log('[ReactPress Client] Client not built yet. Building...');
121+
122+
// Try to build the client
123+
const buildResult = spawnSync('npm', ['run', 'build'], {
124+
stdio: 'inherit',
125+
cwd: clientDir
126+
});
127+
128+
if (buildResult.status !== 0) {
129+
console.error('[ReactPress Client] Failed to build client');
130+
process.exit(1);
131+
}
132+
}
133+
134+
console.log('[ReactPress Client] Starting with PM2...');
135+
136+
// Use PM2 to start the Next.js production server
137+
let pm2Command = 'pm2';
138+
try {
139+
// Try to resolve PM2 path
140+
pm2Command = path.join(clientDir, 'node_modules', '.bin', 'pm2');
141+
if (!fs.existsSync(pm2Command)) {
142+
pm2Command = 'pm2';
143+
}
144+
} catch (e) {
145+
pm2Command = 'pm2';
146+
}
147+
148+
// Start with PM2 using direct command
149+
const pm2 = spawn(pm2Command, ['start', 'npm', '--name', 'reactpress-client', '--', 'run', 'start'], {
150+
stdio: 'inherit',
151+
cwd: clientDir
152+
});
153+
154+
pm2.on('close', (code) => {
155+
console.log(`[ReactPress Client] PM2 process exited with code ${code}`);
156+
process.exit(code);
157+
});
158+
159+
pm2.on('error', (error) => {
160+
console.error('[ReactPress Client] Failed to start with PM2:', error);
161+
process.exit(1);
162+
});
163+
}
164+
165+
// Function to start with regular Node.js
166+
function startWithNode() {
167+
// Check if we're in development or production mode
168+
const isDev = process.env.NODE_ENV !== 'production';
169+
170+
if (isDev) {
171+
// In development mode, start Next.js dev server
172+
console.log('[ReactPress Client] Starting Next.js development server...');
173+
174+
// Use Next.js CLI directly
175+
const nextDev = spawn('npx', ['next', 'dev', '-p', port.toString()], {
176+
stdio: 'inherit',
177+
cwd: clientDir
178+
});
179+
180+
nextDev.on('close', (code) => {
181+
console.log(`[ReactPress Client] Next.js dev server exited with code ${code}`);
182+
process.exit(code);
183+
});
184+
185+
nextDev.on('error', (error) => {
186+
console.error('[ReactPress Client] Failed to start Next.js dev server:', error);
187+
process.exit(1);
188+
});
189+
} else {
190+
// In production mode, check if the app is built and start it
191+
const nextDir = path.join(clientDir, '.next');
192+
193+
if (!fs.existsSync(nextDir)) {
194+
console.log('[ReactPress Client] Client not built yet. Building...');
195+
196+
// Try to build the client
197+
const buildResult = spawnSync('npm', ['run', 'build'], {
198+
stdio: 'inherit',
199+
cwd: clientDir
200+
});
201+
202+
if (buildResult.status !== 0) {
203+
console.error('[ReactPress Client] Failed to build client');
204+
process.exit(1);
205+
}
206+
}
207+
208+
console.log('[ReactPress Client] Starting Next.js production server...');
209+
210+
// Start Next.js production server
211+
const nextStart = spawn('npx', ['next', 'start', '-p', port.toString()], {
212+
stdio: 'inherit',
213+
cwd: clientDir
214+
});
215+
216+
nextStart.on('close', (code) => {
217+
console.log(`[ReactPress Client] Next.js production server exited with code ${code}`);
218+
process.exit(code);
219+
});
220+
221+
nextStart.on('error', (error) => {
222+
console.error('[ReactPress Client] Failed to start Next.js production server:', error);
223+
process.exit(1);
224+
});
225+
}
226+
}
227+
228+
console.log(`[ReactPress Client] Starting client on port ${port}...`);
229+
230+
// Main execution
231+
if (usePM2) {
232+
startWithPM2();
233+
} else {
234+
startWithNode();
235+
}
236+
237+
// Try to automatically open browser after a short delay (only in dev mode and not with PM2)
238+
if (!usePM2 && process.env.NODE_ENV !== 'production') {
239+
setTimeout(() => {
240+
try {
241+
require('open')(clientSiteUrl);
242+
} catch (err) {
243+
console.warn('[ReactPress Client] Failed to open browser automatically');
244+
}
245+
}, 3000);
246+
}

client/package.json

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
{
22
"name": "@fecommunity/reactpress-client",
3-
"version": "1.0.1-beta.9",
3+
"version": "1.0.0-beta.3",
4+
"bin": {
5+
"reactpress-client": "./bin/reactpress-client.js"
6+
},
7+
"files": [
8+
".next/**/*",
9+
"bin/**/*",
10+
"pages/**/*",
11+
"public/**/*",
12+
"src/**/*",
13+
"types/**/*",
14+
"next.config.js",
15+
"next-sitemap.js",
16+
"server.js",
17+
"tsconfig.json"
18+
],
419
"scripts": {
520
"prebuild": "rimraf .next",
621
"build": "next build",

client/public/sitemap.xml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
3-
<url><loc>http://localhost:3001</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2025-09-20T04:45:06.288Z</lastmod></url>
4-
<url><loc>http://localhost:3001/archives</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2025-09-20T04:45:06.288Z</lastmod></url>
5-
<url><loc>http://localhost:3001/knowledge</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2025-09-20T04:45:06.288Z</lastmod></url>
6-
<url><loc>http://localhost:3001/login</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2025-09-20T04:45:06.288Z</lastmod></url>
7-
<url><loc>http://localhost:3001/nav</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2025-09-20T04:45:06.288Z</lastmod></url>
8-
<url><loc>http://localhost:3001/rss</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2025-09-20T04:45:06.288Z</lastmod></url>
3+
<url><loc>http://localhost:3001</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2025-09-20T05:25:49.206Z</lastmod></url>
4+
<url><loc>http://localhost:3001/archives</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2025-09-20T05:25:49.206Z</lastmod></url>
5+
<url><loc>http://localhost:3001/knowledge</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2025-09-20T05:25:49.206Z</lastmod></url>
6+
<url><loc>http://localhost:3001/login</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2025-09-20T05:25:49.206Z</lastmod></url>
7+
<url><loc>http://localhost:3001/nav</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2025-09-20T05:25:49.206Z</lastmod></url>
8+
<url><loc>http://localhost:3001/rss</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2025-09-20T05:25:49.206Z</lastmod></url>
99
</urlset>

client/server.js

Lines changed: 69 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,74 @@
11
const { config } = require('@fecommunity/reactpress-config');
22
const cli = require('next/dist/cli/next-dev');
3+
const { spawn } = require('child_process');
34

4-
const port = config.CLIENT_PORT || 3001;
5+
// Extract port from CLIENT_SITE_URL or default to 3001
6+
let port = 3001;
7+
if (config.CLIENT_SITE_URL) {
8+
try {
9+
const url = require('url');
10+
const parsedUrl = url.parse(config.CLIENT_SITE_URL);
11+
if (parsedUrl.port) {
12+
port = parseInt(parsedUrl.port, 10);
13+
} else if (parsedUrl.protocol === 'https:') {
14+
port = 443;
15+
} else {
16+
port = 80;
17+
}
18+
} catch (err) {
19+
console.warn('[ReactPress] Failed to parse CLIENT_SITE_URL, using default port 3001');
20+
}
21+
}
522

23+
// Get command line arguments
24+
const args = process.argv.slice(2);
25+
const usePM2 = args.includes('--pm2');
626

7-
try {
8-
cli.nextDev(['-p', port]);
9-
console.log(`[ReactPress] 客户端已启动,端口:${port}`);
10-
// 自动打开
11-
require('open')(`http://localhost:${port}`);
12-
} catch (err) {
13-
console.log(`[ReactPress] 客户端启动失败!${err.message || err}`);
14-
}
27+
if (usePM2) {
28+
// Check if PM2 is installed
29+
try {
30+
require.resolve('pm2');
31+
} catch (e) {
32+
// Check if PM2 is installed globally
33+
try {
34+
const { spawnSync } = require('child_process');
35+
spawnSync('pm2', ['--version'], { stdio: 'ignore' });
36+
} catch (e) {
37+
console.log('[ReactPress] PM2 not found. Installing PM2...');
38+
const { spawnSync } = require('child_process');
39+
const installResult = spawnSync('npm', ['install', 'pm2', '--no-save'], {
40+
stdio: 'inherit'
41+
});
42+
43+
if (installResult.status !== 0) {
44+
console.error('[ReactPress] Failed to install PM2');
45+
process.exit(1);
46+
}
47+
}
48+
}
49+
50+
// Use PM2 to start the Next.js development server
51+
console.log('[ReactPress] Starting client with PM2...');
52+
const pm2 = spawn('pm2', ['start', 'npm', '--name', 'reactpress-client', '--', 'run', 'dev'], {
53+
stdio: 'inherit'
54+
});
55+
56+
pm2.on('close', (code) => {
57+
console.log(`[ReactPress] PM2 process exited with code ${code}`);
58+
process.exit(code);
59+
});
60+
61+
pm2.on('error', (error) => {
62+
console.error('[ReactPress] Failed to start with PM2:', error);
63+
process.exit(1);
64+
});
65+
} else {
66+
try {
67+
cli.nextDev(['-p', port.toString());
68+
console.log(`[ReactPress] 客户端已启动,端口:${port}`);
69+
// 自动打开
70+
require('open')(`http://localhost:${port}`);
71+
} catch (err) {
72+
console.log(`[ReactPress] 客户端启动失败!${err.message || err}`);
73+
}
74+
}

config/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@fecommunity/reactpress-config",
3-
"version": "1.0.0-beta.19",
3+
"version": "1.0.0-beta.22",
44
"description": "ReactPress Configuration - Environment and i18n configuration for ReactPress",
55
"author": "fecommunity",
66
"main": "./lib/index.js",

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "reactpress",
2+
"name": "@fecommunity/reactpress",
33
"author": "fecommunity",
44
"version": "1.11.0",
55
"bin": {

0 commit comments

Comments
 (0)