@@ -12,6 +12,7 @@ const Serverless = require('serverless');
1212const childProcessMockFactory = require ( './mocks/child_process.mock' ) ;
1313const fsExtraMockFactory = require ( './mocks/fs-extra.mock' ) ;
1414const packageMock = require ( './mocks/package.mock.json' ) ;
15+ const packageLocalRefMock = require ( './mocks/packageLocalRef.mock.json' ) ;
1516
1617chai . use ( require ( 'chai-as-promised' ) ) ;
1718chai . use ( require ( 'sinon-chai' ) ) ;
@@ -29,6 +30,7 @@ describe('packExternalModules', () => {
2930 let fsExtraMock ;
3031 // Serverless stubs
3132 let writeFileSyncStub ;
33+ let readFileSyncStub ;
3234
3335 before ( ( ) => {
3436 sandbox = sinon . sandbox . create ( ) ;
@@ -59,6 +61,7 @@ describe('packExternalModules', () => {
5961 _ . set ( serverless , 'service.service' , 'test-service' ) ;
6062
6163 writeFileSyncStub = sandbox . stub ( serverless . utils , 'writeFileSync' ) ;
64+ readFileSyncStub = sandbox . stub ( serverless . utils , 'readFileSync' ) ;
6265 _ . set ( serverless , 'service.custom.webpackIncludeModules' , true ) ;
6366
6467 module = _ . assign ( {
@@ -72,6 +75,7 @@ describe('packExternalModules', () => {
7275 afterEach ( ( ) => {
7376 // Reset all counters and restore all stubbed functions
7477 writeFileSyncStub . reset ( ) ;
78+ readFileSyncStub . reset ( ) ;
7579 childProcessMock . exec . reset ( ) ;
7680 fsExtraMock . pathExists . reset ( ) ;
7781 fsExtraMock . copy . reset ( ) ;
@@ -151,6 +155,50 @@ describe('packExternalModules', () => {
151155 }
152156 ]
153157 } ;
158+ const statsWithFileRef = {
159+ stats : [
160+ {
161+ compilation : {
162+ chunks : [
163+ {
164+ modules : [
165+ {
166+ identifier : _ . constant ( '"crypto"' )
167+ } ,
168+ {
169+ identifier : _ . constant ( '"uuid/v4"' )
170+ } ,
171+ {
172+ identifier : _ . constant ( 'external "eslint"' )
173+ } ,
174+ {
175+ identifier : _ . constant ( '"mockery"' )
176+ } ,
177+ {
178+ identifier : _ . constant ( '"@scoped/vendor/module1"' )
179+ } ,
180+ {
181+ identifier : _ . constant ( 'external "@scoped/vendor/module2"' )
182+ } ,
183+ {
184+ identifier : _ . constant ( 'external "uuid/v4"' )
185+ } ,
186+ {
187+ identifier : _ . constant ( 'external "localmodule"' )
188+ } ,
189+ {
190+ identifier : _ . constant ( 'external "bluebird"' )
191+ } ,
192+ ]
193+ }
194+ ] ,
195+ compiler : {
196+ outputPath : '/my/Service/Path/.webpack/service'
197+ }
198+ }
199+ }
200+ ]
201+ } ;
154202
155203 it ( 'should do nothing if webpackIncludeModules is not set' , ( ) => {
156204 _ . unset ( serverless , 'service.custom.webpackIncludeModules' ) ;
@@ -212,6 +260,102 @@ describe('packExternalModules', () => {
212260 ] ) ) ;
213261 } ) ;
214262
263+ it ( 'should rebase file references' , ( ) => {
264+ const expectedLocalModule = 'file:../../locals/../../mymodule' ;
265+ const expectedCompositePackageJSON = {
266+ name : 'test-service' ,
267+ version : '1.0.0' ,
268+ description : 'Packaged externals for test-service' ,
269+ private : true ,
270+ dependencies : {
271+ '@scoped/vendor' : '1.0.0' ,
272+ uuid : '^5.4.1' ,
273+ localmodule : 'file:../../locals/../../mymodule' ,
274+ bluebird : '^3.4.0'
275+ }
276+ } ;
277+ const expectedPackageJSON = {
278+ dependencies : {
279+ '@scoped/vendor' : '1.0.0' ,
280+ uuid : '^5.4.1' ,
281+ localmodule : expectedLocalModule ,
282+ bluebird : '^3.4.0'
283+ }
284+ } ;
285+
286+ const fakePackageLockJSON = {
287+ name : 'test-service' ,
288+ version : '1.0.0' ,
289+ description : 'Packaged externals for test-service' ,
290+ private : true ,
291+ dependencies : {
292+ '@scoped/vendor' : '1.0.0' ,
293+ uuid : {
294+ version : '^5.4.1'
295+ } ,
296+ bluebird : {
297+ version : '^3.4.0'
298+ } ,
299+ localmodule : {
300+ version : 'file:../../mymodule'
301+ }
302+ }
303+ } ;
304+ const expectedPackageLockJSON = {
305+ name : 'test-service' ,
306+ version : '1.0.0' ,
307+ description : 'Packaged externals for test-service' ,
308+ private : true ,
309+ dependencies : {
310+ '@scoped/vendor' : '1.0.0' ,
311+ uuid : {
312+ version : '^5.4.1'
313+ } ,
314+ bluebird : {
315+ version : '^3.4.0'
316+ } ,
317+ localmodule : {
318+ version : expectedLocalModule
319+ }
320+ }
321+ } ;
322+
323+ _ . set ( serverless , 'service.custom.webpackIncludeModules.packagePath' , path . join ( 'locals' , 'package.json' ) ) ;
324+ module . webpackOutputPath = 'outputPath' ;
325+ readFileSyncStub . returns ( fakePackageLockJSON ) ;
326+ fsExtraMock . pathExists . yields ( null , true ) ;
327+ fsExtraMock . copy . yields ( ) ;
328+ childProcessMock . exec . onFirstCall ( ) . yields ( null , '{}' , '' ) ;
329+ childProcessMock . exec . onSecondCall ( ) . yields ( null , '' , '' ) ;
330+ childProcessMock . exec . onThirdCall ( ) . yields ( ) ;
331+ module . compileStats = statsWithFileRef ;
332+
333+ sandbox . stub ( process , 'cwd' ) . returns ( path . join ( '/my/Service/Path' ) ) ;
334+ mockery . registerMock ( path . join ( process . cwd ( ) , 'locals' , 'package.json' ) , packageLocalRefMock ) ;
335+
336+ return expect ( module . packExternalModules ( ) ) . to . be . fulfilled
337+ . then ( ( ) => BbPromise . all ( [
338+ // The module package JSON and the composite one should have been stored
339+ expect ( writeFileSyncStub ) . to . have . been . calledThrice ,
340+ expect ( writeFileSyncStub . firstCall . args [ 1 ] ) . to . equal ( JSON . stringify ( expectedCompositePackageJSON , null , 2 ) ) ,
341+ expect ( writeFileSyncStub . secondCall . args [ 1 ] ) . to . equal ( JSON . stringify ( expectedPackageLockJSON , null , 2 ) ) ,
342+ expect ( writeFileSyncStub . thirdCall . args [ 1 ] ) . to . equal ( JSON . stringify ( expectedPackageJSON , null , 2 ) ) ,
343+ // The modules should have been copied
344+ expect ( fsExtraMock . copy ) . to . have . been . calledOnce ,
345+ // npm ls and npm prune should have been called
346+ expect ( childProcessMock . exec ) . to . have . been . calledThrice ,
347+ expect ( childProcessMock . exec . firstCall ) . to . have . been . calledWith (
348+ 'npm ls -prod -json -depth=1'
349+ ) ,
350+ expect ( childProcessMock . exec . secondCall ) . to . have . been . calledWith (
351+ 'npm install'
352+ ) ,
353+ expect ( childProcessMock . exec . thirdCall ) . to . have . been . calledWith (
354+ 'npm prune'
355+ )
356+ ] ) ) ;
357+ } ) ;
358+
215359 it ( 'should skip module copy for Google provider' , ( ) => {
216360 const expectedCompositePackageJSON = {
217361 name : 'test-service' ,
@@ -601,10 +745,7 @@ describe('packExternalModules', () => {
601745 expect ( writeFileSyncStub . firstCall . args [ 1 ] ) . to . equal ( JSON . stringify ( expectedCompositePackageJSON , null , 2 ) ) ,
602746 expect ( writeFileSyncStub . secondCall . args [ 1 ] ) . to . equal ( JSON . stringify ( expectedPackageJSON , null , 2 ) ) ,
603747 // The modules should have been copied
604- expect ( fsExtraMock . copy ) . to . have . been . calledTwice ,
605- expect ( fsExtraMock . copy . firstCall ) . to . have . been . calledWith (
606- sinon . match ( / p a c k a g e - l o c k .j s o n $ / )
607- ) ,
748+ expect ( fsExtraMock . copy ) . to . have . been . calledOnce ,
608749 // npm ls and npm prune should have been called
609750 expect ( childProcessMock . exec ) . to . have . been . calledThrice ,
610751 expect ( childProcessMock . exec . firstCall ) . to . have . been . calledWith (
@@ -640,9 +781,9 @@ describe('packExternalModules', () => {
640781 } ;
641782
642783 module . webpackOutputPath = 'outputPath' ;
784+ readFileSyncStub . throws ( new Error ( 'Failed to read package-lock.json' ) ) ;
643785 fsExtraMock . pathExists . yields ( null , true ) ;
644- fsExtraMock . copy . onFirstCall ( ) . yields ( new Error ( 'Failed to read package-lock.json' ) ) ;
645- fsExtraMock . copy . onSecondCall ( ) . yields ( ) ;
786+ fsExtraMock . copy . onFirstCall ( ) . yields ( ) ;
646787 childProcessMock . exec . onFirstCall ( ) . yields ( null , '{}' , '' ) ;
647788 childProcessMock . exec . onSecondCall ( ) . yields ( null , '' , '' ) ;
648789 childProcessMock . exec . onThirdCall ( ) . yields ( ) ;
@@ -654,10 +795,7 @@ describe('packExternalModules', () => {
654795 expect ( writeFileSyncStub . firstCall . args [ 1 ] ) . to . equal ( JSON . stringify ( expectedCompositePackageJSON , null , 2 ) ) ,
655796 expect ( writeFileSyncStub . secondCall . args [ 1 ] ) . to . equal ( JSON . stringify ( expectedPackageJSON , null , 2 ) ) ,
656797 // The modules should have been copied
657- expect ( fsExtraMock . copy ) . to . have . been . calledTwice ,
658- expect ( fsExtraMock . copy . firstCall ) . to . have . been . calledWith (
659- sinon . match ( / p a c k a g e - l o c k .j s o n $ / )
660- ) ,
798+ expect ( fsExtraMock . copy ) . to . have . been . calledOnce ,
661799 // npm ls and npm prune should have been called
662800 expect ( childProcessMock . exec ) . to . have . been . calledThrice ,
663801 expect ( childProcessMock . exec . firstCall ) . to . have . been . calledWith (
0 commit comments