-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ENHANCEMENT] use EMBER_NODE_PATH to specify node_modules path
ember-cli will use the value in env.EMBER_NODE_PATH if it is provided to look up addons when `require`-ing them. This allows a user to have their `node_modules` path outside of the project root. Previously, the ember-cli custom require code assumed that `node_modules` is always in the project's root.
- Loading branch information
Showing
5 changed files
with
125 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
'use strict'; | ||
|
||
var path = require('path'); | ||
|
||
function isSubdirectoryOf(parentPath, possibleChildPath) { | ||
return possibleChildPath.length > parentPath.length && | ||
possibleChildPath.indexOf(parentPath) === 0; | ||
} | ||
|
||
// A utility function for determining what path an addon may be found at. Addons | ||
// will only be resolved in the project's local `node_modules/` directory. This | ||
// is in contrast to a plain `require('some-module')` lookup, which would resolve | ||
// a library according to the paths in NODE_PATH. | ||
// | ||
// A description of node's lookup logic can be found here: | ||
// | ||
// * https://nodejs.org/api/modules.html#modules_all_together | ||
// | ||
// By requiring with an absolute path this logic is bypassed. | ||
// | ||
module.exports = function nodeModulesPath(context) { | ||
|
||
// Optionally configure a different home for `node_modules/` in a parent | ||
// directory of the project. Possible use cases for this include caching | ||
// the `node_modules/` directory outside of a source code checkout, and | ||
// ensuring the same source code (shared over a network) can be used with | ||
// different environments (Linux, OSX) where binary compatibility may not | ||
// exist. | ||
// | ||
// For example, you can specify a different home directory for modules: | ||
// | ||
// EMBER_NODE_PATH=/opt/deps/node_modules NODE_PATH=/opt/deps/node_modules ember build | ||
// | ||
var nodePath = process.env.EMBER_NODE_PATH; | ||
var contextPath = path.resolve(context); | ||
|
||
if (nodePath) { | ||
var configuredPath = path.resolve(nodePath); | ||
|
||
// The contextPath is likely the project root, or possibly a subdirectory in | ||
// node_modules/ nested dependencies. If it is more specific (a subdirectory | ||
// of) than the configuredPath prefer the more specific contextPath. | ||
if (isSubdirectoryOf(configuredPath, contextPath)) { | ||
return path.resolve(contextPath,'node_modules'); | ||
} else { | ||
return path.resolve(nodePath); | ||
} | ||
} else { | ||
return path.resolve(contextPath,'node_modules'); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,8 @@ | ||
'use strict'; | ||
|
||
var path = require('path'); | ||
var path = require('path'); | ||
var nodeModulesPath = require('../cli/node-modules-path'); | ||
|
||
module.exports = function requireLocal(lib) { | ||
return require(path.join(process.cwd(), 'node_modules', lib)); | ||
return require(path.join(nodeModulesPath(process.cwd()), lib)); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
'use strict'; | ||
/*jshint expr: true*/ | ||
|
||
var expect = require('chai').expect; | ||
var path = require('path'); | ||
var nodeModulesPath = require('../../../lib/cli/node-modules-path'); | ||
|
||
describe('cli/node-module-path.js', function() { | ||
|
||
afterEach(function() { | ||
delete process.env.EMBER_NODE_PATH; | ||
}); | ||
|
||
|
||
it('nodeModulesPath() should return the local node_modules path by default.', function() { | ||
// Valid commands | ||
var expectedPath = path.join(process.cwd(),'node_modules'); | ||
|
||
expect( | ||
nodeModulesPath(process.cwd()) | ||
).to.equal(expectedPath); | ||
}); | ||
|
||
it('nodeModulesPath() should return subdirectories of EMBER_NODE_PATH when set to an absolute path.', function() { | ||
if (process.platform === 'win32') { | ||
process.env.EMBER_NODE_PATH = 'C:\\tmp\node_modules'; | ||
} else { | ||
process.env.EMBER_NODE_PATH = '/tmp/node_modules'; | ||
} | ||
|
||
expect(nodeModulesPath(process.cwd())).to.equal(path.resolve(process.env.EMBER_NODE_PATH)); | ||
|
||
var addOnPath = path.resolve(process.env.EMBER_NODE_PATH, 'node_modules', 'my-add-on'); | ||
var addOnModulesPath = path.resolve(process.env.EMBER_NODE_PATH, 'node_modules', 'my-add-on', 'node_modules'); | ||
expect(nodeModulesPath(addOnPath)).to.equal(addOnModulesPath); | ||
}); | ||
|
||
it('nodeModulesPath() should return subdirectories of EMBER_NODE_PATH when set to a relative path.', function() { | ||
process.env.EMBER_NODE_PATH = '../../tmp/node_modules'; | ||
expect(nodeModulesPath(process.cwd())).to.equal(path.resolve('../../tmp','node_modules')); | ||
expect(nodeModulesPath('../../tmp/node_modules/my-add-on')).to.equal(path.resolve('../../tmp','node_modules','my-add-on','node_modules')); | ||
}); | ||
}); |