11const _ = require ( 'lodash' ) ;
2- const BbPromise = require ( 'bluebird' ) ;
32const webpack = require ( 'webpack' ) ;
43const { isBuiltin } = require ( 'node:module' ) ;
54const logStats = require ( './logStats' ) ;
@@ -104,61 +103,84 @@ function getExternalModules({ compilation }) {
104103 return Array . from ( externals ) ;
105104}
106105
107- function webpackCompile ( config , logStats ) {
108- return BbPromise . fromCallback ( cb => webpack ( config ) . run ( cb ) ) . then ( stats => {
109- // ensure stats in any array in the case of concurrent build.
110- stats = stats . stats ? stats . stats : [ stats ] ;
106+ async function webpackCompile ( config , logStats ) {
107+ let stats = await new Promise ( ( resolve , reject ) => {
108+ webpack ( config ) . run ( ( error , result ) => {
109+ if ( error ) {
110+ reject ( error ) ;
111+ return ;
112+ }
113+ resolve ( result ) ;
114+ } ) ;
115+ } ) ;
111116
112- _ . forEach ( stats , logStats ) ;
117+ // ensure stats in any array in the case of concurrent build.
118+ stats = stats . stats ? stats . stats : [ stats ] ;
113119
114- return _ . map ( stats , compileStats => ( {
115- outputPath : compileStats . compilation . compiler . outputPath ,
116- externalModules : getExternalModules ( compileStats )
117- } ) ) ;
118- } ) ;
120+ _ . forEach ( stats , logStats ) ;
121+
122+ return _ . map ( stats , compileStats => ( {
123+ outputPath : compileStats . compilation . compiler . outputPath ,
124+ externalModules : getExternalModules ( compileStats )
125+ } ) ) ;
126+ }
127+
128+ async function mapWithConcurrency ( items , concurrency , iteratee ) {
129+ const results = new Array ( items . length ) ;
130+ let currentIndex = 0 ;
131+
132+ async function worker ( ) {
133+ while ( currentIndex < items . length ) {
134+ const index = currentIndex ;
135+ currentIndex += 1 ;
136+ results [ index ] = await iteratee ( items [ index ] , index ) ;
137+ }
138+ }
139+
140+ const workerCount = Math . min ( concurrency , items . length ) ;
141+ await Promise . all ( Array . from ( { length : workerCount } , ( ) => worker ( ) ) ) ;
142+ return results ;
119143}
120144
121- function webpackConcurrentCompile ( configs , logStats , concurrency , ServerlessError ) {
145+ async function webpackConcurrentCompile ( configs , logStats , concurrency , ServerlessError ) {
122146 const errors = [ ] ;
123- return BbPromise . map (
124- configs ,
125- config => {
126- if ( isIndividialPackaging . call ( this ) && _ . get ( config , 'cache.type' ) === 'filesystem' ) {
127- const clonedConfig = _ . clone ( config ) ;
128- const entryFunc = _ . find ( this . entryFunctions , [ 'entry.key' , _ . keys ( config . entry ) [ 0 ] ] ) ;
129- clonedConfig . cache . name = entryFunc . func . name ;
130- return webpackCompile ( clonedConfig , logStats , ServerlessError ) . catch ( error => {
131- errors . push ( error ) ;
132- return error . stats ;
133- } ) ;
134- }
135- return webpackCompile ( config , logStats , ServerlessError ) . catch ( error => {
147+
148+ const stats = await mapWithConcurrency ( configs , concurrency , async config => {
149+ if ( isIndividialPackaging . call ( this ) && _ . get ( config , 'cache.type' ) === 'filesystem' ) {
150+ const clonedConfig = _ . clone ( config ) ;
151+ const entryFunc = _ . find ( this . entryFunctions , [ 'entry.key' , _ . keys ( config . entry ) [ 0 ] ] ) ;
152+ clonedConfig . cache . name = entryFunc . func . name ;
153+ return webpackCompile ( clonedConfig , logStats , ServerlessError ) . catch ( error => {
136154 errors . push ( error ) ;
137155 return error . stats ;
138156 } ) ;
139- } ,
140- { concurrency }
141- ) . then ( stats => {
142- if ( errors . length ) {
143- if ( ! this . log ) {
144- if ( errors . length === 1 ) {
145- throw errors [ 0 ] ;
146- }
147- throw new ServerlessError ( 'Webpack compilation errors, see stats above' ) ;
148- }
149- throw new ServerlessError (
150- `Webpack compilation failed:\n\n${ _ . join (
151- _ . map ( errors , error => error . message ) ,
152- '\n\n'
153- ) } `
154- ) ;
155157 }
156- return _ . flatten ( stats ) ;
158+ return webpackCompile ( config , logStats , ServerlessError ) . catch ( error => {
159+ errors . push ( error ) ;
160+ return error . stats ;
161+ } ) ;
157162 } ) ;
163+
164+ if ( errors . length ) {
165+ if ( ! this . log ) {
166+ if ( errors . length === 1 ) {
167+ throw errors [ 0 ] ;
168+ }
169+ throw new ServerlessError ( 'Webpack compilation errors, see stats above' ) ;
170+ }
171+ throw new ServerlessError (
172+ `Webpack compilation failed:\n\n${ _ . join (
173+ _ . map ( errors , error => error . message ) ,
174+ '\n\n'
175+ ) } `
176+ ) ;
177+ }
178+
179+ return _ . flatten ( stats ) ;
158180}
159181
160182module . exports = {
161- compile ( ) {
183+ async compile ( ) {
162184 if ( this . log ) {
163185 this . log . verbose ( '[Webpack] Building with Webpack' ) ;
164186 this . progress . get ( 'webpack' ) . update ( '[Webpack] Building with Webpack' ) ;
@@ -168,7 +190,7 @@ module.exports = {
168190
169191 const configs = ensureArray ( this . webpackConfig ) ;
170192 if ( configs [ 0 ] === undefined ) {
171- return BbPromise . reject ( 'Unable to find Webpack configuration' ) ;
193+ throw new this . serverless . classes . Error ( 'Unable to find Webpack configuration' ) ;
172194 }
173195
174196 const logStats = getStatsLogger ( configs [ 0 ] . stats , this . serverless . cli . consoleLog , {
@@ -177,20 +199,21 @@ module.exports = {
177199 } ) ;
178200
179201 if ( ! this . configuration ) {
180- return BbPromise . reject ( new this . serverless . classes . Error ( 'Missing plugin configuration' ) ) ;
202+ throw new this . serverless . classes . Error ( 'Missing plugin configuration' ) ;
181203 }
182204 const concurrency = this . configuration . concurrency ;
183205
184- return webpackConcurrentCompile
185- . call ( this , configs , logStats , concurrency , this . serverless . classes . Error )
186- . then ( stats => {
187- this . compileStats = { stats } ;
188-
189- if ( this . log ) {
190- this . progress . get ( 'webpack' ) . remove ( ) ;
191- }
206+ const stats = await webpackConcurrentCompile . call (
207+ this ,
208+ configs ,
209+ logStats ,
210+ concurrency ,
211+ this . serverless . classes . Error
212+ ) ;
213+ this . compileStats = { stats } ;
192214
193- return BbPromise . resolve ( ) ;
194- } ) ;
215+ if ( this . log ) {
216+ this . progress . get ( 'webpack' ) . remove ( ) ;
217+ }
195218 }
196219} ;
0 commit comments