From fda507ac09e2940835af4d176becf7988e321deb Mon Sep 17 00:00:00 2001 From: Gustaf Dalemar Date: Wed, 10 May 2017 10:48:35 +0200 Subject: [PATCH] Changed the Node resolving to be more reliable, fixes some issues Sometimes _resolveFilename will be called without parent.id being present which would result in a crash with the previous logic. This change addresses this and instead uses parent.paths[0] for the same functionality. This solves in particular some problems that have been seen when used together with babel-plugin-lodash. --- docs/RocObject.md | 2 +- src/require/createResolveRequest.js | 4 ++-- src/require/patchResolveFilename.js | 17 +++++++++++++++-- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/docs/RocObject.md b/docs/RocObject.md index 5014928..23370d8 100644 --- a/docs/RocObject.md +++ b/docs/RocObject.md @@ -149,7 +149,7 @@ __`request`__ A string, the path that was requested. __`requestContext`__ -A string, the location of the request. The path to the file that did the request. +A string, the location of the request. The path to the directory from which the request was performed. #### `requires` Dependencies that are required and will be verified to exist by Roc. diff --git a/src/require/createResolveRequest.js b/src/require/createResolveRequest.js index 0b91173..9a3d7a2 100644 --- a/src/require/createResolveRequest.js +++ b/src/require/createResolveRequest.js @@ -30,8 +30,8 @@ export default function createResolveRequest(exports, directory, dependencyConte }; const requestHelper = (request, context, fallback, identifier) => { - // If we got an empty request we want to let Node handle it - if (!request) { + // If we got an empty request or context we want to let Node handle it + if (!request || !context) { return { completedRequest: request }; } diff --git a/src/require/patchResolveFilename.js b/src/require/patchResolveFilename.js index 92b775d..7cb3b93 100644 --- a/src/require/patchResolveFilename.js +++ b/src/require/patchResolveFilename.js @@ -1,4 +1,5 @@ const Module = require('module'); +const path = require('path'); const log = require('debug')('roc:core:require'); @@ -8,8 +9,20 @@ export default function patchResolveFilename(resolveRequest) { log('Initializing'); Module._resolveFilename = function rocResolveFilename(request, parent) { + // Get the context for the request, the directory that the request is coming from. + // We are using "dirname" here to remove "node_modules" from the path that will be + // present given how Nodes algorithm works, with the first path being the directory + // from which the request was performed. + // Example: [/dir/that/did/the/request/node_modules, /dir/that/did/the/node_modules, ...] + const context = parent && parent.paths + ? path.dirname(parent.paths[0]) + : undefined; + try { - return originalResolveFilename.apply(this, [resolveRequest(request, parent.id), parent]); + return originalResolveFilename.apply(this, [ + resolveRequest(request, context), + parent, + ]); } catch (_error) { /* We try again with fallback enabled. * This emulates kinda how NODE_PATH works in that we try again with another scope. @@ -19,7 +32,7 @@ export default function patchResolveFilename(resolveRequest) { * extension is providing. */ return originalResolveFilename.apply(this, [ - resolveRequest(request, parent.id, { fallback: true }), + resolveRequest(request, context, { fallback: true }), parent, ]); }