@@ -5,7 +5,6 @@ const _ = require('lodash');
55const path = require ( 'path' ) ;
66const childProcess = require ( 'child_process' ) ;
77const fse = require ( 'fs-extra' ) ;
8- const npm = require ( 'npm-programmatic' ) ;
98const isBuiltinModule = require ( 'is-builtin-module' ) ;
109
1110function getProdModules ( externalModules , packagePath , dependencyGraph ) {
@@ -193,22 +192,49 @@ module.exports = {
193192 // (1.a) Install all needed modules
194193 const compositeModulePath = path . join ( this . webpackOutputPath , 'dependencies' ) ;
195194 const compositePackageJson = path . join ( compositeModulePath , 'package.json' ) ;
196- this . serverless . utils . writeFileSync ( compositePackageJson , '{}' ) ;
197195
198- this . serverless . cli . log ( 'Packing external modules: ' + compositeModules . join ( ', ' ) ) ;
196+ // (1.a.1) Create a package.json
197+ const compositePackage = {
198+ name : this . serverless . service . service ,
199+ version : '1.0.0' ,
200+ description : `Packaged externals for ${ this . serverless . service . service } ` ,
201+ private : true
202+ } ;
203+ _ . forEach ( compositeModules , compositeModule => {
204+ const splitModule = _ . split ( compositeModule , '@' ) ;
205+ // If we have a scoped module we have to re-add the @
206+ if ( _ . startsWith ( compositeModule , '@' ) ) {
207+ splitModule . splice ( 0 , 1 ) ;
208+ splitModule [ 0 ] = '@' + splitModule [ 0 ] ;
209+ }
210+ const moduleVersion = _ . join ( _ . tail ( splitModule ) , '@' ) ;
211+ _ . set ( compositePackage , `dependencies.${ _ . first ( splitModule ) } ` , moduleVersion ) ;
212+ } ) ;
213+ this . serverless . utils . writeFileSync ( compositePackageJson , JSON . stringify ( compositePackage , null , 2 ) ) ;
199214
200- return new BbPromise ( ( resolve , reject ) => {
215+ // (1.a.2) Copy package-lock.json if it exists, to prevent unwanted upgrades
216+ const packageLockPath = path . join ( path . dirname ( packageJsonPath ) , 'package-lock.json' ) ;
217+ return BbPromise . fromCallback ( cb => fse . pathExists ( packageLockPath , cb ) )
218+ . then ( exists => {
219+ if ( exists ) {
220+ this . serverless . cli . log ( 'Package lock found - Using locked versions' ) ;
221+ return BbPromise . fromCallback ( cb => fse . copy ( packageLockPath , path . join ( compositeModulePath , 'package-lock.json' ) , cb ) )
222+ . catch ( err => this . serverless . cli . log ( `Warning: Could not copy lock file: ${ err . message } ` ) ) ;
223+ }
224+ return BbPromise . resolve ( ) ;
225+ } )
226+ . then ( ( ) => {
201227 const start = _ . now ( ) ;
202- npm . install ( compositeModules , {
203- cwd : compositeModulePath ,
204- maxBuffer : this . serverless . service . custom . packExternalModulesMaxBuffer || 200 * 1024 ,
205- save : true
206- } ) . then ( ( ) => {
207- this . options . verbose && this . serverless . cli . log ( `Package took [ ${ _ . now ( ) - start } ms]` ) ; // eslint-disable-line promise/always-return
208- resolve ( stats . stats ) ;
209- } ) . catch ( e => {
210- reject ( e ) ;
211- } ) ;
228+ this . serverless . cli . log ( 'Packing external modules: ' + compositeModules . join ( ', ' ) ) ;
229+ return BbPromise . fromCallback ( cb => {
230+ childProcess . exec ( 'npm install' , {
231+ cwd : compositeModulePath ,
232+ maxBuffer : this . serverless . service . custom . packExternalModulesMaxBuffer || 200 * 1024 ,
233+ encoding : 'utf8'
234+ } , cb ) ;
235+ } )
236+ . then ( ( ) => this . options . verbose && this . serverless . cli . log ( `Package took [ ${ _ . now ( ) - start } ms]` ) )
237+ . return ( stats . stats ) ;
212238 } )
213239 . mapSeries ( compileStats => {
214240 const modulePath = compileStats . compilation . compiler . outputPath ;
0 commit comments