@@ -16,10 +16,17 @@ class DevServerPlugin {
1616 }
1717
1818 /**
19- * An Entry, it can be of type string or string[] or Object<string | string[],string>
19+ * A Entry, it can be of type string or string[] or Object<string | string[],string>
2020 * @typedef {(string[] | string | Object<string | string[],string>) } Entry
2121 */
2222
23+ /**
24+ * Additional entry to add to specific chunk
25+ * @typedef {Object } AdditionalChunkEntry
26+ * @property {Entry } entry
27+ * @property {string[] } [chunks]
28+ */
29+
2330 /**
2431 * Apply the plugin
2532 * @param {Object } compiler the compiler instance
@@ -69,7 +76,7 @@ class DevServerPlugin {
6976 /**
7077 * prependEntry Method for webpack 4
7178 * @param {Entry } originalEntry
72- * @param {Entry } additionalEntries
79+ * @param {AdditionalChunkEntry[] } additionalEntries
7380 * @returns {Entry }
7481 */
7582 const prependEntry = ( originalEntry , additionalEntries ) => {
@@ -86,8 +93,13 @@ class DevServerPlugin {
8693
8794 Object . keys ( originalEntry ) . forEach ( ( key ) => {
8895 // entry[key] should be a string here
96+ const chunkAdditionalEntries = additionalEntries . filter (
97+ ( additionalEntry ) =>
98+ ! additionalEntry . chunks || additionalEntry . chunks . includes ( key )
99+ ) ;
100+
89101 const entryDescription = originalEntry [ key ] ;
90- clone [ key ] = prependEntry ( entryDescription , additionalEntries ) ;
102+ clone [ key ] = prependEntry ( entryDescription , chunkAdditionalEntries ) ;
91103 } ) ;
92104
93105 return clone ;
@@ -96,13 +108,15 @@ class DevServerPlugin {
96108 // in this case, entry is a string or an array.
97109 // make sure that we do not add duplicates.
98110 /** @type {Entry } */
99- const entriesClone = additionalEntries . slice ( 0 ) ;
111+ const newEntries = additionalEntries . map (
112+ ( additionalEntry ) => additionalEntry . entry
113+ ) ;
100114 [ ] . concat ( originalEntry ) . forEach ( ( newEntry ) => {
101- if ( ! entriesClone . includes ( newEntry ) ) {
102- entriesClone . push ( newEntry ) ;
115+ if ( ! newEntries . includes ( newEntry ) ) {
116+ newEntries . push ( newEntry ) ;
103117 }
104118 } ) ;
105- return entriesClone ;
119+ return newEntries ;
106120 } ;
107121
108122 /**
@@ -115,23 +129,27 @@ class DevServerPlugin {
115129
116130 /**
117131 *
118- * @param {Boolean | checkInjectOptionsParam } option - inject(Hot|Client) it is Boolean | fn => Boolean
132+ * @param {Boolean | string[] | checkInjectOptionsParam } option - inject(Hot|Client) it is Boolean | fn => Boolean
119133 * @param {Object } _config
120134 * @param {Boolean } defaultValue
121- * @return {Boolean }
135+ * @return {Boolean | string[] }
122136 */
123- // eslint-disable-next-line no-shadow
137+ // eslint-disable-next-line no-shadow
124138 const checkInject = ( option , _config , defaultValue ) => {
125- if ( typeof option === 'boolean' ) {
126- return option ;
127- }
139+ if ( typeof option === 'boolean' ) {
140+ return option ;
141+ }
128142
129- if ( typeof option === 'function' ) {
130- return option ( _config ) ;
131- }
143+ if ( Array . isArray ( option ) ) {
144+ return option ;
145+ }
132146
133- return defaultValue ;
134- } ;
147+ if ( typeof option === 'function' ) {
148+ return option ( _config ) ;
149+ }
150+
151+ return defaultValue ;
152+ } ;
135153
136154 const compilerOptions = compiler . options ;
137155
@@ -141,35 +159,68 @@ class DevServerPlugin {
141159 const isWebTarget = compilerOptions . externalsPresets
142160 ? compilerOptions . externalsPresets . web
143161 : [
144- 'web' ,
145- 'webworker' ,
146- 'electron-renderer' ,
147- 'node-webkit' ,
148- // eslint-disable-next-line no-undefined
149- undefined ,
150- null ,
151- ] . includes ( compilerOptions . target ) ;
152-
153- /** @type {Entry } */
154- const additionalEntries = checkInject (
162+ 'web' ,
163+ 'webworker' ,
164+ 'electron-renderer' ,
165+ 'node-webkit' ,
166+ // eslint-disable-next-line no-undefined
167+ undefined ,
168+ null ,
169+ ] . includes ( compilerOptions . target ) ;
170+
171+ /** @type {AdditionalChunkEntry[] } */
172+ const additionalEntries = [ ] ;
173+
174+ const checkInjectClientResult = checkInject (
155175 options . injectClient ,
156176 compilerOptions ,
157177 isWebTarget
158- )
159- ? [ clientEntry ]
160- : [ ] ;
178+ ) ;
179+ if ( checkInjectClientResult ) {
180+ additionalEntries . push ( {
181+ entry : clientEntry ,
182+ chunks : Array . isArray ( checkInjectClientResult )
183+ ? checkInjectClientResult
184+ : null ,
185+ } ) ;
186+ }
161187
162- if ( hotEntry && checkInject ( options . injectHot , compilerOptions , true ) ) {
163- additionalEntries . push ( hotEntry ) ;
188+ if ( hotEntry ) {
189+ const checkInjectHotResult = checkInject (
190+ options . injectHot ,
191+ compilerOptions ,
192+ true
193+ ) ;
194+ if ( checkInjectHotResult ) {
195+ additionalEntries . push ( {
196+ entry : hotEntry ,
197+ chunks : Array . isArray ( checkInjectHotResult )
198+ ? checkInjectHotResult
199+ : null ,
200+ } ) ;
201+ }
164202 }
165203
166204 // use a hook to add entries if available
167205 if ( EntryPlugin ) {
168- for ( const additionalEntry of additionalEntries ) {
169- new EntryPlugin ( compiler . context , additionalEntry , {
170- // eslint-disable-next-line no-undefined
171- name : undefined ,
172- } ) . apply ( compiler ) ;
206+ for ( const additionalChunkEntry of additionalEntries ) {
207+ // add entry to existing chunks
208+ if (
209+ additionalChunkEntry . chunks &&
210+ Array . isArray ( additionalChunkEntry . chunks )
211+ ) {
212+ additionalChunkEntry . chunks . forEach ( ( chunkName ) => {
213+ new EntryPlugin ( compiler . context , additionalChunkEntry . entry , {
214+ // eslint-disable-next-line no-undefined
215+ name : chunkName ,
216+ } ) . apply ( compiler ) ;
217+ } ) ;
218+ } else {
219+ new EntryPlugin ( compiler . context , additionalChunkEntry . entry , {
220+ // eslint-disable-next-line no-undefined
221+ name : undefined ,
222+ } ) . apply ( compiler ) ;
223+ }
173224 }
174225 } else {
175226 compilerOptions . entry = prependEntry (
0 commit comments