diff --git a/__tests__/fixtures/node_modules/optional-dep-meta-parent/index.js b/__tests__/fixtures/node_modules/optional-dep-meta-parent/index.js new file mode 100644 index 0000000..7b388e4 --- /dev/null +++ b/__tests__/fixtures/node_modules/optional-dep-meta-parent/index.js @@ -0,0 +1 @@ +require('optional-dep-wont-be-found'); diff --git a/__tests__/fixtures/node_modules/optional-dep-meta-parent/package.json b/__tests__/fixtures/node_modules/optional-dep-meta-parent/package.json new file mode 100644 index 0000000..45ddaa0 --- /dev/null +++ b/__tests__/fixtures/node_modules/optional-dep-meta-parent/package.json @@ -0,0 +1,19 @@ +{ + "name": "optional-dep-meta-parent", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "peerDependencies": { + "optional-dep-wont-be-found": "^1" + }, + "peerDependenciesMeta": { + "optional-dep-wont-be-found": { + "optional": true + } + } +} diff --git a/__tests__/fixtures/optional-dep-meta-missing.js b/__tests__/fixtures/optional-dep-meta-missing.js new file mode 100644 index 0000000..8230a51 --- /dev/null +++ b/__tests__/fixtures/optional-dep-meta-missing.js @@ -0,0 +1 @@ +require('optional-dep-meta-parent'); diff --git a/__tests__/get-dependency-list.js b/__tests__/get-dependency-list.js index 15f488d..38641dd 100644 --- a/__tests__/get-dependency-list.js +++ b/__tests__/get-dependency-list.js @@ -83,6 +83,17 @@ test('should handle requires to a missing optionalDependency listed in dependenc t.true(log.called); }); +test('should handle requires to a missing peerDependency listed in peerDependenciesMeta as optional', (t) => { + const fileName = path.join(__dirname, 'fixtures', 'optional-dep-meta-missing.js'); + const log = sinon.stub(); + + const list = getDependencyList(fileName, Object.assign({ cli: { log } }, serverless)); + + t.true(list.some(item => item.indexOf(`optional-dep-meta-missing.js`) !== -1)); + t.true(list.some(item => item.indexOf(`node_modules/optional-dep-meta-parent/index.js`) !== -1)); + t.true(log.called); +}); + test('includes a dependency with peerDependencies', (t) => { const fileName = path.join(__dirname, 'fixtures', 'dep-with-peer.js'); diff --git a/get-dependency-list.js b/get-dependency-list.js index 507ba96..448c394 100644 --- a/get-dependency-list.js +++ b/get-dependency-list.js @@ -8,8 +8,9 @@ const readPkgUp = require('read-pkg-up'); const requirePackageName = require('require-package-name'); const glob = require('glob'); -function ignoreMissing(dependency, optional) { - return optional && dependency in optional; +function ignoreMissing(dependency, optional, peerDependenciesMeta) { + return optional && dependency in optional + || peerDependenciesMeta && dependency in peerDependenciesMeta && peerDependenciesMeta[dependency].optional; } module.exports = function(filename, serverless) { @@ -21,7 +22,7 @@ module.exports = function(filename, serverless) { const modulesToProcess = []; const localFilesToProcess = [filename]; - function handle(name, basedir, optionalDependencies) { + function handle(name, basedir, optionalDependencies, peerDependenciesMeta) { const moduleName = requirePackageName(name.replace(/\\/, '/')); try { @@ -35,7 +36,7 @@ module.exports = function(filename, serverless) { } } catch (e) { if (e.code === 'MODULE_NOT_FOUND') { - if (ignoreMissing(moduleName, optionalDependencies)) { + if (ignoreMissing(moduleName, optionalDependencies, peerDependenciesMeta)) { serverless.cli.log(`[serverless-plugin-include-dependencies]: WARNING missing optional dependency: ${moduleName}`); return null; } @@ -90,7 +91,7 @@ module.exports = function(filename, serverless) { if (dependencies) { Object.keys(dependencies).forEach(dependency => { - handle(dependency, currentModulePath, packageJson.optionalDependencies); + handle(dependency, currentModulePath, packageJson.optionalDependencies, packageJson.peerDependenciesMeta); }); } });