From 7c21120ccbb6313d4462c22118ea4a9bd5261231 Mon Sep 17 00:00:00 2001 From: Todd Humphrey Date: Fri, 10 May 2019 16:47:11 -0400 Subject: [PATCH 1/7] lint / prettier --- index.js | 187 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 94 insertions(+), 93 deletions(-) diff --git a/index.js b/index.js index 3032c8cd83..3dd6748fcc 100644 --- a/index.js +++ b/index.js @@ -17,7 +17,6 @@ const packageModules = require('./lib/packageModules'); const lib = require('./lib'); class ServerlessWebpack { - static get lib() { return lib; } @@ -28,10 +27,10 @@ class ServerlessWebpack { if ( (_.has(this.serverless, 'service.custom.webpack') && - _.isString(this.serverless.service.custom.webpack) && - _.endsWith(this.serverless.service.custom.webpack, '.ts')) || + _.isString(this.serverless.service.custom.webpack) && + _.endsWith(this.serverless.service.custom.webpack, '.ts')) || (_.has(this.serverless, 'service.custom.webpack.webpackConfig') && - _.endsWith(this.serverless.service.custom.webpack.webpackConfig, '.ts')) + _.endsWith(this.serverless.service.custom.webpack.webpackConfig, '.ts')) ) { require('ts-node/register'); } @@ -48,15 +47,13 @@ class ServerlessWebpack { prepareLocalInvoke, runPluginSupport, prepareOfflineInvoke, - prepareStepOfflineInvoke + prepareStepOfflineInvoke, ); this.commands = { webpack: { usage: 'Bundle with Webpack', - lifecycleEvents: [ - 'webpack' - ], + lifecycleEvents: ['webpack'], options: { out: { usage: 'Path to output directory', @@ -66,127 +63,131 @@ class ServerlessWebpack { commands: { validate: { type: 'entrypoint', - lifecycleEvents: [ - 'validate', - ], + lifecycleEvents: ['validate'], }, compile: { type: 'entrypoint', - lifecycleEvents: [ - 'compile', - ], + lifecycleEvents: ['compile'], commands: { watch: { type: 'entrypoint', - lifecycleEvents: [ - 'compile' - ] - } - } + lifecycleEvents: ['compile'], + }, + }, }, package: { type: 'entrypoint', - lifecycleEvents: [ - 'packExternalModules', - 'packageModules' - ], + lifecycleEvents: [ 'packExternalModules', 'packageModules' ], }, }, }, }; this.hooks = { - 'before:package:createDeploymentArtifacts': () => BbPromise.bind(this) - .then(() => this.serverless.pluginManager.spawn('webpack:validate')) - .then(() => this.serverless.pluginManager.spawn('webpack:compile')) - .then(() => this.serverless.pluginManager.spawn('webpack:package')), - - 'after:package:createDeploymentArtifacts': () => BbPromise.bind(this) - .then(this.cleanup), - - 'before:deploy:function:packageFunction': () => BbPromise.bind(this) - .then(() => this.serverless.pluginManager.spawn('webpack:validate')) - .then(() => this.serverless.pluginManager.spawn('webpack:compile')) - .then(() => this.serverless.pluginManager.spawn('webpack:package')), - - 'before:invoke:local:invoke': () => BbPromise.bind(this) - .then(() => { - lib.webpack.isLocal = true; - // --no-build override - if (this.options.build === false) { - this.skipCompile = true; - } - - return this.serverless.pluginManager.spawn('webpack:validate'); - }) - .then(() => this.skipCompile ? BbPromise.resolve() : this.serverless.pluginManager.spawn('webpack:compile')) - .then(this.prepareLocalInvoke), + 'before:package:createDeploymentArtifacts': () => + BbPromise.bind(this) + .then(() => this.serverless.pluginManager.spawn('webpack:validate')) + .then(() => this.serverless.pluginManager.spawn('webpack:compile')) + .then(() => this.serverless.pluginManager.spawn('webpack:package')), + + 'after:package:createDeploymentArtifacts': () => + BbPromise.bind(this).then(this.cleanup), + + 'before:deploy:function:packageFunction': () => + BbPromise.bind(this) + .then(() => this.serverless.pluginManager.spawn('webpack:validate')) + .then(() => this.serverless.pluginManager.spawn('webpack:compile')) + .then(() => this.serverless.pluginManager.spawn('webpack:package')), + + 'before:invoke:local:invoke': () => + BbPromise.bind(this) + .then(() => { + lib.webpack.isLocal = true; + // --no-build override + if (this.options.build === false) { + this.skipCompile = true; + } - 'after:invoke:local:invoke': () => BbPromise.bind(this) - .then(() => { + return this.serverless.pluginManager.spawn('webpack:validate'); + }) + .then(() => + this.skipCompile + ? BbPromise.resolve() + : this.serverless.pluginManager.spawn('webpack:compile'), + ) + .then(this.prepareLocalInvoke), + + 'after:invoke:local:invoke': () => + BbPromise.bind(this).then(() => { if (this.options.watch && !this.isWatching) { return this.watch('invoke:local'); } return BbPromise.resolve(); }), - 'before:run:run': () => BbPromise.bind(this) - .then(() => _.set(this.serverless, 'service.package.individually', false)) - .then(() => this.serverless.pluginManager.spawn('webpack:validate')) - .then(() => this.serverless.pluginManager.spawn('webpack:compile')) - .then(this.packExternalModules) - .then(this.prepareRun), - - 'after:run:run': () => BbPromise.bind(this) - .then(() => { + 'before:run:run': () => + BbPromise.bind(this) + .then(() => + _.set(this.serverless, 'service.package.individually', false), + ) + .then(() => this.serverless.pluginManager.spawn('webpack:validate')) + .then(() => this.serverless.pluginManager.spawn('webpack:compile')) + .then(this.packExternalModules) + .then(this.prepareRun), + + 'after:run:run': () => + BbPromise.bind(this).then(() => { if (this.options.watch && !this.isWatching) { return this.watch(this.watchRun.bind(this)); } return BbPromise.resolve(); }), - 'webpack:webpack': () => BbPromise.bind(this) - .then(() => this.serverless.pluginManager.spawn('webpack:validate')) - .then(() => this.serverless.pluginManager.spawn('webpack:compile')) - .then(() => this.serverless.pluginManager.spawn('webpack:package')), + 'webpack:webpack': () => + BbPromise.bind(this) + .then(() => this.serverless.pluginManager.spawn('webpack:validate')) + .then(() => this.serverless.pluginManager.spawn('webpack:compile')) + .then(() => this.serverless.pluginManager.spawn('webpack:package')), /* * Internal webpack events (can be hooked by plugins) */ - 'webpack:validate:validate': () => BbPromise.bind(this) - .then(this.validate), + 'webpack:validate:validate': () => + BbPromise.bind(this).then(this.validate), - 'webpack:compile:compile': () => BbPromise.bind(this) - .then(this.compile), + 'webpack:compile:compile': () => BbPromise.bind(this).then(this.compile), 'webpack:compile:watch:compile': () => BbPromise.resolve(), - 'webpack:package:packExternalModules': () => BbPromise.bind(this) - .then(this.packExternalModules), - - 'webpack:package:packageModules': () => BbPromise.bind(this) - .then(this.packageModules), - - 'before:offline:start': () => BbPromise.bind(this) - .tap(() => { - lib.webpack.isLocal = true; - }) - .then(this.prepareOfflineInvoke) - .then(this.wpwatch), - - 'before:offline:start:init': () => BbPromise.bind(this) - .tap(() => { - lib.webpack.isLocal = true; - }) - .then(this.prepareOfflineInvoke) - .then(this.wpwatch), - - 'before:step-functions-offline:start': () => BbPromise.bind(this) - .tap(() => { - lib.webpack.isLocal = true; - }) - .then(this.prepareStepOfflineInvoke) - .then(() => this.serverless.pluginManager.spawn('webpack:compile')), + 'webpack:package:packExternalModules': () => + BbPromise.bind(this).then(this.packExternalModules), + + 'webpack:package:packageModules': () => + BbPromise.bind(this).then(this.packageModules), + + 'before:offline:start': () => + BbPromise.bind(this) + .tap(() => { + lib.webpack.isLocal = true; + }) + .then(this.prepareOfflineInvoke) + .then(this.wpwatch), + + 'before:offline:start:init': () => + BbPromise.bind(this) + .tap(() => { + lib.webpack.isLocal = true; + }) + .then(this.prepareOfflineInvoke) + .then(this.wpwatch), + + 'before:step-functions-offline:start': () => + BbPromise.bind(this) + .tap(() => { + lib.webpack.isLocal = true; + }) + .then(this.prepareStepOfflineInvoke) + .then(() => this.serverless.pluginManager.spawn('webpack:compile')), }; } } From d8035c20a83f9cacf2a629c4ba03d7336c967371 Mon Sep 17 00:00:00 2001 From: Todd Humphrey Date: Fri, 10 May 2019 17:01:33 -0400 Subject: [PATCH 2/7] add --no-build support for serverless offline start --- index.js | 20 ++++++++++++++------ index.test.js | 30 ++++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/index.js b/index.js index 3dd6748fcc..e317fe21b0 100644 --- a/index.js +++ b/index.js @@ -167,19 +167,27 @@ class ServerlessWebpack { 'before:offline:start': () => BbPromise.bind(this) - .tap(() => { - lib.webpack.isLocal = true; - }) - .then(this.prepareOfflineInvoke) - .then(this.wpwatch), + .tap(() => { + lib.webpack.isLocal = true; + // --no-build override + if (this.options.build === false) { + this.skipCompile = true; + } + }) + .then(this.prepareOfflineInvoke) + .then(() => (this.skipCompile ? BbPromise.resolve() : this.wpwatch())), 'before:offline:start:init': () => BbPromise.bind(this) .tap(() => { lib.webpack.isLocal = true; + // --no-build override + if (this.options.build === false) { + this.skipCompile = true; + } }) .then(this.prepareOfflineInvoke) - .then(this.wpwatch), + .then(() => (this.skipCompile ? BbPromise.resolve() : this.wpwatch())), 'before:step-functions-offline:start': () => BbPromise.bind(this) diff --git a/index.test.js b/index.test.js index 1e9c6ca97c..87826c7992 100644 --- a/index.test.js +++ b/index.test.js @@ -103,7 +103,7 @@ describe('ServerlessWebpack', () => { describe('hooks', () => { let slsw; - + before(() => { slsw = new ServerlessWebpack(serverless, {}); sandbox.stub(slsw, 'cleanup').returns(BbPromise.resolve()); @@ -336,6 +336,8 @@ describe('ServerlessWebpack', () => { name: 'before:offline:start', test: () => { it('should prepare offline', () => { + slsw.options.build = true; + slsw.skipCompile = false; return expect(slsw.hooks['before:offline:start']()).to.be.fulfilled .then(() => { expect(ServerlessWebpack.lib.webpack.isLocal).to.be.true; @@ -344,12 +346,25 @@ describe('ServerlessWebpack', () => { return null; }); }); + it('should skip compiling when requested', () => { + slsw.skipCompile = false; + slsw.options.build = false; + return expect(slsw.hooks['before:offline:start']()).to.be.fulfilled + .then(() => { + expect(ServerlessWebpack.lib.webpack.isLocal).to.be.true; + expect(slsw.prepareOfflineInvoke).to.have.been.calledOnce; + expect(slsw.wpwatch).to.not.have.been.called; + return null; + }); + }); } }, { name: 'before:offline:start:init', test: () => { it('should prepare offline', () => { + slsw.skipCompile = false; + slsw.options.build = true; return expect(slsw.hooks['before:offline:start:init']()).to.be.fulfilled .then(() => { expect(ServerlessWebpack.lib.webpack.isLocal).to.be.true; @@ -358,6 +373,17 @@ describe('ServerlessWebpack', () => { return null; }); }); + it('should skip compiling when requested', () => { + slsw.skipCompile = false; + slsw.options.build = false; + return expect(slsw.hooks['before:offline:start:init']()).to.be.fulfilled + .then(() => { + expect(ServerlessWebpack.lib.webpack.isLocal).to.be.true; + expect(slsw.prepareOfflineInvoke).to.have.been.calledOnce; + expect(slsw.wpwatch).to.not.have.been.called; + return null; + }); + }); } }, { @@ -379,7 +405,7 @@ describe('ServerlessWebpack', () => { it(`should expose hook ${hook.name}`, () => { expect(slsw).to.have.a.nested.property(`hooks.${hook.name}`); }); - + describe(hook.name, () => { hook.test(); }); From 9e2ec06456c67da4d4cbe7cc9bde2cd1fd3fbce0 Mon Sep 17 00:00:00 2001 From: Todd Humphrey Date: Fri, 10 May 2019 17:02:24 -0400 Subject: [PATCH 3/7] lint / prettier --- index.js | 26 +- index.test.js | 640 ++++++++++++++++++++++++++++---------------------- 2 files changed, 376 insertions(+), 290 deletions(-) diff --git a/index.js b/index.js index e317fe21b0..b28b897aaf 100644 --- a/index.js +++ b/index.js @@ -77,7 +77,7 @@ class ServerlessWebpack { }, package: { type: 'entrypoint', - lifecycleEvents: [ 'packExternalModules', 'packageModules' ], + lifecycleEvents: ['packExternalModules', 'packageModules'], }, }, }, @@ -167,15 +167,17 @@ class ServerlessWebpack { 'before:offline:start': () => BbPromise.bind(this) - .tap(() => { - lib.webpack.isLocal = true; - // --no-build override - if (this.options.build === false) { - this.skipCompile = true; - } - }) - .then(this.prepareOfflineInvoke) - .then(() => (this.skipCompile ? BbPromise.resolve() : this.wpwatch())), + .tap(() => { + lib.webpack.isLocal = true; + // --no-build override + if (this.options.build === false) { + this.skipCompile = true; + } + }) + .then(this.prepareOfflineInvoke) + .then(() => + this.skipCompile ? BbPromise.resolve() : this.wpwatch(), + ), 'before:offline:start:init': () => BbPromise.bind(this) @@ -187,7 +189,9 @@ class ServerlessWebpack { } }) .then(this.prepareOfflineInvoke) - .then(() => (this.skipCompile ? BbPromise.resolve() : this.wpwatch())), + .then(() => + this.skipCompile ? BbPromise.resolve() : this.wpwatch(), + ), 'before:step-functions-offline:start': () => BbPromise.bind(this) diff --git a/index.test.js b/index.test.js index 87826c7992..f4604e5c5b 100644 --- a/index.test.js +++ b/index.test.js @@ -27,7 +27,7 @@ describe('ServerlessWebpack', () => { sandbox = sinon.createSandbox(); - mockery.enable({ useCleanCache: true, warnOnUnregistered: false }); + mockery.enable({useCleanCache: true, warnOnUnregistered: false}); mockery.registerMock('ts-node/register', {}); mockery.registerMock('webpack', {}); @@ -39,10 +39,12 @@ describe('ServerlessWebpack', () => { serverless = new Serverless(); serverless.cli = { log: sandbox.stub(), - consoleLog: sandbox.stub() + consoleLog: sandbox.stub(), }; - sandbox.stub(serverless.pluginManager, 'spawn').returns(BbPromise.resolve()); + sandbox + .stub(serverless.pluginManager, 'spawn') + .returns(BbPromise.resolve()); }); afterEach(() => { @@ -58,10 +60,15 @@ describe('ServerlessWebpack', () => { it('should expose a lib object', () => { const lib = ServerlessWebpack.lib; expect(lib).to.be.an('object'); - expect(lib).to.have.a.property('entries').that.is.an('object').that.is.empty; - expect(lib).to.have.a.property('webpack').that.is.an('object').that.deep.equals({ - isLocal: false - }); + expect(lib) + .to.have.a.property('entries') + .that.is.an('object').that.is.empty; + expect(lib) + .to.have.a.property('webpack') + .that.is.an('object') + .that.deep.equals({ + isLocal: false, + }); }); describe('with a TS webpack configuration', () => { @@ -73,7 +80,11 @@ describe('ServerlessWebpack', () => { }); it('should support new config and register ts-node', () => { - _.set(serverless, 'service.custom.webpack.webpackConfig', 'webpack.config.ts'); + _.set( + serverless, + 'service.custom.webpack.webpackConfig', + 'webpack.config.ts', + ); new ServerlessWebpack(serverless, {}); expect(Module._load).to.have.been.calledOnce; expect(Module._load).to.have.been.calledWith('ts-node/register'); @@ -88,18 +99,23 @@ describe('ServerlessWebpack', () => { }); }); - _.forEach([ - 'commands.webpack', - 'commands.webpack.commands.validate', - 'commands.webpack.commands.compile', - 'commands.webpack.commands.compile.commands.watch', - 'commands.webpack.commands.package', - ], command => { - it(`should expose command/entrypoint ${_.last(_.split(command, '.'))}`, () => { - const slsw = new ServerlessWebpack(serverless, {}); - expect(slsw).to.have.a.nested.property(command); - }); - }); + _.forEach( + [ + 'commands.webpack', + 'commands.webpack.commands.validate', + 'commands.webpack.commands.compile', + 'commands.webpack.commands.compile.commands.watch', + 'commands.webpack.commands.package', + ], + (command) => { + it(`should expose command/entrypoint ${_.last( + _.split(command, '.'), + )}`, () => { + const slsw = new ServerlessWebpack(serverless, {}); + expect(slsw).to.have.a.nested.property(command); + }); + }, + ); describe('hooks', () => { let slsw; @@ -117,7 +133,9 @@ describe('ServerlessWebpack', () => { sandbox.stub(slsw, 'packageModules').returns(BbPromise.resolve()); sandbox.stub(slsw, 'prepareLocalInvoke').returns(BbPromise.resolve()); sandbox.stub(slsw, 'prepareOfflineInvoke').returns(BbPromise.resolve()); - sandbox.stub(slsw, 'prepareStepOfflineInvoke').returns(BbPromise.resolve()); + sandbox + .stub(slsw, 'prepareStepOfflineInvoke') + .returns(BbPromise.resolve()); }); beforeEach(() => { @@ -128,287 +146,351 @@ describe('ServerlessWebpack', () => { slsw.cleanup.restore(); }); - _.forEach([ - { - name: 'before:package:createDeploymentArtifacts', - test: () => { - it('should spawn validate, compile and package', () => { - return expect(slsw.hooks['before:package:createDeploymentArtifacts']()).to.be.fulfilled - .then(() => { - expect(slsw.serverless.pluginManager.spawn).to.have.been.calledThrice; - expect(slsw.serverless.pluginManager.spawn.firstCall).to.have.been.calledWithExactly('webpack:validate'); - expect(slsw.serverless.pluginManager.spawn.secondCall).to.have.been.calledWithExactly('webpack:compile'); - expect(slsw.serverless.pluginManager.spawn.thirdCall).to.have.been.calledWithExactly('webpack:package'); - return null; + _.forEach( + [ + { + name: 'before:package:createDeploymentArtifacts', + test: () => { + it('should spawn validate, compile and package', () => { + return expect( + slsw.hooks['before:package:createDeploymentArtifacts'](), + ).to.be.fulfilled.then(() => { + expect(slsw.serverless.pluginManager.spawn).to.have.been + .calledThrice; + expect( + slsw.serverless.pluginManager.spawn.firstCall, + ).to.have.been.calledWithExactly('webpack:validate'); + expect( + slsw.serverless.pluginManager.spawn.secondCall, + ).to.have.been.calledWithExactly('webpack:compile'); + expect( + slsw.serverless.pluginManager.spawn.thirdCall, + ).to.have.been.calledWithExactly('webpack:package'); + return null; + }); }); - }); - } - }, - { - name: 'after:package:createDeploymentArtifacts', - test: () => { - it('should call cleanup', () => { - return expect(slsw.hooks['after:package:createDeploymentArtifacts']()).to.be.fulfilled - .then(() => { - expect(slsw.cleanup).to.have.been.calledOnce; - return null; + }, + }, + { + name: 'after:package:createDeploymentArtifacts', + test: () => { + it('should call cleanup', () => { + return expect( + slsw.hooks['after:package:createDeploymentArtifacts'](), + ).to.be.fulfilled.then(() => { + expect(slsw.cleanup).to.have.been.calledOnce; + return null; + }); }); - }); - } - }, - { - name: 'before:deploy:function:packageFunction', - test: () => { - it('should spawn validate, compile and package', () => { - return expect(slsw.hooks['before:deploy:function:packageFunction']()).to.be.fulfilled - .then(() => { - expect(slsw.serverless.pluginManager.spawn).to.have.been.calledThrice; - expect(slsw.serverless.pluginManager.spawn.firstCall).to.have.been.calledWithExactly('webpack:validate'); - expect(slsw.serverless.pluginManager.spawn.secondCall).to.have.been.calledWithExactly('webpack:compile'); - expect(slsw.serverless.pluginManager.spawn.thirdCall).to.have.been.calledWithExactly('webpack:package'); - return null; + }, + }, + { + name: 'before:deploy:function:packageFunction', + test: () => { + it('should spawn validate, compile and package', () => { + return expect( + slsw.hooks['before:deploy:function:packageFunction'](), + ).to.be.fulfilled.then(() => { + expect(slsw.serverless.pluginManager.spawn).to.have.been + .calledThrice; + expect( + slsw.serverless.pluginManager.spawn.firstCall, + ).to.have.been.calledWithExactly('webpack:validate'); + expect( + slsw.serverless.pluginManager.spawn.secondCall, + ).to.have.been.calledWithExactly('webpack:compile'); + expect( + slsw.serverless.pluginManager.spawn.thirdCall, + ).to.have.been.calledWithExactly('webpack:package'); + return null; + }); }); - }); - } - }, - { - name: 'webpack:webpack', - test: () => { - it('should spawn validate, compile and package', () => { - return expect(slsw.hooks['webpack:webpack']()).to.be.fulfilled - .then(() => { - expect(slsw.serverless.pluginManager.spawn).to.have.been.calledThrice; - expect(slsw.serverless.pluginManager.spawn.firstCall).to.have.been.calledWithExactly('webpack:validate'); - expect(slsw.serverless.pluginManager.spawn.secondCall).to.have.been.calledWithExactly('webpack:compile'); - expect(slsw.serverless.pluginManager.spawn.thirdCall).to.have.been.calledWithExactly('webpack:package'); - return null; + }, + }, + { + name: 'webpack:webpack', + test: () => { + it('should spawn validate, compile and package', () => { + return expect( + slsw.hooks['webpack:webpack'](), + ).to.be.fulfilled.then(() => { + expect(slsw.serverless.pluginManager.spawn).to.have.been + .calledThrice; + expect( + slsw.serverless.pluginManager.spawn.firstCall, + ).to.have.been.calledWithExactly('webpack:validate'); + expect( + slsw.serverless.pluginManager.spawn.secondCall, + ).to.have.been.calledWithExactly('webpack:compile'); + expect( + slsw.serverless.pluginManager.spawn.thirdCall, + ).to.have.been.calledWithExactly('webpack:package'); + return null; + }); }); - }); - } - }, - { - name: 'before:invoke:local:invoke', - test: () => { - it('should prepare for local invoke', () => { - return expect(slsw.hooks['before:invoke:local:invoke']()).to.be.fulfilled - .then(() => { - expect(ServerlessWebpack.lib.webpack.isLocal).to.be.true; - expect(slsw.serverless.pluginManager.spawn).to.have.been.calledTwice; - expect(slsw.serverless.pluginManager.spawn.firstCall).to.have.been.calledWithExactly('webpack:validate'); - expect(slsw.serverless.pluginManager.spawn.secondCall).to.have.been.calledWithExactly('webpack:compile'); - expect(slsw.prepareLocalInvoke).to.have.been.calledOnce; - return null; + }, + }, + { + name: 'before:invoke:local:invoke', + test: () => { + it('should prepare for local invoke', () => { + return expect( + slsw.hooks['before:invoke:local:invoke'](), + ).to.be.fulfilled.then(() => { + expect(ServerlessWebpack.lib.webpack.isLocal).to.be.true; + expect(slsw.serverless.pluginManager.spawn).to.have.been + .calledTwice; + expect( + slsw.serverless.pluginManager.spawn.firstCall, + ).to.have.been.calledWithExactly('webpack:validate'); + expect( + slsw.serverless.pluginManager.spawn.secondCall, + ).to.have.been.calledWithExactly('webpack:compile'); + expect(slsw.prepareLocalInvoke).to.have.been.calledOnce; + return null; + }); }); - }); - it('should skip compile if requested', () => { - slsw.options.build = false; - return expect(slsw.hooks['before:invoke:local:invoke']()).to.be.fulfilled - .then(() => { - expect(slsw.serverless.pluginManager.spawn).to.have.been.calledOnce; - expect(slsw.serverless.pluginManager.spawn).to.have.been.calledWithExactly('webpack:validate'); - expect(slsw.prepareLocalInvoke).to.have.been.calledOnce; - return null; + it('should skip compile if requested', () => { + slsw.options.build = false; + return expect( + slsw.hooks['before:invoke:local:invoke'](), + ).to.be.fulfilled.then(() => { + expect(slsw.serverless.pluginManager.spawn).to.have.been + .calledOnce; + expect( + slsw.serverless.pluginManager.spawn, + ).to.have.been.calledWithExactly('webpack:validate'); + expect(slsw.prepareLocalInvoke).to.have.been.calledOnce; + return null; + }); }); - }); - } - }, - { - name: 'after:invoke:local:invoke', - test: () => { - it('should return if watch is disabled', () => { - slsw.options.watch = false; - return expect(slsw.hooks['after:invoke:local:invoke']()).to.be.fulfilled - .then(() => { - expect(slsw.watch).to.not.have.been.called; - return null; + }, + }, + { + name: 'after:invoke:local:invoke', + test: () => { + it('should return if watch is disabled', () => { + slsw.options.watch = false; + return expect( + slsw.hooks['after:invoke:local:invoke'](), + ).to.be.fulfilled.then(() => { + expect(slsw.watch).to.not.have.been.called; + return null; + }); }); - }); - it('should watch if enabled', () => { - slsw.options.watch = true; - return expect(slsw.hooks['after:invoke:local:invoke']()).to.be.fulfilled - .then(() => { - expect(slsw.watch).to.have.been.calledOnce; - expect(slsw.watch).to.have.been.calledWithExactly('invoke:local'); - return null; + it('should watch if enabled', () => { + slsw.options.watch = true; + return expect( + slsw.hooks['after:invoke:local:invoke'](), + ).to.be.fulfilled.then(() => { + expect(slsw.watch).to.have.been.calledOnce; + expect(slsw.watch).to.have.been.calledWithExactly( + 'invoke:local', + ); + return null; + }); }); - }); - } - }, - { - name: 'before:run:run', - test: () => { - it('should prepare for run', () => { - return expect(slsw.hooks['before:run:run']()).to.be.fulfilled - .then(() => { - expect(slsw.serverless.service.package.individually).to.be.false; - expect(slsw.serverless.pluginManager.spawn).to.have.been.calledTwice; - expect(slsw.serverless.pluginManager.spawn.firstCall).to.have.been.calledWithExactly('webpack:validate'); - expect(slsw.serverless.pluginManager.spawn.secondCall).to.have.been.calledWithExactly('webpack:compile'); - expect(slsw.packExternalModules).to.have.been.calledOnce; - expect(slsw.prepareRun).to.have.been.calledOnce; - return null; + }, + }, + { + name: 'before:run:run', + test: () => { + it('should prepare for run', () => { + return expect( + slsw.hooks['before:run:run'](), + ).to.be.fulfilled.then(() => { + expect(slsw.serverless.service.package.individually).to.be + .false; + expect(slsw.serverless.pluginManager.spawn).to.have.been + .calledTwice; + expect( + slsw.serverless.pluginManager.spawn.firstCall, + ).to.have.been.calledWithExactly('webpack:validate'); + expect( + slsw.serverless.pluginManager.spawn.secondCall, + ).to.have.been.calledWithExactly('webpack:compile'); + expect(slsw.packExternalModules).to.have.been.calledOnce; + expect(slsw.prepareRun).to.have.been.calledOnce; + return null; + }); }); - }); - } - }, - { - name: 'after:run:run', - test: () => { - it('should return if watch is disabled', () => { - slsw.options.watch = false; - return expect(slsw.hooks['after:run:run']()).to.be.fulfilled - .then(() => { - expect(slsw.watch).to.not.have.been.called; - return null; + }, + }, + { + name: 'after:run:run', + test: () => { + it('should return if watch is disabled', () => { + slsw.options.watch = false; + return expect(slsw.hooks['after:run:run']()).to.be.fulfilled.then( + () => { + expect(slsw.watch).to.not.have.been.called; + return null; + }, + ); }); - }); - it('should watch if enabled', () => { - slsw.options.watch = true; - return expect(slsw.hooks['after:run:run']()).to.be.fulfilled - .then(() => { - expect(slsw.watch).to.have.been.calledOnce; - expect(slsw.watch).to.have.been.calledOnce; - return null; + it('should watch if enabled', () => { + slsw.options.watch = true; + return expect(slsw.hooks['after:run:run']()).to.be.fulfilled.then( + () => { + expect(slsw.watch).to.have.been.calledOnce; + expect(slsw.watch).to.have.been.calledOnce; + return null; + }, + ); }); - }); - } - }, - { - name: 'webpack:validate:validate', - test: () => { - it('should call validate', () => { - return expect(slsw.hooks['webpack:validate:validate']()).to.be.fulfilled - .then(() => { - expect(slsw.validate).to.have.been.calledOnce; - return null; + }, + }, + { + name: 'webpack:validate:validate', + test: () => { + it('should call validate', () => { + return expect( + slsw.hooks['webpack:validate:validate'](), + ).to.be.fulfilled.then(() => { + expect(slsw.validate).to.have.been.calledOnce; + return null; + }); }); - }); - } - }, - { - name: 'webpack:compile:compile', - test: () => { - it('should call compile', () => { - return expect(slsw.hooks['webpack:compile:compile']()).to.be.fulfilled - .then(() => { - expect(slsw.compile).to.have.been.calledOnce; - return null; + }, + }, + { + name: 'webpack:compile:compile', + test: () => { + it('should call compile', () => { + return expect( + slsw.hooks['webpack:compile:compile'](), + ).to.be.fulfilled.then(() => { + expect(slsw.compile).to.have.been.calledOnce; + return null; + }); }); - }); - } - }, - { - name: 'webpack:compile:watch:compile', - test: () => { - it('should resolve', () => { - return expect(slsw.hooks['webpack:compile:watch:compile']()).to.be.fulfilled; - }); - } - }, - { - name: 'webpack:package:packExternalModules', - test: () => { - it('should call packExternalModules', () => { - return expect(slsw.hooks['webpack:package:packExternalModules']()).to.be.fulfilled - .then(() => { - expect(slsw.packExternalModules).to.have.been.calledOnce; - return null; + }, + }, + { + name: 'webpack:compile:watch:compile', + test: () => { + it('should resolve', () => { + return expect(slsw.hooks['webpack:compile:watch:compile']()).to.be + .fulfilled; }); - }); - } - }, - { - name: 'webpack:package:packageModules', - test: () => { - it('should call packageModules', () => { - return expect(slsw.hooks['webpack:package:packageModules']()).to.be.fulfilled - .then(() => { - expect(slsw.packageModules).to.have.been.calledOnce; - return null; + }, + }, + { + name: 'webpack:package:packExternalModules', + test: () => { + it('should call packExternalModules', () => { + return expect( + slsw.hooks['webpack:package:packExternalModules'](), + ).to.be.fulfilled.then(() => { + expect(slsw.packExternalModules).to.have.been.calledOnce; + return null; + }); }); - }); - } - }, - { - name: 'before:offline:start', - test: () => { - it('should prepare offline', () => { - slsw.options.build = true; - slsw.skipCompile = false; - return expect(slsw.hooks['before:offline:start']()).to.be.fulfilled - .then(() => { - expect(ServerlessWebpack.lib.webpack.isLocal).to.be.true; - expect(slsw.prepareOfflineInvoke).to.have.been.calledOnce; - expect(slsw.wpwatch).to.have.been.calledOnce; - return null; + }, + }, + { + name: 'webpack:package:packageModules', + test: () => { + it('should call packageModules', () => { + return expect( + slsw.hooks['webpack:package:packageModules'](), + ).to.be.fulfilled.then(() => { + expect(slsw.packageModules).to.have.been.calledOnce; + return null; + }); }); - }); - it('should skip compiling when requested', () => { - slsw.skipCompile = false; - slsw.options.build = false; - return expect(slsw.hooks['before:offline:start']()).to.be.fulfilled - .then(() => { - expect(ServerlessWebpack.lib.webpack.isLocal).to.be.true; - expect(slsw.prepareOfflineInvoke).to.have.been.calledOnce; - expect(slsw.wpwatch).to.not.have.been.called; - return null; + }, + }, + { + name: 'before:offline:start', + test: () => { + it('should prepare offline', () => { + slsw.options.build = true; + slsw.skipCompile = false; + return expect( + slsw.hooks['before:offline:start'](), + ).to.be.fulfilled.then(() => { + expect(ServerlessWebpack.lib.webpack.isLocal).to.be.true; + expect(slsw.prepareOfflineInvoke).to.have.been.calledOnce; + expect(slsw.wpwatch).to.have.been.calledOnce; + return null; + }); }); - }); - } - }, - { - name: 'before:offline:start:init', - test: () => { - it('should prepare offline', () => { - slsw.skipCompile = false; - slsw.options.build = true; - return expect(slsw.hooks['before:offline:start:init']()).to.be.fulfilled - .then(() => { - expect(ServerlessWebpack.lib.webpack.isLocal).to.be.true; - expect(slsw.prepareOfflineInvoke).to.have.been.calledOnce; - expect(slsw.wpwatch).to.have.been.calledOnce; - return null; + it('should skip compiling when requested', () => { + slsw.skipCompile = false; + slsw.options.build = false; + return expect( + slsw.hooks['before:offline:start'](), + ).to.be.fulfilled.then(() => { + expect(ServerlessWebpack.lib.webpack.isLocal).to.be.true; + expect(slsw.prepareOfflineInvoke).to.have.been.calledOnce; + expect(slsw.wpwatch).to.not.have.been.called; + return null; + }); }); - }); - it('should skip compiling when requested', () => { - slsw.skipCompile = false; - slsw.options.build = false; - return expect(slsw.hooks['before:offline:start:init']()).to.be.fulfilled - .then(() => { - expect(ServerlessWebpack.lib.webpack.isLocal).to.be.true; - expect(slsw.prepareOfflineInvoke).to.have.been.calledOnce; - expect(slsw.wpwatch).to.not.have.been.called; - return null; + }, + }, + { + name: 'before:offline:start:init', + test: () => { + it('should prepare offline', () => { + slsw.skipCompile = false; + slsw.options.build = true; + return expect( + slsw.hooks['before:offline:start:init'](), + ).to.be.fulfilled.then(() => { + expect(ServerlessWebpack.lib.webpack.isLocal).to.be.true; + expect(slsw.prepareOfflineInvoke).to.have.been.calledOnce; + expect(slsw.wpwatch).to.have.been.calledOnce; + return null; + }); }); - }); - } - }, - { - name: 'before:step-functions-offline:start', - test: () => { - it('should prepare offline', () => { - return expect(slsw.hooks['before:step-functions-offline:start']()).to.be.fulfilled - .then(() => { - expect(ServerlessWebpack.lib.webpack.isLocal).to.be.true; - expect(slsw.prepareStepOfflineInvoke).to.have.been.calledOnce; - expect(slsw.serverless.pluginManager.spawn).to.have.been.calledOnce; - expect(slsw.serverless.pluginManager.spawn).to.have.been.calledWithExactly('webpack:compile'); - return null; + it('should skip compiling when requested', () => { + slsw.skipCompile = false; + slsw.options.build = false; + return expect( + slsw.hooks['before:offline:start:init'](), + ).to.be.fulfilled.then(() => { + expect(ServerlessWebpack.lib.webpack.isLocal).to.be.true; + expect(slsw.prepareOfflineInvoke).to.have.been.calledOnce; + expect(slsw.wpwatch).to.not.have.been.called; + return null; + }); }); - }); - } - }, - ], hook => { - it(`should expose hook ${hook.name}`, () => { - expect(slsw).to.have.a.nested.property(`hooks.${hook.name}`); - }); + }, + }, + { + name: 'before:step-functions-offline:start', + test: () => { + it('should prepare offline', () => { + return expect( + slsw.hooks['before:step-functions-offline:start'](), + ).to.be.fulfilled.then(() => { + expect(ServerlessWebpack.lib.webpack.isLocal).to.be.true; + expect(slsw.prepareStepOfflineInvoke).to.have.been.calledOnce; + expect(slsw.serverless.pluginManager.spawn).to.have.been + .calledOnce; + expect( + slsw.serverless.pluginManager.spawn, + ).to.have.been.calledWithExactly('webpack:compile'); + return null; + }); + }); + }, + }, + ], + (hook) => { + it(`should expose hook ${hook.name}`, () => { + expect(slsw).to.have.a.nested.property(`hooks.${hook.name}`); + }); - describe(hook.name, () => { - hook.test(); - }); - }); + describe(hook.name, () => { + hook.test(); + }); + }, + ); }); }); From 4b5202fe163dd99ca7bb9fa0c5cded63029c0202 Mon Sep 17 00:00:00 2001 From: francisu Date: Thu, 15 Oct 2020 11:57:53 -0700 Subject: [PATCH 4/7] Update package-lock.json --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 4db7687cf3..25f1e054cd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4928,7 +4928,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "requires": { "brace-expansion": "^1.1.7" } From bef4239d4b043d46ae35386e9e2622650cb1ca6e Mon Sep 17 00:00:00 2001 From: francisu Date: Thu, 15 Oct 2020 13:45:28 -0700 Subject: [PATCH 5/7] Add support for --no-build when running with serverless offline --- index.js | 6 +++--- index.test.js | 48 +++++++++++++++++------------------------------- 2 files changed, 20 insertions(+), 34 deletions(-) diff --git a/index.js b/index.js index 0e7e473e78..b378c3fb06 100644 --- a/index.js +++ b/index.js @@ -51,7 +51,7 @@ class ServerlessWebpack { prepareLocalInvoke, runPluginSupport, prepareOfflineInvoke, - prepareStepOfflineInvoke, + prepareStepOfflineInvoke ); this.commands = { @@ -169,7 +169,7 @@ class ServerlessWebpack { } }) .then(this.prepareOfflineInvoke) - .then(this.skipCompile? BbPromise.resolve() : this.wpwatch), + .then(() => (this.skipCompile ? BbPromise.resolve() : this.wpwatch())), 'before:offline:start:init': () => BbPromise.bind(this) @@ -181,7 +181,7 @@ class ServerlessWebpack { } }) .then(this.prepareOfflineInvoke) - .then(this.skipCompile? BbPromise.resolve() : this.wpwatch), + .then(() => (this.skipCompile ? BbPromise.resolve() : this.wpwatch())), 'before:step-functions-offline:start': () => BbPromise.bind(this) diff --git a/index.test.js b/index.test.js index f0f277b182..ad77ffbb27 100644 --- a/index.test.js +++ b/index.test.js @@ -28,7 +28,7 @@ describe('ServerlessWebpack', () => { sandbox = sinon.createSandbox(); - mockery.enable({useCleanCache: true, warnOnUnregistered: false}); + mockery.enable({ useCleanCache: true, warnOnUnregistered: false }); mockery.registerMock('ts-node/register', {}); mockery.registerMock('webpack', {}); @@ -40,12 +40,10 @@ describe('ServerlessWebpack', () => { serverless = new Serverless(); serverless.cli = { log: sandbox.stub(), - consoleLog: sandbox.stub(), + consoleLog: sandbox.stub() }; - sandbox - .stub(serverless.pluginManager, 'spawn') - .returns(BbPromise.resolve()); + sandbox.stub(serverless.pluginManager, 'spawn').returns(BbPromise.resolve()); }); afterEach(() => { @@ -61,15 +59,10 @@ describe('ServerlessWebpack', () => { it('should expose a lib object', () => { const lib = ServerlessWebpack.lib; expect(lib).to.be.an('object'); - expect(lib) - .to.have.a.property('entries') - .that.is.an('object').that.is.empty; - expect(lib) - .to.have.a.property('webpack') - .that.is.an('object') - .that.deep.equals({ - isLocal: false, - }); + expect(lib).to.have.a.property('entries').that.is.an('object').that.is.empty; + expect(lib).to.have.a.property('webpack').that.is.an('object').that.deep.equals({ + isLocal: false + }); }); describe('with a TS webpack configuration', () => { @@ -81,11 +74,7 @@ describe('ServerlessWebpack', () => { }); it('should support new config and register ts-node', () => { - _.set( - serverless, - 'service.custom.webpack.webpackConfig', - 'webpack.config.ts', - ); + _.set(serverless, 'service.custom.webpack.webpackConfig', 'webpack.config.ts'); new ServerlessWebpack(serverless, {}); expect(Module._load).to.have.been.calledOnce; expect(Module._load).to.have.been.calledWith('ts-node/register'); @@ -96,7 +85,7 @@ describe('ServerlessWebpack', () => { _.set(serverless, 'service.custom.webpack.webpackConfig', 'webpack.config.ts'); - const badDeps = function() { + const badDeps = function () { new ServerlessWebpack(serverless, {}); }; @@ -151,9 +140,7 @@ describe('ServerlessWebpack', () => { sandbox.stub(slsw, 'packageModules').returns(BbPromise.resolve()); sandbox.stub(slsw, 'prepareLocalInvoke').returns(BbPromise.resolve()); sandbox.stub(slsw, 'prepareOfflineInvoke').returns(BbPromise.resolve()); - sandbox - .stub(slsw, 'prepareStepOfflineInvoke') - .returns(BbPromise.resolve()); + sandbox.stub(slsw, 'prepareStepOfflineInvoke').returns(BbPromise.resolve()); }); beforeEach(() => { @@ -251,6 +238,7 @@ describe('ServerlessWebpack', () => { it('should skip compile if requested', () => { slsw.options.build = false; + slsw.skipCompile = false; return expect(slsw.hooks['before:invoke:local:invoke']()).to.be.fulfilled.then(() => { expect(slsw.serverless.pluginManager.spawn).to.have.been.calledOnce; expect(slsw.serverless.pluginManager.spawn).to.have.been.calledWithExactly('webpack:validate'); @@ -378,6 +366,8 @@ describe('ServerlessWebpack', () => { name: 'before:offline:start', test: () => { it('should prepare offline', () => { + slsw.skipCompile = false; + slsw.options.build = true; return expect(slsw.hooks['before:offline:start']()).to.be.fulfilled.then(() => { expect(ServerlessWebpack.lib.webpack.isLocal).to.be.true; expect(slsw.prepareOfflineInvoke).to.have.been.calledOnce; @@ -388,22 +378,21 @@ describe('ServerlessWebpack', () => { it('should skip compiling when requested', () => { slsw.skipCompile = false; slsw.options.build = false; - return expect( - slsw.hooks['before:offline:start'](), - ).to.be.fulfilled.then(() => { + return expect(slsw.hooks['before:offline:start']()).to.be.fulfilled.then(() => { expect(ServerlessWebpack.lib.webpack.isLocal).to.be.true; expect(slsw.prepareOfflineInvoke).to.have.been.calledOnce; expect(slsw.wpwatch).to.not.have.been.called; return null; }); }); - } }, { name: 'before:offline:start:init', test: () => { it('should prepare offline', () => { + slsw.skipCompile = false; + slsw.options.build = true; return expect(slsw.hooks['before:offline:start:init']()).to.be.fulfilled.then(() => { expect(ServerlessWebpack.lib.webpack.isLocal).to.be.true; expect(slsw.prepareOfflineInvoke).to.have.been.calledOnce; @@ -414,16 +403,13 @@ describe('ServerlessWebpack', () => { it('should skip compiling when requested', () => { slsw.skipCompile = false; slsw.options.build = false; - return expect( - slsw.hooks['before:offline:start:init'](), - ).to.be.fulfilled.then(() => { + return expect(slsw.hooks['before:offline:start:init']()).to.be.fulfilled.then(() => { expect(ServerlessWebpack.lib.webpack.isLocal).to.be.true; expect(slsw.prepareOfflineInvoke).to.have.been.calledOnce; expect(slsw.wpwatch).to.not.have.been.called; return null; }); }); - } }, { From 26d8bda39833f327b0c22af1140dfe9547f97579 Mon Sep 17 00:00:00 2001 From: francisu Date: Thu, 15 Oct 2020 13:54:19 -0700 Subject: [PATCH 6/7] Formatting --- index.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.test.js b/index.test.js index ad77ffbb27..96fd1bca9e 100644 --- a/index.test.js +++ b/index.test.js @@ -85,7 +85,7 @@ describe('ServerlessWebpack', () => { _.set(serverless, 'service.custom.webpack.webpackConfig', 'webpack.config.ts'); - const badDeps = function () { + const badDeps = function() { new ServerlessWebpack(serverless, {}); }; From 781e9f6984db2682a67cc1a91e764205ca1cffd6 Mon Sep 17 00:00:00 2001 From: francisu Date: Thu, 15 Oct 2020 16:28:51 -0700 Subject: [PATCH 7/7] Doc update --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 8ba96577d0..9252e34939 100644 --- a/README.md +++ b/README.md @@ -620,6 +620,8 @@ e.g. a mounted volume in a Docker container, you can enable polling with the `--webpack-use-polling=