@@ -9,13 +9,14 @@ const {
9
9
const ConstDependency = require ( 'webpack/lib/dependencies/ConstDependency' ) ;
10
10
const { refreshGlobal, webpackRequire, webpackVersion } = require ( './globals' ) ;
11
11
const {
12
+ getAdditionalEntries,
13
+ getIntegrationEntry,
12
14
getParserHelpers,
13
15
getRefreshGlobal,
14
16
getSocketIntegration,
15
17
injectRefreshEntry,
16
18
injectRefreshLoader,
17
19
normalizeOptions,
18
- getAdditionalEntries,
19
20
} = require ( './utils' ) ;
20
21
const schema = require ( './options.json' ) ;
21
22
@@ -33,27 +34,6 @@ const REPLACEMENTS = {
33
34
} ,
34
35
} ;
35
36
36
- /**
37
- * Gets the socket integration to use for Webpack messages.
38
- * @param {'wds' | 'whm' | 'wps' | string } integrationType A valid socket integration type or a path to a module.
39
- * @returns {string | undefined } Path to the resolved socket integration module.
40
- */
41
- function getSocketIntegrationEntry ( integrationType ) {
42
- let resolvedEntry ;
43
- switch ( integrationType ) {
44
- case 'whm' : {
45
- resolvedEntry = 'webpack-hot-middleware/client' ;
46
- break ;
47
- }
48
- case 'wps' : {
49
- resolvedEntry = 'webpack-plugin-serve/client' ;
50
- break ;
51
- }
52
- }
53
-
54
- return resolvedEntry ;
55
- }
56
-
57
37
class ReactRefreshPlugin {
58
38
/**
59
39
* @param {import('./types').ReactRefreshPluginOptions } [options] Options for react-refresh-plugin.
@@ -107,20 +87,19 @@ class ReactRefreshPlugin {
107
87
options : this . options ,
108
88
} ) ;
109
89
if ( EntryPlugin ) {
90
+ // Prepended entries does not care about injection order,
91
+ // so we can utilise EntryPlugin for simpler logic.
110
92
additional . prependEntries . forEach ( ( entry ) => {
111
93
new EntryPlugin ( compiler . context , entry , { name : undefined } ) . apply ( compiler ) ;
112
94
} ) ;
113
95
96
+ const integrationEntry = getIntegrationEntry ( this . options . overlay . sockIntegration ) ;
114
97
const socketEntryData = [ ] ;
115
98
compiler . hooks . make . tap (
116
99
{ name : this . constructor . name , stage : Number . POSITIVE_INFINITY } ,
117
100
( compilation ) => {
118
- const integrationEntry = getSocketIntegrationEntry ( this . options . overlay . sockIntegration ) ;
119
-
120
101
// Exhaustively search all entries for `integrationEntry`.
121
- // If found, inject `overlayEntries` to those entries,
122
- // and ensure the order of dependencies either here or in `seal`.
123
- // Else, inject `overlayEntries` to global entries.
102
+ // If found, mark those entries and the index of `integrationEntry`.
124
103
for ( const [ name , entryData ] of compilation . entries . entries ( ) ) {
125
104
const index = entryData . dependencies . findIndex ( ( dep ) =>
126
105
dep . request . includes ( integrationEntry )
@@ -132,6 +111,9 @@ class ReactRefreshPlugin {
132
111
}
133
112
) ;
134
113
114
+ // Overlay entries need to be injected AFTER integration's entry,
115
+ // so we will loop through everything in `finishMake` instead of `make`.
116
+ // This ensures we can traverse all entry points and inject stuff with the correct order.
135
117
additional . overlayEntries . forEach ( ( entry , idx , arr ) => {
136
118
compiler . hooks . finishMake . tapPromise (
137
119
{ name : this . constructor . name , stage : Number . MIN_SAFE_INTEGER + ( arr . length - idx - 1 ) } ,
@@ -150,6 +132,10 @@ class ReactRefreshPlugin {
150
132
compilation . addEntry ( compiler . context , dep , options , ( err ) => {
151
133
if ( err ) return reject ( err ) ;
152
134
135
+ // If the entry is not a global one,
136
+ // and we have registered the index for integration entry,
137
+ // we will reorder all entry dependencies to our desired order.
138
+ // That is, to have additional entries DIRECTLY behind integration entry.
153
139
if ( name && typeof index !== 'undefined' ) {
154
140
const entryData = compilation . entries . get ( name ) ;
155
141
entryData . dependencies . splice (
0 commit comments