@@ -8,36 +8,45 @@ import { logger } from '@modern-js/utils';
8
8
import { devPlugin , manager } from './dev' ;
9
9
import { getDevAssetPrefix , getDevOptions } from './helpers' ;
10
10
import { ResourceType } from './helpers/utils' ;
11
+ import serverHmrPlugin from './plugins/serverHmr' ;
11
12
import type { ApplyPlugins , ModernDevServerOptions } from './types' ;
12
13
13
- export async function createDevServer (
14
+ async function createServerOptions (
14
15
options : ModernDevServerOptions ,
15
- applyPlugins : ApplyPlugins ,
16
+ serverConfigPath : string ,
17
+ distDir : string ,
16
18
) {
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
-
22
19
const serverConfig = ( await loadServerRuntimeConfig ( serverConfigPath ) ) || { } ;
23
20
24
- const prodServerOptions = {
21
+ return {
25
22
...options ,
26
- pwd : distDir , // server base pwd must distDir,
23
+ pwd : distDir ,
27
24
serverConfig : {
28
25
...serverConfig ,
29
26
...options . serverConfig ,
30
27
} ,
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
- */
36
28
plugins : [ ...( serverConfig . plugins || [ ] ) , ...( options . plugins || [ ] ) ] ,
37
29
} ;
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
+ ) ;
38
46
39
47
const server = createServerBase ( prodServerOptions ) ;
40
48
let currentServer = server ;
49
+ let isReloading = false ;
41
50
42
51
const devHttpsOption = typeof dev === 'object' && dev . https ;
43
52
const isHttp2 = ! ! devHttpsOption ;
@@ -62,69 +71,64 @@ export async function createDevServer(
62
71
compiler : options . compiler ,
63
72
} ) ;
64
73
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
-
86
74
const reload = async ( ) => {
75
+ if ( isReloading ) {
76
+ return ;
77
+ }
87
78
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 ;
103
80
81
+ const updatedProdServerOptions = await createServerOptions (
82
+ options ,
83
+ serverConfigPath ,
84
+ distDir ,
85
+ ) ;
104
86
const newServer = createServerBase ( updatedProdServerOptions ) ;
105
87
106
88
await manager . close ( ResourceType . Watcher ) ;
107
89
108
90
newServer . addPlugins ( [
91
+ serverHmrPlugin ( reload ) ,
109
92
devPlugin ( {
110
93
...options ,
111
94
} ) ,
112
95
] ) ;
113
-
114
96
await applyPlugins ( newServer , updatedProdServerOptions , nodeServer ) ;
115
-
116
97
await newServer . init ( ) ;
117
98
118
99
currentServer = newServer ;
119
100
logger . info ( `Custom Web Server HMR succeeded` ) ;
120
101
} catch ( e ) {
121
102
logger . error ( '[Custom Web Server HMR failed]:' , e ) ;
103
+ } finally {
104
+ isReloading = false ;
122
105
}
123
106
} ;
124
107
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
+
125
130
return {
126
131
server : nodeServer ,
127
132
afterListen,
128
- reload,
129
133
} ;
130
134
}
0 commit comments