Skip to content

Commit 0164159

Browse files
authored
Merge pull request #347 from serverless-heaven/skip-build-with-invoke-local
Add --no-build switch for invoke local to use already compiled output
2 parents 321dd88 + 3e4cd0b commit 0164159

File tree

6 files changed

+76
-3
lines changed

6 files changed

+76
-3
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,19 @@ All options that are supported by invoke local can be used as usual:
422422

423423
> :exclamation: The old `webpack invoke` command has been disabled.
424424

425+
#### Run a function with an existing compiled output (--no-build)
426+
427+
On CI systems it is likely that you'll run multiple integration tests with `invoke local`
428+
sequentially. To improve this, you can do one compile and run multiple invokes on the
429+
compiled output - it is not necessary to compile again before each and every invoke.
430+
431+
```bash
432+
$ serverless webpack
433+
$ serverless invoke local --function <function-name-1> --no-build
434+
$ serverless invoke local --function <function-name-2> --no-build
435+
...
436+
```
437+
425438
### Run a function locally on source changes
426439

427440
Or to run a function every time the source files change use the `--watch` option

index.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,14 @@ class ServerlessWebpack {
112112
'before:invoke:local:invoke': () => BbPromise.bind(this)
113113
.then(() => {
114114
lib.webpack.isLocal = true;
115+
// --no-build override
116+
if (this.options.build === false) {
117+
this.skipCompile = true;
118+
}
119+
115120
return this.serverless.pluginManager.spawn('webpack:validate');
116121
})
117-
.then(() => this.serverless.pluginManager.spawn('webpack:compile'))
122+
.then(() => this.skipCompile ? BbPromise.resolve() : this.serverless.pluginManager.spawn('webpack:compile'))
118123
.then(this.prepareLocalInvoke),
119124

120125
'after:invoke:local:invoke': () => BbPromise.bind(this)
@@ -181,7 +186,7 @@ class ServerlessWebpack {
181186
lib.webpack.isLocal = true;
182187
})
183188
.then(this.prepareStepOfflineInvoke)
184-
.then(this.compile)
189+
.then(() => this.serverless.pluginManager.spawn('webpack:compile')),
185190
};
186191
}
187192
}

index.test.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,17 @@ describe('ServerlessWebpack', () => {
200200
return null;
201201
});
202202
});
203+
204+
it('should skip compile if requested', () => {
205+
slsw.options.build = false;
206+
return expect(slsw.hooks['before:invoke:local:invoke']()).to.be.fulfilled
207+
.then(() => {
208+
expect(slsw.serverless.pluginManager.spawn).to.have.been.calledOnce;
209+
expect(slsw.serverless.pluginManager.spawn).to.have.been.calledWithExactly('webpack:validate');
210+
expect(slsw.prepareLocalInvoke).to.have.been.calledOnce;
211+
return null;
212+
});
213+
});
203214
}
204215
},
205216
{
@@ -357,7 +368,8 @@ describe('ServerlessWebpack', () => {
357368
.then(() => {
358369
expect(ServerlessWebpack.lib.webpack.isLocal).to.be.true;
359370
expect(slsw.prepareStepOfflineInvoke).to.have.been.calledOnce;
360-
expect(slsw.compile).to.have.been.calledOnce;
371+
expect(slsw.serverless.pluginManager.spawn).to.have.been.calledOnce;
372+
expect(slsw.serverless.pluginManager.spawn).to.have.been.calledWithExactly('webpack:compile');
361373
return null;
362374
});
363375
});

lib/validate.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,15 @@ module.exports = {
143143
this.webpackConfig.output.path = path.join(this.serverless.config.servicePath, this.options.out);
144144
}
145145

146+
if (this.skipCompile) {
147+
this.serverless.cli.log('Skipping build and using existing compiled output');
148+
if (!fse.pathExistsSync(this.webpackConfig.output.path)) {
149+
return BbPromise.reject(new this.serverless.classes
150+
.Error('No compiled output found'));
151+
}
152+
this.keepOutputDirectory = true;
153+
}
154+
146155
if (!this.keepOutputDirectory) {
147156
this.options.verbose && this.serverless.cli.log(`Removing ${this.webpackConfig.output.path}`);
148157
fse.removeSync(this.webpackConfig.output.path);

tests/mocks/fs-extra.mock.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module.exports.create = sandbox => {
88
const fsExtraMock = {
99
copy: sandbox.stub().yields(),
1010
pathExists: sandbox.stub().yields(),
11+
pathExistsSync: sandbox.stub().returns(false),
1112
removeSync: sandbox.stub()
1213
};
1314

tests/validate.test.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ describe('validate', () => {
5353

5454
afterEach(() => {
5555
fsExtraMock.removeSync.reset();
56+
fsExtraMock.pathExistsSync.reset();
5657
sandbox.restore();
5758
});
5859

@@ -733,6 +734,38 @@ describe('validate', () => {
733734
});
734735
});
735736
});
737+
});
736738

739+
describe('with skipped builds', () => {
740+
it('should keep output directory', () => {
741+
const testConfig = {
742+
entry: 'test',
743+
output: {},
744+
};
745+
const testServicePath = 'testpath';
746+
module.serverless.config.servicePath = testServicePath;
747+
_.set(module.serverless.service, 'custom.webpack.config', testConfig);
748+
module.skipCompile = true;
749+
fsExtraMock.pathExistsSync.returns(true);
750+
return module
751+
.validate()
752+
.then(() => {
753+
expect(module.keepOutputDirectory).to.be.true;
754+
return null;
755+
});
756+
});
757+
758+
it('should fail without exiting output', () => {
759+
const testConfig = {
760+
entry: 'test',
761+
output: {},
762+
};
763+
const testServicePath = 'testpath';
764+
module.serverless.config.servicePath = testServicePath;
765+
_.set(module.serverless.service, 'custom.webpack.config', testConfig);
766+
module.skipCompile = true;
767+
fsExtraMock.pathExistsSync.returns(false);
768+
return expect(module.validate()).to.be.rejectedWith(/No compiled output found/);
769+
});
737770
});
738771
});

0 commit comments

Comments
 (0)