-
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.
- Loading branch information
Showing
10 changed files
with
228 additions
and
31 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,74 @@ | ||
'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 own `node_modules/` directory, they | ||
do not follow the standard node `require` logic that a standard | ||
`require('mode-module')` lookup would use, which finds the module according | ||
to the `NODE_PATH`. | ||
A description of node's lookup logic can be found here: | ||
https://nodejs.org/api/modules.html#modules_all_together | ||
Using this method to discover the correct location of project's `node_modules` | ||
directory allows addons to be looked up properly even when that `node_modules` | ||
directory is outside of the project's root. | ||
This method checks the env variable `EMBER_NODE_PATH`. If present, its value | ||
is used to determine the `node_modules` path. | ||
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, if you have a project in /projects/my-app and its `node_modules` | ||
directory is at /resource/node_modules, you would: | ||
``` | ||
# Node uses this as its search path for standard `require('module')` calls | ||
export NODE_PATH=/resource/node_modules | ||
# So that ember addon discovery looks here | ||
export EMBER_NODE_PATH=/resource/node_modules | ||
cd /projects/my-app && ember build | ||
``` | ||
@private | ||
@method nodeModulesPath | ||
@param {String} context The starting directory to use to find the | ||
node_modules path. This will usually be the | ||
project's root | ||
@return {String} absolute path to the node_modules directory | ||
*/ | ||
module.exports = function nodeModulesPath(context) { | ||
|
||
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 than the | ||
// the configuredPath (i.e. it is a subdirectory of 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
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
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')); | ||
}); | ||
}); |
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
Oops, something went wrong.