From c1960dbe029617fdd772cc55ee6a3f47ac476359 Mon Sep 17 00:00:00 2001 From: Adam Miskiewicz Date: Thu, 11 Feb 2016 10:35:50 -0500 Subject: [PATCH] Make Babel resolve plugins relative to where they were specified. Given the following `.babelrc`: ``` { "plugins": ["./myPluginDir/somePlugin.js"] } ``` Babel should resolve that plugin relative to the directory that contains the `.babelrc` file. Currently, Babel is resolving the plugin relative to the current `process.cwd()`, as you can see in this test case: https://github.com/skevy/babel-plugin-resolution-test-case This is occurring because the "fake" `Module` that we're creating in the `resolve` helper doesn't have an `id` and `filename`. Therefore, Node builds an array of paths that contains a number of node_module paths as well as `.`, and doesn't contain the path in which we'd actually like to look up the plugin. `.` of course resolves to the current `process.cwd()`, and thus makes the Babel plugin resolution mechanism quite fragile. The relevant code in Node.JS can be found here (tagged at the v5.4.1 release): https://github.com/nodejs/node/blob/ff992037246010fdad6f72323fe556da69640531/lib/module.js#L236-L242. This PR adds `id` and `filename` to that fake `Module` in order to resolve this issue. --- packages/babel-core/src/helpers/resolve.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/babel-core/src/helpers/resolve.js b/packages/babel-core/src/helpers/resolve.js index aaf0695d3c..623a910cbf 100644 --- a/packages/babel-core/src/helpers/resolve.js +++ b/packages/babel-core/src/helpers/resolve.js @@ -1,4 +1,5 @@ import Module from "module"; +import path from "path"; let relativeModules = {}; @@ -10,6 +11,17 @@ export default function (loc: string, relative: string = process.cwd()): ?string if (!relativeMod) { relativeMod = new Module; + + // We need to define an id and filename on our "fake" relative` module so that + // Node knows what "." means in the case of us trying to resolve a plugin + // such as "./myPlugins/somePlugin.js". If we don't specify id and filename here, + // Node presumes "." is process.cwd(), not our relative path. + // Since this fake module is never "loaded", we don't have to worry about mutating + // any global Node module cache state here. + let filename = path.join(relative, ".babelrc"); + relativeMod.id = filename; + relativeMod.filename = filename; + relativeMod.paths = Module._nodeModulePaths(relative); relativeModules[relative] = relativeMod; }