From 0a6c8516134f9f9114d9945d0c5782dc428535ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Bigio?= Date: Tue, 13 Oct 2015 10:38:23 -0700 Subject: [PATCH] Fail loud when module is not resolved correctly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: @​public We've been forgiving unresolved modules errors in the past but we've realized that doing so makes the codebase a bit unstable as people don't make sure to fix these errors. From now on we'll early fail and stop the packager when any module cannot be resolved (including assets) Reviewed By: @amasad Differential Revision: D2518076 fb-gh-sync-id: e170d95b905cc29afbe46e24b65425ddd887f77c --- .../DependencyGraph/ResolutionRequest.js | 77 +++++++++++++------ react-packager/src/Server/index.js | 4 +- 2 files changed, 57 insertions(+), 24 deletions(-) diff --git a/react-packager/src/DependencyResolver/DependencyGraph/ResolutionRequest.js b/react-packager/src/DependencyResolver/DependencyGraph/ResolutionRequest.js index dda09abe..e8396de6 100644 --- a/react-packager/src/DependencyResolver/DependencyGraph/ResolutionRequest.js +++ b/react-packager/src/DependencyResolver/DependencyGraph/ResolutionRequest.js @@ -65,7 +65,8 @@ class ResolutionRequest { }; const forgive = (error) => { - if (error.type !== 'UnableToResolveError') { + if (error.type !== 'UnableToResolveError' || + this._platform === 'ios') { throw error; } @@ -92,7 +93,7 @@ class ResolutionRequest { return this._resolveNodeDependency(fromModule, toModuleName) .then( cacheResult, - forgive + forgive, ); } @@ -193,12 +194,20 @@ class ResolutionRequest { path.relative(packageName, realModuleName) ); return this._tryResolve( - () => this._loadAsFile(potentialModulePath), - () => this._loadAsDir(potentialModulePath), + () => this._loadAsFile( + potentialModulePath, + fromModule, + toModuleName, + ), + () => this._loadAsDir(potentialModulePath, fromModule, toModuleName), ); } - throw new UnableToResolveError('Unable to resolve dependency'); + throw new UnableToResolveError( + fromModule, + toModuleName, + 'Unable to resolve dependency', + ); }); } @@ -218,8 +227,8 @@ class ResolutionRequest { path.join(path.dirname(fromModule.path), toModuleName); return this._redirectRequire(fromModule, potentialModulePath).then( realModuleName => this._tryResolve( - () => this._loadAsFile(realModuleName), - () => this._loadAsDir(realModuleName) + () => this._loadAsFile(realModuleName, fromModule, toModuleName), + () => this._loadAsDir(realModuleName, fromModule, toModuleName) ) ); } else { @@ -234,14 +243,18 @@ class ResolutionRequest { ); } - let p = Promise.reject(new UnableToResolveError('Node module not found')); + let p = Promise.reject(new UnableToResolveError( + fromModule, + toModuleName, + 'Node module not found', + )); searchQueue.forEach(potentialModulePath => { p = this._tryResolve( () => this._tryResolve( () => p, - () => this._loadAsFile(potentialModulePath), + () => this._loadAsFile(potentialModulePath, fromModule, toModuleName), ), - () => this._loadAsDir(potentialModulePath) + () => this._loadAsDir(potentialModulePath, fromModule, toModuleName) ); }); @@ -250,12 +263,16 @@ class ResolutionRequest { } } - _loadAsFile(potentialModulePath) { + _loadAsFile(potentialModulePath, fromModule, toModule) { return Promise.resolve().then(() => { if (this._helpers.isAssetFile(potentialModulePath)) { const dirname = path.dirname(potentialModulePath); if (!this._fastfs.dirExists(dirname)) { - throw new UnableToResolveError(`Directory ${dirname} doesn't exist`); + throw new UnableToResolveError( + fromModule, + toModule, + `Directory ${dirname} doesn't exist`, + ); } const {name, type} = getAssetDataFromName(potentialModulePath); @@ -289,17 +306,25 @@ class ResolutionRequest { } else if (this._fastfs.fileExists(potentialModulePath + '.json')) { file = potentialModulePath + '.json'; } else { - throw new UnableToResolveError(`File ${potentialModulePath} doesnt exist`); + throw new UnableToResolveError( + fromModule, + toModule, + `File ${potentialModulePath} doesnt exist`, + ); } return this._moduleCache.getModule(file); }); } - _loadAsDir(potentialDirPath) { + _loadAsDir(potentialDirPath, fromModule, toModule) { return Promise.resolve().then(() => { if (!this._fastfs.dirExists(potentialDirPath)) { - throw new UnableToResolveError(`Invalid directory ${potentialDirPath}`); + throw new UnableToResolveError( + fromModule, + toModule, + `Invalid directory ${potentialDirPath}`, + ); } const packageJsonPath = path.join(potentialDirPath, 'package.json'); @@ -307,13 +332,17 @@ class ResolutionRequest { return this._moduleCache.getPackage(packageJsonPath) .getMain().then( (main) => this._tryResolve( - () => this._loadAsFile(main), - () => this._loadAsDir(main) + () => this._loadAsFile(main, fromModule, toModule), + () => this._loadAsDir(main, fromModule, toModule) ) ); } - return this._loadAsFile(path.join(potentialDirPath, 'index')); + return this._loadAsFile( + path.join(potentialDirPath, 'index'), + fromModule, + toModule, + ); }); } @@ -328,17 +357,20 @@ function resolutionHash(modulePath, depName) { } -function UnableToResolveError() { +function UnableToResolveError(fromModule, toModule, message) { Error.call(this); Error.captureStackTrace(this, this.constructor); - var msg = util.format.apply(util, arguments); - this.message = msg; + this.message = util.format( + 'Unable to resolve module %s from %s: %s', + toModule, + fromModule.path, + message, + ); this.type = this.name = 'UnableToResolveError'; } util.inherits(UnableToResolveError, Error); - function normalizePath(modulePath) { if (path.sep === '/') { modulePath = path.normalize(modulePath); @@ -349,5 +381,4 @@ function normalizePath(modulePath) { return modulePath.replace(/\/$/, ''); } - module.exports = ResolutionRequest; diff --git a/react-packager/src/Server/index.js b/react-packager/src/Server/index.js index 4fd0be57..c18fe04a 100644 --- a/react-packager/src/Server/index.js +++ b/react-packager/src/Server/index.js @@ -388,7 +388,9 @@ class Server { 'Content-Type': 'application/json; charset=UTF-8', }); - if (error.type === 'TransformError' || error.type === 'NotFoundError') { + if (error.type === 'TransformError' || + error.type === 'NotFoundError' || + error.type === 'UnableToResolveError') { error.errors = [{ description: error.description, filename: error.filename,