1+ const http = require ( 'http' ) ;
2+ const fs = require ( 'fs' ) ;
3+ const path = require ( 'path' ) ;
4+ const url = require ( 'url' ) ;
5+
6+ const PORT = 3003 ;
7+ const BUILD_DIR = path . join ( __dirname , 'build' ) ;
8+ const BASE_URL = '/flywave.gl/' ; // 与 docusaurus.config.ts 中的 baseUrl 保持一致
9+
10+ // MIME types
11+ const MIME_TYPES = {
12+ '.html' : 'text/html' ,
13+ '.css' : 'text/css' ,
14+ '.js' : 'text/javascript' ,
15+ '.json' : 'application/json' ,
16+ '.png' : 'image/png' ,
17+ '.jpg' : 'image/jpeg' ,
18+ '.gif' : 'image/gif' ,
19+ '.svg' : 'image/svg+xml' ,
20+ '.ico' : 'image/x-icon' ,
21+ '.webp' : 'image/webp' ,
22+ '.woff' : 'font/woff' ,
23+ '.woff2' : 'font/woff2' ,
24+ '.ttf' : 'font/ttf' ,
25+ '.map' : 'application/json'
26+ } ;
27+
28+ // 处理请求
29+ function handleRequest ( req , res ) {
30+ console . log ( `${ req . method } ${ req . url } ` ) ;
31+
32+ // 解析URL
33+ const parsedUrl = url . parse ( req . url ) ;
34+ let pathname = parsedUrl . pathname ;
35+
36+ // 处理 baseUrl 前缀
37+ if ( pathname . startsWith ( BASE_URL ) ) {
38+ pathname = pathname . substring ( BASE_URL . length - 1 ) ; // 保留前导斜杠
39+ }
40+
41+ let filePath = path . join ( BUILD_DIR , pathname ) ;
42+
43+ // 默认页面
44+ if ( pathname === '/' || pathname === '' ) {
45+ filePath = path . join ( BUILD_DIR , 'index.html' ) ;
46+ }
47+
48+ // 获取文件扩展名
49+ const extname = path . extname ( filePath ) . toLowerCase ( ) ;
50+
51+ // 检查文件是否存在
52+ fs . access ( filePath , fs . constants . F_OK , ( err ) => {
53+ if ( err ) {
54+ // 文件不存在,尝试添加.html后缀
55+ if ( extname === '' ) {
56+ const htmlPath = filePath + '.html' ;
57+ fs . access ( htmlPath , fs . constants . F_OK , ( err ) => {
58+ if ( err ) {
59+ serve404 ( res ) ;
60+ } else {
61+ serveFile ( res , htmlPath , '.html' ) ;
62+ }
63+ } ) ;
64+ } else {
65+ serve404 ( res ) ;
66+ }
67+ } else {
68+ // 检查是否是目录
69+ fs . stat ( filePath , ( err , stats ) => {
70+ if ( err ) {
71+ serve404 ( res ) ;
72+ } else if ( stats . isDirectory ( ) ) {
73+ // 如果是目录,尝试提供index.html
74+ const indexPath = path . join ( filePath , 'index.html' ) ;
75+ fs . access ( indexPath , fs . constants . F_OK , ( err ) => {
76+ if ( err ) {
77+ serve404 ( res ) ;
78+ } else {
79+ serveFile ( res , indexPath , '.html' ) ;
80+ }
81+ } ) ;
82+ } else {
83+ serveFile ( res , filePath , extname ) ;
84+ }
85+ } ) ;
86+ }
87+ } ) ;
88+ }
89+
90+ // 提供文件
91+ function serveFile ( res , filePath , extname ) {
92+ const contentType = MIME_TYPES [ extname ] || 'application/octet-stream' ;
93+
94+ fs . readFile ( filePath , ( err , content ) => {
95+ if ( err ) {
96+ if ( err . code === 'ENOENT' ) {
97+ serve404 ( res ) ;
98+ } else {
99+ res . writeHead ( 500 ) ;
100+ res . end ( `Server Error: ${ err . code } ` ) ;
101+ }
102+ } else {
103+ res . writeHead ( 200 , { 'Content-Type' : contentType } ) ;
104+ res . end ( content , 'utf-8' ) ;
105+ }
106+ } ) ;
107+ }
108+
109+ // 404页面
110+ function serve404 ( res ) {
111+ const filePath = path . join ( BUILD_DIR , '404.html' ) ;
112+ fs . access ( filePath , fs . constants . F_OK , ( err ) => {
113+ if ( err ) {
114+ // 如果没有404.html文件,提供简单404响应
115+ res . writeHead ( 404 , { 'Content-Type' : 'text/html' } ) ;
116+ res . end ( '<h1>404 Not Found</h1><p>The requested URL was not found on this server.</p>' ) ;
117+ } else {
118+ serveFile ( res , filePath , '.html' ) ;
119+ }
120+ } ) ;
121+ }
122+
123+ // 创建服务器
124+ const server = http . createServer ( handleRequest ) ;
125+
126+ server . listen ( PORT , ( ) => {
127+ console . log ( `========================================` ) ;
128+ console . log ( `Documentation test server is running!` ) ;
129+ console . log ( `Local: http://localhost:${ PORT } ${ BASE_URL } ` ) ;
130+ console . log ( `Build directory: ${ BUILD_DIR } ` ) ;
131+ console . log ( `Base URL: ${ BASE_URL } ` ) ;
132+ console . log ( `Press Ctrl+C to stop the server` ) ;
133+ console . log ( `========================================` ) ;
134+ } ) ;
135+
136+ // 优雅关闭
137+ process . on ( 'SIGINT' , ( ) => {
138+ console . log ( '\nShutting down server...' ) ;
139+ server . close ( ( ) => {
140+ console . log ( 'Server closed.' ) ;
141+ process . exit ( 0 ) ;
142+ } ) ;
143+ } ) ;
0 commit comments