diff --git a/index.js b/index.js index 326669c47..e370bbebf 100644 --- a/index.js +++ b/index.js @@ -81,7 +81,7 @@ class ServerlessWebpack { }, package: { type: 'entrypoint', - lifecycleEvents: [ 'packExternalModules', 'packageModules' ] + lifecycleEvents: [ 'packExternalModules', 'packageModules', 'copyExistingArtifacts' ] } } } @@ -91,7 +91,7 @@ class ServerlessWebpack { 'before:package:createDeploymentArtifacts': () => BbPromise.bind(this) .then(() => this.serverless.pluginManager.spawn('webpack:validate')) - .then(() => this.serverless.pluginManager.spawn('webpack:compile')) + .then(() => (this.skipCompile ? BbPromise.resolve() : this.serverless.pluginManager.spawn('webpack:compile'))) .then(() => this.serverless.pluginManager.spawn('webpack:package')), 'after:package:createDeploymentArtifacts': () => BbPromise.bind(this).then(this.cleanup), @@ -106,10 +106,6 @@ class ServerlessWebpack { 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'); }) @@ -159,6 +155,8 @@ class ServerlessWebpack { 'webpack:package:packageModules': () => BbPromise.bind(this).then(this.packageModules), + 'webpack:package:copyExistingArtifacts': () => BbPromise.bind(this).then(this.copyExistingArtifacts), + 'before:offline:start': () => BbPromise.bind(this) .tap(() => { diff --git a/index.test.js b/index.test.js index ab0a03bcc..585e8b70a 100644 --- a/index.test.js +++ b/index.test.js @@ -133,6 +133,7 @@ describe('ServerlessWebpack', () => { sandbox.stub(slsw, 'watch').returns(BbPromise.resolve()); sandbox.stub(slsw, 'wpwatch').returns(BbPromise.resolve()); sandbox.stub(slsw, 'packExternalModules').returns(BbPromise.resolve()); + sandbox.stub(slsw, 'copyExistingArtifacts').returns(BbPromise.resolve()); sandbox.stub(slsw, 'prepareRun').returns(BbPromise.resolve()); sandbox.stub(slsw, 'watchRun').returns(BbPromise.resolve()); sandbox.stub(slsw, 'validate').returns(BbPromise.resolve()); @@ -145,6 +146,7 @@ describe('ServerlessWebpack', () => { beforeEach(() => { ServerlessWebpack.lib.webpack.isLocal = false; + slsw.skipCompile = false; }); after(() => { @@ -169,6 +171,20 @@ describe('ServerlessWebpack', () => { return null; }); }); + + it('should skip compile if requested', () => { + slsw.skipCompile = true; + return expect(slsw.hooks['before:package:createDeploymentArtifacts']()).to.be.fulfilled.then(() => { + 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:package' + ); + return null; + }); + }); } }, { @@ -237,7 +253,7 @@ describe('ServerlessWebpack', () => { }); it('should skip compile if requested', () => { - slsw.options.build = false; + slsw.skipCompile = true; 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'); @@ -361,6 +377,17 @@ describe('ServerlessWebpack', () => { }); } }, + { + name: 'webpack:package:copyExistingArtifacts', + test: () => { + it('should call copyExistingArtifacts', () => { + return expect(slsw.hooks['webpack:package:copyExistingArtifacts']()).to.be.fulfilled.then(() => { + expect(slsw.copyExistingArtifacts).to.have.been.calledOnce; + return null; + }); + }); + } + }, { name: 'before:offline:start', test: () => { diff --git a/lib/cleanup.js b/lib/cleanup.js index 63bfcc796..9173529ff 100644 --- a/lib/cleanup.js +++ b/lib/cleanup.js @@ -7,7 +7,7 @@ module.exports = { cleanup() { const webpackOutputPath = this.webpackOutputPath; - const keepOutputDirectory = this.configuration.keepOutputDirectory; + const keepOutputDirectory = this.keepOutputDirectory; if (!keepOutputDirectory) { this.options.verbose && this.serverless.cli.log(`Remove ${webpackOutputPath}`); if (this.serverless.utils.dirExistsSync(webpackOutputPath)) { diff --git a/lib/packExternalModules.js b/lib/packExternalModules.js index cd762a304..8ae24e6c1 100644 --- a/lib/packExternalModules.js +++ b/lib/packExternalModules.js @@ -228,6 +228,10 @@ module.exports = { * and performance. */ packExternalModules() { + if (this.skipCompile) { + return BbPromise.resolve(); + } + const stats = this.compileStats; const includes = this.configuration.includeModules; diff --git a/lib/packageModules.js b/lib/packageModules.js index 422af3893..5026f2c29 100644 --- a/lib/packageModules.js +++ b/lib/packageModules.js @@ -11,6 +11,8 @@ const semver = require('semver'); function setArtifactPath(funcName, func, artifactPath) { const version = this.serverless.getVersion(); + this.options.verbose && this.serverless.cli.log(`Setting artifact for function '${funcName}' to '${artifactPath}'`); + // Serverless changed the artifact path location in version 1.18 if (semver.lt(version, '1.18.0')) { func.artifact = artifactPath; @@ -26,7 +28,8 @@ function setArtifactPath(funcName, func, artifactPath) { function zip(directory, name) { const zip = archiver.create('zip'); // Create artifact in temp path and move it to the package path (if any) later - const artifactFilePath = path.join(this.serverless.config.servicePath, '.serverless', name); + // This allows us to persist the webpackOutputPath and re-use the compiled output + const artifactFilePath = path.join(this.webpackOutputPath, name); this.serverless.utils.writeFileDir(artifactFilePath); const output = fs.createWriteStream(artifactFilePath); @@ -69,13 +72,47 @@ function zip(directory, name) { }); } +function getArtifactLocations(name) { + const archiveName = `${name}.zip`; + + const webpackArtifact = path.join(this.webpackOutputPath, archiveName); + const serverlessArtifact = path.join('.serverless', archiveName); + + return { webpackArtifact, serverlessArtifact }; +} + +function copyArtifactByName(artifactName) { + const { webpackArtifact, serverlessArtifact } = getArtifactLocations.call(this, artifactName); + + // Make sure the destination dir exists + this.serverless.utils.writeFileDir(serverlessArtifact); + + fs.copyFileSync(webpackArtifact, serverlessArtifact); +} + +function setServiceArtifactPath(artifactPath) { + _.set(this.serverless, 'service.package.artifact', artifactPath); +} + +function isIndividialPackaging() { + return _.get(this.serverless, 'service.package.individually'); +} + +function getArtifactName(entryFunction) { + return `${entryFunction.funcName || this.serverless.service.getServiceObject().name}.zip`; +} + module.exports = { packageModules() { + if (this.skipCompile) { + return BbPromise.resolve(); + } + const stats = this.compileStats; return BbPromise.mapSeries(stats.stats, (compileStats, index) => { const entryFunction = _.get(this.entryFunctions, index, {}); - const filename = `${entryFunction.funcName || this.serverless.service.getServiceObject().name}.zip`; + const filename = getArtifactName.call(this, entryFunction); const modulePath = compileStats.compilation.compiler.outputPath; const startZip = _.now(); @@ -87,37 +124,52 @@ module.exports = { this.serverless.cli.log( `Zip ${_.isEmpty(entryFunction) ? 'service' : 'function'}: ${modulePath} [${_.now() - startZip} ms]` ) - ) - .then(artifactPath => { - if (_.get(this.serverless, 'service.package.individually')) { - setArtifactPath.call( - this, - entryFunction.funcName, - entryFunction.func, - path.relative(this.serverless.config.servicePath, artifactPath) - ); - } - return artifactPath; - }); - }).then(artifacts => { - if (!_.get(this.serverless, 'service.package.individually') && !_.isEmpty(artifacts)) { - // Set the service artifact to all functions - const allFunctionNames = this.serverless.service.getAllFunctions(); - _.forEach(allFunctionNames, funcName => { - const func = this.serverless.service.getFunction(funcName); - setArtifactPath.call(this, funcName, func, path.relative(this.serverless.config.servicePath, artifacts[0])); - }); - // For Google set the service artifact path - if (_.get(this.serverless, 'service.provider.name') === 'google') { - _.set( - this.serverless, - 'service.package.artifact', - path.relative(this.serverless.config.servicePath, artifacts[0]) - ); - } - } + ); + }); + }, + + copyExistingArtifacts() { + this.serverless.cli.log('Copying existing artifacts...'); + const allFunctionNames = this.serverless.service.getAllFunctions(); + + // Copy artifacts to package location + if (isIndividialPackaging.call(this)) { + _.forEach(allFunctionNames, funcName => copyArtifactByName.call(this, funcName)); + } else { + // Copy service packaged artifact + const serviceName = this.serverless.service.getServiceObject().name; + copyArtifactByName.call(this, serviceName); + } + + _.forEach(allFunctionNames, funcName => { + const func = this.serverless.service.getFunction(funcName); + + const archiveName = isIndividialPackaging.call(this) ? funcName : this.serverless.service.getServiceObject().name; - return null; + const { serverlessArtifact } = getArtifactLocations.call(this, archiveName); + setArtifactPath.call(this, funcName, func, serverlessArtifact); }); + + // Set artifact locations + if (isIndividialPackaging.call(this)) { + _.forEach(allFunctionNames, funcName => { + const func = this.serverless.service.getFunction(funcName); + + const archiveName = funcName; + + const { serverlessArtifact } = getArtifactLocations.call(this, archiveName); + setArtifactPath.call(this, funcName, func, serverlessArtifact); + }); + } else { + const archiveName = this.serverless.service.getServiceObject().name; + + const { serverlessArtifact } = getArtifactLocations.call(this, archiveName); + + if (_.get(this.serverless, 'service.provider.name') === 'google') { + setServiceArtifactPath.call(this, serverlessArtifact); + } + } + + return BbPromise.resolve(); } }; diff --git a/lib/validate.js b/lib/validate.js index 80c0eb784..b46d8532d 100644 --- a/lib/validate.js +++ b/lib/validate.js @@ -171,7 +171,9 @@ module.exports = { this.webpackConfig.output.path = path.join(this.serverless.config.servicePath, this.options.out); } - if (this.skipCompile) { + // Skip compilation with --no-build + if (this.options.build === false) { + this.skipCompile = true; this.serverless.cli.log('Skipping build and using existing compiled output'); if (!fse.pathExistsSync(this.webpackConfig.output.path)) { return BbPromise.reject(new this.serverless.classes.Error('No compiled output found')); diff --git a/tests/cleanup.test.js b/tests/cleanup.test.js index 4d9eda2d2..2be4cd3a2 100644 --- a/tests/cleanup.test.js +++ b/tests/cleanup.test.js @@ -55,8 +55,7 @@ describe('cleanup', () => { { serverless, options: {}, - webpackOutputPath: 'my/Output/Path', - configuration: {} + webpackOutputPath: 'my/Output/Path' }, baseModule ); @@ -96,7 +95,7 @@ describe('cleanup', () => { fseMock.removeSync.reset(); const configuredModule = _.assign({}, module, { - configuration: { keepOutputDirectory: true } + keepOutputDirectory: true }); return expect(configuredModule.cleanup()).to.be.fulfilled.then(() => { expect(dirExistsSyncStub).to.not.have.been.calledOnce; diff --git a/tests/mocks/fs.mock.js b/tests/mocks/fs.mock.js index 8590528a3..a9e06cea8 100644 --- a/tests/mocks/fs.mock.js +++ b/tests/mocks/fs.mock.js @@ -23,6 +23,7 @@ module.exports.create = sandbox => { readFileSync: sandbox.stub(), statSync: sinon.stub().returns(statMock), // Persistent stub writeFileSync: sandbox.stub(), + copyFileSync: sandbox.stub(), _streamMock: streamMock, _statMock: statMock diff --git a/tests/packExternalModules.test.js b/tests/packExternalModules.test.js index b1abd4305..236ea593b 100644 --- a/tests/packExternalModules.test.js +++ b/tests/packExternalModules.test.js @@ -334,6 +334,24 @@ describe('packExternalModules', () => { ); }); + it('should do nothing if skipCompile is true', () => { + module.configuration = new Configuration({ + webpack: { + includeModules: { + packagePath: path.join('locals', 'package.json') + } + } + }); + module.skipCompile = true; + return expect(module.packExternalModules()).to.be.fulfilled.then(() => + BbPromise.all([ + expect(fsExtraMock.copy).to.not.have.been.called, + expect(packagerFactoryMock.get).to.not.have.been.called, + expect(writeFileSyncStub).to.not.have.been.called + ]) + ); + }); + it('should copy needed package sections if available', () => { const originalPackageJSON = { name: 'test-service', diff --git a/tests/packageModules.test.js b/tests/packageModules.test.js index 0d5665bea..a1bd1a504 100644 --- a/tests/packageModules.test.js +++ b/tests/packageModules.test.js @@ -72,7 +72,8 @@ describe('packageModules', () => { module = _.assign( { serverless, - options: {} + options: {}, + webpackOutputPath: '.webpack' }, baseModule ); @@ -97,6 +98,18 @@ describe('packageModules', () => { ); }); + it('should do nothing if skipCompile is true', () => { + module.skipCompile = true; + return expect(module.packageModules()).to.be.fulfilled.then(() => + BbPromise.all([ + expect(archiverMock.create).to.not.have.been.called, + expect(writeFileDirStub).to.not.have.been.called, + expect(fsMock.createWriteStream).to.not.have.been.called, + expect(globMock.sync).to.not.have.been.called + ]) + ); + }); + describe('with service packaging', () => { beforeEach(() => { // Setup behavior for service packaging @@ -142,15 +155,9 @@ describe('packageModules', () => { fsMock._streamMock.on.withArgs('close').yields(); fsMock._statMock.isDirectory.returns(false); - const expectedArtifactPath = path.join('.serverless', 'test-service.zip'); - module.compileStats = stats; - return expect(module.packageModules()).to.be.fulfilled.then(() => - BbPromise.all([ - expect(func1).to.have.a.nested.property('package.artifact').that.equals(expectedArtifactPath), - expect(func2).to.have.a.nested.property('package.artifact').that.equals(expectedArtifactPath) - ]) - ); + + return expect(module.packageModules()).to.be.fulfilled.then(() => BbPromise.all([])); }); describe('with the Google provider', () => { @@ -207,12 +214,8 @@ describe('packageModules', () => { fsMock._streamMock.on.withArgs('close').yields(); fsMock._statMock.isDirectory.returns(false); - const expectedArtifactPath = path.join('.serverless', 'test-service.zip'); - module.compileStats = stats; - return expect(module.packageModules()).to.be.fulfilled.then(() => - expect(serverless.service).to.have.a.nested.property('package.artifact').that.equals(expectedArtifactPath) - ); + return expect(module.packageModules()).to.be.fulfilled; }); }); @@ -253,28 +256,14 @@ describe('packageModules', () => { fsMock._streamMock.on.withArgs('close').yields(); fsMock._statMock.isDirectory.returns(false); - const expectedArtifactPath = path.join('.serverless', 'test-service.zip'); - module.compileStats = stats; return BbPromise.each([ '1.18.1', '2.17.0', '10.15.3' ], version => { getVersionStub.returns(version); - return expect(module.packageModules()).to.be.fulfilled.then(() => - BbPromise.all([ - expect(func1).to.have.a.nested.property('package.artifact').that.equals(expectedArtifactPath), - expect(func2).to.have.a.nested.property('package.artifact').that.equals(expectedArtifactPath) - ]) - ); + return expect(module.packageModules()).to.be.fulfilled.then(() => BbPromise.all([])); }).then(() => BbPromise.each([ '1.17.0', '1.16.0-alpha', '1.15.3' ], version => { getVersionStub.returns(version); - return expect(module.packageModules()).to.be.fulfilled.then(() => - BbPromise.all([ - expect(func1).to.have.a.nested.property('artifact').that.equals(expectedArtifactPath), - expect(func2).to.have.a.nested.property('artifact').that.equals(expectedArtifactPath), - expect(func1).to.have.a.nested.property('package.disable').that.is.true, - expect(func2).to.have.a.nested.property('package.disable').that.is.true - ]) - ); + return expect(module.packageModules()).to.be.fulfilled.then(() => BbPromise.all([])); }) ); }); @@ -388,14 +377,232 @@ describe('packageModules', () => { fsMock._statMock.isDirectory.returns(false); module.compileStats = stats; - return expect(module.packageModules()).to.be.fulfilled.then(() => + + return expect(module.packageModules()).to.be.fulfilled; + }); + }); + }); + + describe('copyExistingArtifacts()', () => { + const allFunctions = [ 'func1', 'func2' ]; + const func1 = { + handler: 'src/handler1', + events: [] + }; + const func2 = { + handler: 'src/handler2', + events: [] + }; + + const entryFunctions = [ + { + handlerFile: 'src/handler1.js', + funcName: 'func1', + func: func1 + }, + { + handlerFile: 'src/handler2.js', + funcName: 'func2', + func: func2 + } + ]; + + describe('with service packaging', () => { + afterEach(() => { + fsMock.copyFileSync.resetHistory(); + }); + + beforeEach(() => { + _.set(module, 'entryFunctions', entryFunctions); + _.set(serverless.service.package, 'individually', false); + getVersionStub.returns('1.18.0'); + getServiceObjectStub.returns({ + name: 'test-service' + }); + getAllFunctionsStub.returns(allFunctions); + getFunctionStub.withArgs('func1').returns(func1); + getFunctionStub.withArgs('func2').returns(func2); + }); + + it('copies the artifact', () => { + const expectedArtifactSource = path.join('.webpack', 'test-service.zip'); + const expectedArtifactDestination = path.join('.serverless', 'test-service.zip'); + + return expect(module.copyExistingArtifacts()).to.be.fulfilled.then(() => + BbPromise.all([ + // Should copy the artifact into .serverless + expect(fsMock.copyFileSync).callCount(1), + expect(fsMock.copyFileSync).to.be.calledWith(expectedArtifactSource, expectedArtifactDestination), + + // Should set package artifact for each function to the single artifact + expect(func1) + .to.have.a.nested.property('package.artifact') + .that.equals(expectedArtifactDestination), + expect(func2) + .to.have.a.nested.property('package.artifact') + .that.equals(expectedArtifactDestination) + ]) + ); + }); + + it('should set the function artifact depending on the serverless version', () => { + // Test data + const stats = { + stats: [ + { + compilation: { + compiler: { + outputPath: '/my/Service/Path/.webpack/service' + } + } + } + ] + }; + const files = [ 'README.md', 'src/handler1.js', 'src/handler1.js.map', 'src/handler2.js', 'src/handler2.js.map' ]; + const allFunctions = [ 'func1', 'func2' ]; + const func1 = { + handler: 'src/handler1', + events: [] + }; + const func2 = { + handler: 'src/handler2', + events: [] + }; + // Serverless behavior + sandbox.stub(serverless.config, 'servicePath').value('/my/Service/Path'); + getServiceObjectStub.returns({ + name: 'test-service' + }); + getAllFunctionsStub.returns(allFunctions); + getFunctionStub.withArgs('func1').returns(func1); + getFunctionStub.withArgs('func2').returns(func2); + // Mock behavior + globMock.sync.returns(files); + fsMock._streamMock.on.withArgs('open').yields(); + fsMock._streamMock.on.withArgs('close').yields(); + fsMock._statMock.isDirectory.returns(false); + + const expectedArtifactPath = path.join('.serverless', 'test-service.zip'); + + module.compileStats = stats; + return BbPromise.each([ '1.18.1', '2.17.0', '10.15.3' ], version => { + getVersionStub.returns(version); + return expect(module.copyExistingArtifacts()).to.be.fulfilled.then(() => + BbPromise.all([ + expect(func1) + .to.have.a.nested.property('package.artifact') + .that.equals(expectedArtifactPath), + expect(func2) + .to.have.a.nested.property('package.artifact') + .that.equals(expectedArtifactPath) + ]) + ); + }).then(() => + BbPromise.each([ '1.17.0', '1.16.0-alpha', '1.15.3' ], version => { + getVersionStub.returns(version); + return expect(module.copyExistingArtifacts()).to.be.fulfilled.then(() => + BbPromise.all([ + expect(func1) + .to.have.a.nested.property('artifact') + .that.equals(expectedArtifactPath), + expect(func2) + .to.have.a.nested.property('artifact') + .that.equals(expectedArtifactPath), + expect(func1).to.have.a.nested.property('package.disable').that.is.true, + expect(func2).to.have.a.nested.property('package.disable').that.is.true + ]) + ); + }) + ); + }); + + describe('with the Google provider', () => { + let oldProviderName; + + beforeEach(() => { + oldProviderName = serverless.service.provider.name; + // Imitate Google provider + serverless.service.provider.name = 'google'; + }); + + afterEach(() => { + if (oldProviderName) { + serverless.service.provider.name = oldProviderName; + } else { + _.unset(serverless.service.provider, 'name'); + } + }); + + it('should set the service artifact path', () => { + // Test data + const allFunctions = [ 'func1', 'func2' ]; + const func1 = { + handler: 'handler1', + events: [] + }; + const func2 = { + handler: 'handler2', + events: [] + }; + sandbox.stub(serverless.config, 'servicePath').value('/my/Service/Path'); + getVersionStub.returns('1.18.0'); + getServiceObjectStub.returns({ + name: 'test-service' + }); + getAllFunctionsStub.returns(allFunctions); + getFunctionStub.withArgs('func1').returns(func1); + getFunctionStub.withArgs('func2').returns(func2); + // Mock behavior + // fsMock._streamMock.on.withArgs('open').yields(); + // fsMock._streamMock.on.withArgs('close').yields(); + // fsMock._statMock.isDirectory.returns(false); + + const expectedArtifactPath = path.join('.serverless', 'test-service.zip'); + + return expect(module.copyExistingArtifacts()).to.be.fulfilled.then(() => + expect(serverless.service) + .to.have.a.nested.property('package.artifact') + .that.equals(expectedArtifactPath) + ); + }); + }); + }); + + describe('with individual packaging', () => { + afterEach(() => { + fsMock.copyFileSync.resetHistory(); + }); + + beforeEach(() => { + _.set(module, 'entryFunctions', entryFunctions); + _.set(serverless.service.package, 'individually', true); + getVersionStub.returns('1.18.0'); + getServiceObjectStub.returns({ + name: 'test-service' + }); + getAllFunctionsStub.returns(allFunctions); + getFunctionStub.withArgs('func1').returns(func1); + getFunctionStub.withArgs('func2').returns(func2); + }); + + it('copies each artifact', () => { + const expectedFunc1Destination = path.join('.serverless', 'func1.zip'); + const expectedFunc2Destination = path.join('.serverless', 'func2.zip'); + + return expect(module.copyExistingArtifacts()).to.be.fulfilled.then(() => BbPromise.all([ + // Should copy an artifact per function into .serverless + expect(fsMock.copyFileSync).callCount(2), + expect(fsMock.copyFileSync).to.be.calledWith(path.join('.webpack', 'func1.zip'), expectedFunc1Destination), + expect(fsMock.copyFileSync).to.be.calledWith(path.join('.webpack', 'func2.zip'), expectedFunc2Destination), + + // Should set package artifact locations expect(func1) .to.have.a.nested.property('package.artifact') - .that.equals(path.join('.serverless', 'func1.zip')), + .that.equals(expectedFunc1Destination), expect(func2) .to.have.a.nested.property('package.artifact') - .that.equals(path.join('.serverless', 'func2.zip')) + .that.equals(expectedFunc2Destination) ]) ); }); diff --git a/tests/validate.test.js b/tests/validate.test.js index 12c2ae89a..24c513aa9 100644 --- a/tests/validate.test.js +++ b/tests/validate.test.js @@ -960,6 +960,24 @@ describe('validate', () => { }); describe('with skipped builds', () => { + it('should set `skipComile` to true if `options.build` is false', () => { + const testConfig = { + entry: 'test', + output: {} + }; + const testServicePath = 'testpath'; + module.serverless.config.servicePath = testServicePath; + _.set(module.serverless.service, 'custom.webpack.config', testConfig); + + module.options.build = false; + + fsExtraMock.pathExistsSync.returns(true); + return module.validate().then(() => { + expect(module.skipCompile).to.be.true; + return null; + }); + }); + it('should keep output directory', () => { const testConfig = { entry: 'test', @@ -968,7 +986,7 @@ describe('validate', () => { const testServicePath = 'testpath'; module.serverless.config.servicePath = testServicePath; _.set(module.serverless.service, 'custom.webpack.config', testConfig); - module.skipCompile = true; + module.options.build = false; fsExtraMock.pathExistsSync.returns(true); return module.validate().then(() => { expect(module.keepOutputDirectory).to.be.true; @@ -984,7 +1002,7 @@ describe('validate', () => { const testServicePath = 'testpath'; module.serverless.config.servicePath = testServicePath; _.set(module.serverless.service, 'custom.webpack.config', testConfig); - module.skipCompile = true; + module.options.build = false; fsExtraMock.pathExistsSync.returns(false); return expect(module.validate()).to.be.rejectedWith(/No compiled output found/); });