From 219b5de5445e12bf74fedaae8c1b49c2b5c643b6 Mon Sep 17 00:00:00 2001 From: hieuunguyeen Date: Thu, 13 Jan 2022 18:13:21 +0200 Subject: [PATCH 1/2] Fix filesystem cache not working when package individually is set Remove leftover parameter --- lib/compile.js | 20 +++++- tests/compile.test.js | 157 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 174 insertions(+), 3 deletions(-) diff --git a/lib/compile.js b/lib/compile.js index 20847f722..9743f9522 100644 --- a/lib/compile.js +++ b/lib/compile.js @@ -16,6 +16,10 @@ function getStatsLogger(statsConfig, consoleLog, { log, ServerlessError }) { }; } +function isIndividialPackaging() { + return _.get(this.serverless, 'service.package.individually'); +} + function getExternalModuleName(module) { const pathArray = /^external .*"(.*?)"$/.exec(module.identifier()); if (!pathArray) { @@ -120,11 +124,21 @@ function webpackConcurrentCompile(configs, logStats, concurrency, ServerlessErro const errors = []; return BbPromise.map( configs, - config => - webpackCompile(config, logStats).catch(error => { + config => { + if (isIndividialPackaging.call(this) && _.get(config, 'cache.type') === 'filesystem') { + const clonedConfig = _.clone(config); + const entryFunc = _.find(this.entryFunctions, ['entry.key', _.keys(config.entry)[0]]); + clonedConfig.cache.name = entryFunc.func.name; + return webpackCompile(clonedConfig, logStats, ServerlessError).catch(error => { + errors.push(error); + return error.stats; + }); + } + return webpackCompile(config, logStats, ServerlessError).catch(error => { errors.push(error); return error.stats; - }), + }); + }, { concurrency } ).then(stats => { if (errors.length) { diff --git a/tests/compile.test.js b/tests/compile.test.js index e308a0a69..945da5c13 100644 --- a/tests/compile.test.js +++ b/tests/compile.test.js @@ -98,6 +98,68 @@ describe('compile', () => { }); }); + it('should work with individual compile and webpack filesystem cache', () => { + const testWebpackConfig = { + cache: { + type: 'filesystem' + }, + // Below entry is inserted during validate() which happens before compile() + // Thus the assumed value + entry: { + 'function-name/handler': './function-name/handler.js' + } + }; + const multiStats = { + stats: [ + { + compilation: { + errors: [], + compiler: { + outputPath: 'statsMock-outputPath' + }, + modules: [] + }, + toString: sandbox.stub().returns('testStats'), + hasErrors: _.constant(false) + } + ] + }; + module.webpackConfig = testWebpackConfig; + module.configuration = { concurrency: 1 }; + module.serverless.service.package = { + individually: true + }; + module.entryFunctions = [ + { + handlerFile: 'function-name/handler', + funcName: 'function-name', + func: { + handler: 'function-name/handler.handler', + name: 'service-stage-function-name' + }, + entry: { + key: 'function-name/handler', + value: './function-name/handler.js' + } + } + ]; + webpackMock.compilerMock.run.reset(); + webpackMock.compilerMock.run.yields(null, multiStats); + return expect(module.compile()).to.be.fulfilled.then(() => { + expect(webpackMock).to.have.been.calledWith({ + cache: { + type: 'filesystem', + name: 'service-stage-function-name' + }, + entry: { + 'function-name/handler': './function-name/handler.js' + } + }); + expect(webpackMock.compilerMock.run).to.have.been.calledOnce; + return null; + }); + }); + it('should work with concurrent compile', () => { const testWebpackConfig = ['testconfig', 'testconfig2']; const multiStats = { @@ -129,6 +191,101 @@ describe('compile', () => { }); }); + it('should concurrently work with individual compile and webpack filesystem cache', () => { + const testWebpackConfig = [ + { + cache: { + type: 'filesystem' + }, + // Below entry is inserted during validate() which happens before compile() + // Thus the assumed value + entry: { + 'function-name-1/handler': './function-name-1/handler.js' + } + }, + { + cache: { + type: 'filesystem' + }, + // Below entry is inserted during validate() which happens before compile() + // Thus the assumed value + entry: { + 'function-name-2/handler': './function-name-2/handler.js' + } + } + ]; + const multiStats = { + stats: [ + { + compilation: { + errors: [], + compiler: { + outputPath: 'statsMock-outputPath' + }, + modules: [] + }, + toString: sandbox.stub().returns('testStats'), + hasErrors: _.constant(false) + } + ] + }; + module.webpackConfig = testWebpackConfig; + module.configuration = { concurrency: 2 }; + module.serverless.service.package = { + individually: true + }; + module.entryFunctions = [ + { + handlerFile: 'function-name-1/handler', + funcName: 'function-name-1', + func: { + handler: 'function-name-1/handler.handler', + name: 'service-stage-function-name-1' + }, + entry: { + key: 'function-name-1/handler', + value: './function-name-1/handler.js' + } + }, + { + handlerFile: 'function-name-2/handler', + funcName: 'function-name-2', + func: { + handler: 'function-name-2/handler.handler', + name: 'service-stage-function-name-2' + }, + entry: { + key: 'function-name-2/handler', + value: './function-name-2/handler.js' + } + } + ]; + webpackMock.compilerMock.run.reset(); + webpackMock.compilerMock.run.yields(null, multiStats); + return expect(module.compile()).to.be.fulfilled.then(() => { + expect(webpackMock).to.have.been.calledWith({ + cache: { + type: 'filesystem', + name: 'service-stage-function-name-1' + }, + entry: { + 'function-name-1/handler': './function-name-1/handler.js' + } + }); + expect(webpackMock).to.have.been.calledWith({ + cache: { + type: 'filesystem', + name: 'service-stage-function-name-2' + }, + entry: { + 'function-name-2/handler': './function-name-2/handler.js' + } + }); + expect(webpackMock.compilerMock.run).to.have.been.calledTwice; + return null; + }); + }); + it('should use correct stats option', () => { const testWebpackConfig = { stats: 'minimal' From 3e96143f6c5a441a9f44b2c7a99f56537471a47d Mon Sep 17 00:00:00 2001 From: hieuunguyeen Date: Tue, 29 Mar 2022 17:38:38 +0300 Subject: [PATCH 2/2] Convert tests to jest dialect --- tests/compile.test.js | 82 +++++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 39 deletions(-) diff --git a/tests/compile.test.js b/tests/compile.test.js index 945da5c13..dab93c989 100644 --- a/tests/compile.test.js +++ b/tests/compile.test.js @@ -119,7 +119,7 @@ describe('compile', () => { }, modules: [] }, - toString: sandbox.stub().returns('testStats'), + toString: jest.fn().mockReturnValue('testStats'), hasErrors: _.constant(false) } ] @@ -143,21 +143,23 @@ describe('compile', () => { } } ]; - webpackMock.compilerMock.run.reset(); - webpackMock.compilerMock.run.yields(null, multiStats); - return expect(module.compile()).to.be.fulfilled.then(() => { - expect(webpackMock).to.have.been.calledWith({ - cache: { - type: 'filesystem', - name: 'service-stage-function-name' - }, - entry: { - 'function-name/handler': './function-name/handler.js' - } + webpackMock.compilerMock.run.mockClear(); + webpackMock.compilerMock.run.mockImplementation(cb => cb(null, multiStats)); + return expect(module.compile()) + .resolves.toBeUndefined() + .then(() => { + expect(webpackMock).toHaveBeenCalledWith({ + cache: { + type: 'filesystem', + name: 'service-stage-function-name' + }, + entry: { + 'function-name/handler': './function-name/handler.js' + } + }); + expect(webpackMock.compilerMock.run).toHaveBeenCalledTimes(1); + return null; }); - expect(webpackMock.compilerMock.run).to.have.been.calledOnce; - return null; - }); }); it('should work with concurrent compile', () => { @@ -224,7 +226,7 @@ describe('compile', () => { }, modules: [] }, - toString: sandbox.stub().returns('testStats'), + toString: jest.fn().mockReturnValue('testStats'), hasErrors: _.constant(false) } ] @@ -260,30 +262,32 @@ describe('compile', () => { } } ]; - webpackMock.compilerMock.run.reset(); - webpackMock.compilerMock.run.yields(null, multiStats); - return expect(module.compile()).to.be.fulfilled.then(() => { - expect(webpackMock).to.have.been.calledWith({ - cache: { - type: 'filesystem', - name: 'service-stage-function-name-1' - }, - entry: { - 'function-name-1/handler': './function-name-1/handler.js' - } - }); - expect(webpackMock).to.have.been.calledWith({ - cache: { - type: 'filesystem', - name: 'service-stage-function-name-2' - }, - entry: { - 'function-name-2/handler': './function-name-2/handler.js' - } + webpackMock.compilerMock.run.mockClear(); + webpackMock.compilerMock.run.mockImplementation(cb => cb(null, multiStats)); + return expect(module.compile()) + .resolves.toBeUndefined() + .then(() => { + expect(webpackMock).toHaveBeenCalledWith({ + cache: { + type: 'filesystem', + name: 'service-stage-function-name-1' + }, + entry: { + 'function-name-1/handler': './function-name-1/handler.js' + } + }); + expect(webpackMock).toHaveBeenCalledWith({ + cache: { + type: 'filesystem', + name: 'service-stage-function-name-2' + }, + entry: { + 'function-name-2/handler': './function-name-2/handler.js' + } + }); + expect(webpackMock.compilerMock.run).toHaveBeenCalledTimes(2); + return null; }); - expect(webpackMock.compilerMock.run).to.have.been.calledTwice; - return null; - }); }); it('should use correct stats option', () => {