diff --git a/lib/compiler.js b/lib/compiler.js index 309dc05..dc08f6e 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -349,7 +349,7 @@ function findModelDefinitions(rootDir, sources) { function resolveAppPath(rootDir, relativePath, resolveOptions) { var resolvedPath = tryResolveAppPath(rootDir, relativePath, resolveOptions); - if (resolvedPath === undefined) { + if (resolvedPath === undefined && !resolveOptions.optional) { var err = new Error('Cannot resolve path "' + relativePath + '"'); err.code = 'PATH_NOT_FOUND'; throw err; @@ -469,7 +469,18 @@ function buildMiddlewareInstructions(rootDir, config) { allConfigs = [allConfigs]; allConfigs.forEach(function(config) { - var resolved = resolveMiddlewarePath(rootDir, middleware); + var resolved = resolveMiddlewarePath(rootDir, middleware, config); + + // resolved.sourceFile will be false-y if an optional middleware + // is not resolvable. + // if a non-optional middleware is not resolvable, it will throw + // at resolveAppPath() and not reach here + if (!resolved.sourceFile) { + return console.log('Middleware "%s" not found: %s', + middleware, + resolved.optional + ); + } var middlewareConfig = cloneDeep(config); middlewareConfig.phase = phase; @@ -507,14 +518,19 @@ function buildMiddlewareInstructions(rootDir, config) { }; } -function resolveMiddlewarePath(rootDir, middleware) { - var resolved = {}; +function resolveMiddlewarePath(rootDir, middleware, config) { + var resolved = { + optional: !!config.optional + }; var segments = middleware.split('#'); var pathName = segments[0]; var fragment = segments[1]; var middlewarePath = pathName; - var opts = { strict: true }; + var opts = { + strict: true, + optional: !!config.optional + }; if (fragment) { resolved.fragment = fragment; @@ -660,6 +676,9 @@ function fixFileExtension(filepath, files, onlyScriptsExportingFunction) { function resolveAppScriptPath(rootDir, relativePath, resolveOptions) { var resolvedPath = resolveAppPath(rootDir, relativePath, resolveOptions); + if (!resolvedPath) { + return false; + } var sourceDir = path.dirname(resolvedPath); var files = tryReadDir(sourceDir); var fixedFile = fixFileExtension(resolvedPath, files, false); diff --git a/test/compiler.test.js b/test/compiler.test.js index a0a3aad..4d11d8b 100644 --- a/test/compiler.test.js +++ b/test/compiler.test.js @@ -1564,6 +1564,20 @@ describe('compiler', function() { .to.throw(/path-does-not-exist/); }); + it('does not fail when an optional middleware cannot be resolved', + function() { + appdir.writeConfigFileSync('middleware.json', { + final: { + 'loopback/path-does-not-exist': { + optional: 'this middleware is optional' + } + } + }); + + expect(function() { boot.compile(appdir.PATH); }) + .to.not.throw(); + }); + it('fails when a module middleware fragment cannot be resolved', function() { appdir.writeConfigFileSync('middleware.json', { @@ -1578,6 +1592,20 @@ describe('compiler', function() { .to.throw(/path-does-not-exist/); }); + it('does not fail when an optional middleware fragment cannot be resolved', + function() { + appdir.writeConfigFileSync('middleware.json', { + final: { + 'loopback#path-does-not-exist': { + optional: 'this middleware is optional' + } + } + }); + + expect(function() { boot.compile(appdir.PATH); }) + .to.not.throw(); + }); + it('resolves paths relatively to appRootDir', function() { appdir.writeFileSync('my-middleware.js', ''); appdir.writeConfigFileSync('./middleware.json', {