Repository: serverless-heaven/serverless-webpack
Pull request #264 (2017-10-30 00:19:36)

Exclude node_modules completely if deploying to google cloud functions, as GCF installs package.json.
<!--
1. Do not remove any section of the template. If something is not applicable leave it empty but leave it in the PR
2. Please follow the template, otherwise we'll have to ask you to update it and it will take longer until your PR is merged
-->

## Exclude node_modules completely if deploying to google cloud functions, as GCF installs package.json.

<!--
Briefly describe the feature if no issue exists for this PR. If possible only
submit PRs for existing issues. If the PR is trivial (like doc changes or simple
code fixes) it can be submitted without a related issue, but as soon as it adds
or changes functionality, a related issue should be present.
-->

## Added a check to see if the provider is Google

<!--
If this is a nontrivial change please briefly describe your implementation so its easy for us to understand and review your code.
-->

## How can we verify it:

<!--
Add any applicable config, commands, screenshots or other resources
to make it easy for us to verify this works. The easier you make it for us
to review a PR, the faster we can review and merge it.

Examples:
* Step by step description, how to verify
* Screenshots - Showing the difference between your output and the master
* Other - Anything else that comes to mind to help us evaluate
-->

## Todos:

- [x] Write tests
- [ ] Write documentation
- [x] Fix linting errors
- [x] Make sure code coverage hasn't dropped
- [ ] Provide verification config / commands / resources
- [x] Enable "Allow edits from maintainers" for this PR
- [x] Update the messages below

***Is this ready for review?:*** YES
***Is it a breaking change?:*** NO



Patch:
diff --git a/lib/packExternalModules.js b/lib/packExternalModules.js
index 7b88e7c..2c5b330 100644
--- a/lib/packExternalModules.js
+++ b/lib/packExternalModules.js
@@ -291,7 +291,12 @@ module.exports = {
         addModulesToPackageJson(prodModules, modulePackage);
         this.serverless.utils.writeFileSync(modulePackageJson, JSON.stringify(modulePackage, null, 2));
 
-        // Copy modules
+        // GOOGLE: Copy modules only if not google-cloud-functions
+        //         GCF Auto installs the package json
+        if (_.get(this.serverless, 'service.provider.name') === 'google') {
+          return BbPromise.resolve();
+        }
+
         const startCopy = _.now();
         return BbPromise.fromCallback(callback => fse.copy(path.join(compositeModulePath, 'node_modules'), path.join(modulePath, 'node_modules'), callback))
         .tap(() => this.options.verbose && this.serverless.cli.log(`Copy modules: ${modulePath} [${_.now() - startCopy} ms]`))


Test patch:
diff --git a/tests/packExternalModules.test.js b/tests/packExternalModules.test.js
index 2188905..049772d 100644
--- a/tests/packExternalModules.test.js
+++ b/tests/packExternalModules.test.js
@@ -212,6 +212,53 @@ describe('packExternalModules', () => {
       ]));
     });
 
+    it('should skip module copy for Google provider', () => {
+      const expectedCompositePackageJSON = {
+        name: 'test-service',
+        version: '1.0.0',
+        description: 'Packaged externals for test-service',
+        private: true,
+        dependencies: {
+          '@scoped/vendor': '1.0.0',
+          uuid: '^5.4.1',
+          bluebird: '^3.4.0'
+        }
+      };
+      const expectedPackageJSON = {
+        dependencies: {
+          '@scoped/vendor': '1.0.0',
+          uuid: '^5.4.1',
+          bluebird: '^3.4.0'
+        }
+      };
+
+      _.set(serverless, 'service.provider.name', 'google');
+      module.webpackOutputPath = 'outputPath';
+      fsExtraMock.pathExists.yields(null, false);
+      fsExtraMock.copy.yields();
+      childProcessMock.exec.onFirstCall().yields(null, '{}', '');
+      childProcessMock.exec.onSecondCall().yields(null, '', '');
+      childProcessMock.exec.onThirdCall().yields();
+      module.compileStats = stats;
+      return expect(module.packExternalModules()).to.be.fulfilled
+      .then(() => BbPromise.all([
+        // The module package JSON and the composite one should have been stored
+        expect(writeFileSyncStub).to.have.been.calledTwice,
+        expect(writeFileSyncStub.firstCall.args[1]).to.equal(JSON.stringify(expectedCompositePackageJSON, null, 2)),
+        expect(writeFileSyncStub.secondCall.args[1]).to.equal(JSON.stringify(expectedPackageJSON, null, 2)),
+        // The modules should have been copied
+        expect(fsExtraMock.copy).to.have.not.been.called,
+        // npm ls and npm prune should have been called
+        expect(childProcessMock.exec).to.have.been.calledTwice,
+        expect(childProcessMock.exec.firstCall).to.have.been.calledWith(
+          'npm ls -prod -json -depth=1'
+        ),
+        expect(childProcessMock.exec.secondCall).to.have.been.calledWith(
+          'npm install'
+        )
+      ]));
+    });
+
     it('should reject if npm install fails', () => {
       module.webpackOutputPath = 'outputPath';
       fsExtraMock.pathExists.yields(null, false);