11import * as fs from 'fs' ;
2- import { join } from 'path' ;
2+ import { join , dirname } from 'path' ;
33import * as express from 'express' ;
44import * as bodyParser from 'body-parser' ;
55import * as open from 'open' ;
@@ -189,33 +189,6 @@ const startServerWithState = (app: express.Express, port: number): Promise<void>
189189 } ) ;
190190} ;
191191
192- // 启动主应用
193- const startMainApplication = async ( ) : Promise < void > => {
194- try {
195- console . log ( '[ReactPress] Starting main application...' ) ;
196-
197- // 确保安装服务器完全关闭
198- await safelyCloseServer ( ) ;
199-
200- // 清除安装状态
201- global . isInstalling = false ;
202-
203- // 延迟启动以确保端口释放
204- await new Promise ( resolve => setTimeout ( resolve , 1000 ) ) ;
205-
206- // 动态导入以避免在安装阶段加载 NestJS
207- const { bootstrap } = await import ( './starter' ) ;
208- if ( typeof bootstrap === 'function' ) {
209- await bootstrap ( ) ;
210- } else {
211- throw new Error ( 'Bootstrap function not found' ) ;
212- }
213- } catch ( error ) {
214- console . error ( '[ReactPress] Failed to start main application:' , error ) ;
215- process . exit ( 1 ) ;
216- }
217- } ;
218-
219192// 信号处理
220193const setupSignalHandlers = ( ) => {
221194 const shutdown = async ( signal : string ) => {
@@ -231,6 +204,69 @@ const setupSignalHandlers = () => {
231204 process . on ( 'SIGHUP' , ( ) => shutdown ( 'SIGHUP' ) ) ;
232205} ;
233206
207+ // 主执行函数
208+ const main = async ( ) => {
209+ try {
210+ setupSignalHandlers ( ) ;
211+
212+ // 获取项目根目录路径(考虑npm包场景)
213+ const projectRoot = getProjectRoot ( ) ;
214+ const envPath = join ( projectRoot , '.env' ) ;
215+
216+ if ( fs . existsSync ( envPath ) ) {
217+ console . log ( '[ReactPress] Environment file exists, starting main application' ) ;
218+ await startMainApplication ( ) ;
219+ return ;
220+ }
221+
222+ console . log ( '[ReactPress] Starting installation wizard' ) ;
223+ await runInstallationWizard ( ) ;
224+
225+ } catch ( error ) {
226+ console . error ( '[ReactPress] Fatal error:' , error ) ;
227+ // 确保服务器被正确关闭
228+ await safelyCloseServer ( ) ;
229+ process . exit ( 1 ) ;
230+ }
231+ } ;
232+
233+ // 获取项目根目录路径的函数
234+ const getProjectRoot = ( ) : string => {
235+ // 如果是通过npm包安装的,__dirname会指向node_modules中的路径
236+ // 我们需要找到实际的项目根目录
237+
238+ // 方法1: 检查是否存在package.json(项目根目录标识)
239+ let currentDir = __dirname ;
240+
241+ // 向上查找最多5层目录
242+ for ( let i = 0 ; i < 5 ; i ++ ) {
243+ const packageJsonPath = join ( currentDir , 'package.json' ) ;
244+ if ( fs . existsSync ( packageJsonPath ) ) {
245+ // 检查是否是根package.json(通过name字段判断)
246+ try {
247+ const packageJson = JSON . parse ( fs . readFileSync ( packageJsonPath , 'utf8' ) ) ;
248+ if ( packageJson . name === 'reactpress' ) {
249+ return currentDir ;
250+ }
251+ } catch ( e ) {
252+ // 解析失败,继续向上查找
253+ }
254+ }
255+ currentDir = dirname ( currentDir ) ;
256+ }
257+
258+ // 方法2: 如果找不到根package.json,则使用传统方式(server目录的上一级)
259+ // 这适用于开发环境
260+ const traditionalRoot = join ( __dirname , '../../' ) ;
261+ if ( fs . existsSync ( join ( traditionalRoot , 'package.json' ) ) ) {
262+ return traditionalRoot ;
263+ }
264+
265+ // 方法3: 默认返回当前工作目录
266+ // 这适用于npm包安装场景
267+ return process . cwd ( ) ;
268+ } ;
269+
234270// 安装向导主函数
235271const runInstallationWizard = async ( ) : Promise < void > => {
236272 try {
@@ -293,7 +329,7 @@ const runInstallationWizard = async (): Promise<void> => {
293329 await connection . execute ( 'SELECT 1' ) ;
294330 await connection . end ( ) ;
295331
296- // 创建环境文件
332+ // 创建环境文件到项目根目录
297333 const envContent = `# Database Config
298334DB_HOST=${ db . host || '127.0.0.1' }
299335DB_PORT=${ db . port || 3306 }
@@ -309,7 +345,9 @@ SERVER_SITE_URL=${site.serverUrl || 'http://localhost:3002'}
309345SERVER_PORT=${ site . serverPort || 3002 }
310346SERVER_API_PREFIX=/api` . trim ( ) ;
311347
312- const envPath = join ( __dirname , '../.env' ) ;
348+ // 使用项目根目录路径创建.env文件
349+ const projectRoot = getProjectRoot ( ) ;
350+ const envPath = join ( projectRoot , '.env' ) ;
313351 fs . writeFileSync ( envPath , envContent , 'utf8' ) ;
314352
315353 res . json ( {
@@ -354,28 +392,31 @@ SERVER_API_PREFIX=/api`.trim();
354392 }
355393} ;
356394
357- // 主执行函数
358- const main = async ( ) => {
395+ // 启动主应用
396+ const startMainApplication = async ( ) : Promise < void > => {
359397 try {
360- setupSignalHandlers ( ) ;
398+ console . log ( '[ReactPress] Starting main application...' ) ;
361399
362- const envPath = join ( __dirname , '../.env' ) ;
363- if ( fs . existsSync ( envPath ) ) {
364- console . log ( '[ReactPress] Environment file exists, starting main application' ) ;
365- await startMainApplication ( ) ;
366- return ;
367- }
400+ // 确保安装服务器完全关闭
401+ await safelyCloseServer ( ) ;
368402
369- console . log ( '[ReactPress] Starting installation wizard' ) ;
370- await runInstallationWizard ( ) ;
403+ // 清除安装状态
404+ global . isInstalling = false ;
405+
406+ // 延迟启动以确保端口释放
407+ await new Promise ( resolve => setTimeout ( resolve , 1000 ) ) ;
371408
409+ // 动态导入以避免在安装阶段加载 NestJS
410+ const { bootstrap } = await import ( './starter' ) ;
411+ if ( typeof bootstrap === 'function' ) {
412+ await bootstrap ( ) ;
413+ } else {
414+ throw new Error ( 'Bootstrap function not found' ) ;
415+ }
372416 } catch ( error ) {
373- console . error ( '[ReactPress] Fatal error:' , error ) ;
374- // 确保服务器被正确关闭
375- await safelyCloseServer ( ) ;
417+ console . error ( '[ReactPress] Failed to start main application:' , error ) ;
376418 process . exit ( 1 ) ;
377419 }
378420} ;
379421
380- // 启动应用
381422main ( ) ;
0 commit comments