@@ -8,36 +8,45 @@ import { logger } from '@modern-js/utils';
88import { devPlugin , manager } from './dev' ;
99import { getDevAssetPrefix , getDevOptions } from './helpers' ;
1010import { ResourceType } from './helpers/utils' ;
11+ import serverHmrPlugin from './plugins/serverHmr' ;
1112import type { ApplyPlugins , ModernDevServerOptions } from './types' ;
1213
13- export async function createDevServer (
14+ async function createServerOptions (
1415 options : ModernDevServerOptions ,
15- applyPlugins : ApplyPlugins ,
16+ serverConfigPath : string ,
17+ distDir : string ,
1618) {
17- const { config, pwd, serverConfigPath, builder } = options ;
18- const dev = getDevOptions ( options . dev ) ;
19-
20- const distDir = path . resolve ( pwd , config . output . distPath ?. root || 'dist' ) ;
21-
2219 const serverConfig = ( await loadServerRuntimeConfig ( serverConfigPath ) ) || { } ;
2320
24- const prodServerOptions = {
21+ return {
2522 ...options ,
26- pwd : distDir , // server base pwd must distDir,
23+ pwd : distDir ,
2724 serverConfig : {
2825 ...serverConfig ,
2926 ...options . serverConfig ,
3027 } ,
31- /**
32- * 1. server plugins from modern.server.ts
33- * 2. server plugins register by cli use _internalServerPlugins
34- * Merge plugins, the plugins from modern.server.ts will run first
35- */
3628 plugins : [ ...( serverConfig . plugins || [ ] ) , ...( options . plugins || [ ] ) ] ,
3729 } ;
30+ }
31+
32+ export async function createDevServer (
33+ options : ModernDevServerOptions ,
34+ applyPlugins : ApplyPlugins ,
35+ ) {
36+ const { config, pwd, serverConfigPath, builder } = options ;
37+ const dev = getDevOptions ( options . dev ) ;
38+
39+ const distDir = path . resolve ( pwd , config . output . distPath ?. root || 'dist' ) ;
40+
41+ const prodServerOptions = await createServerOptions (
42+ options ,
43+ serverConfigPath ,
44+ distDir ,
45+ ) ;
3846
3947 const server = createServerBase ( prodServerOptions ) ;
4048 let currentServer = server ;
49+ let isReloading = false ;
4150
4251 const devHttpsOption = typeof dev === 'object' && dev . https ;
4352 const isHttp2 = ! ! devHttpsOption ;
@@ -62,69 +71,64 @@ export async function createDevServer(
6271 compiler : options . compiler ,
6372 } ) ;
6473
65- server . addPlugins ( [
66- devPlugin ( {
67- ...options ,
68- builderDevServer,
69- } ) ,
70- ] ) ;
71-
72- // run after createDevServer, we can get assetPrefix from builder
73- const assetPrefix = await promise ;
74- if ( assetPrefix ) {
75- prodServerOptions . config . output . assetPrefix = assetPrefix ;
76- }
77-
78- await applyPlugins ( server , prodServerOptions , nodeServer ) ;
79-
80- await server . init ( ) ;
81-
82- const afterListen = async ( ) => {
83- await builderDevServer ?. afterListen ( ) ;
84- } ;
85-
8674 const reload = async ( ) => {
75+ if ( isReloading ) {
76+ return ;
77+ }
8778 try {
88- const updatedServerConfig =
89- ( await loadServerRuntimeConfig ( serverConfigPath ) ) || { } ;
90-
91- const updatedProdServerOptions = {
92- ...options ,
93- pwd : distDir ,
94- serverConfig : {
95- ...updatedServerConfig ,
96- ...options . serverConfig ,
97- } ,
98- plugins : [
99- ...( updatedServerConfig . plugins || [ ] ) ,
100- ...( options . plugins || [ ] ) ,
101- ] ,
102- } ;
79+ isReloading = true ;
10380
81+ const updatedProdServerOptions = await createServerOptions (
82+ options ,
83+ serverConfigPath ,
84+ distDir ,
85+ ) ;
10486 const newServer = createServerBase ( updatedProdServerOptions ) ;
10587
10688 await manager . close ( ResourceType . Watcher ) ;
10789
10890 newServer . addPlugins ( [
91+ serverHmrPlugin ( reload ) ,
10992 devPlugin ( {
11093 ...options ,
11194 } ) ,
11295 ] ) ;
113-
11496 await applyPlugins ( newServer , updatedProdServerOptions , nodeServer ) ;
115-
11697 await newServer . init ( ) ;
11798
11899 currentServer = newServer ;
119100 logger . info ( `Custom Web Server HMR succeeded` ) ;
120101 } catch ( e ) {
121102 logger . error ( '[Custom Web Server HMR failed]:' , e ) ;
103+ } finally {
104+ isReloading = false ;
122105 }
123106 } ;
124107
108+ server . addPlugins ( [
109+ serverHmrPlugin ( reload ) ,
110+ devPlugin ( {
111+ ...options ,
112+ builderDevServer,
113+ } ) ,
114+ ] ) ;
115+
116+ // run after createDevServer, we can get assetPrefix from builder
117+ const assetPrefix = await promise ;
118+ if ( assetPrefix ) {
119+ prodServerOptions . config . output . assetPrefix = assetPrefix ;
120+ }
121+
122+ await applyPlugins ( server , prodServerOptions , nodeServer ) ;
123+
124+ await server . init ( ) ;
125+
126+ const afterListen = async ( ) => {
127+ await builderDevServer ?. afterListen ( ) ;
128+ } ;
129+
125130 return {
126131 server : nodeServer ,
127132 afterListen,
128- reload,
129133 } ;
130134}
0 commit comments