New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ENHANCEMENT] Support custom node_module paths #3771
[ENHANCEMENT] Support custom node_module paths #3771
Conversation
looks like windows is unhappy |
@stefanpenner I think my last variation should pass (looks like builds got really backed up and someone cancelled a bunch of them). If there is a better suggestion as to how to handle this on windows I am open to hear it (I currently do not have a local way to test on windows). |
var nodePath = process.env.EMBER_NODE_PATH; | ||
var contextPath = path.resolve(context); | ||
|
||
if(nodePath) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
whitespace
do all the NPM commands |
@stefanpenner fixed whitespace/formatting issues, let me know if anything else is off
It would be the responsibility of the developer to run The |
I will try to spend some time understanding the docker issue correct. I am hesitant to accept more complexity here, without fully understanding the problem it aims to solve. |
@stefanpenner let me know if you need any help with this, I will also bang on this next week with @mixonic (he will be in our office all week). The heart of the issue is really very simple in that There is a secondary benefit that comes from changing this which is that the behavior of dependency loading is currently implicit and harder to understand than it should be since there are no explicit requirements or tests. I actually think the |
var path = require('path'); | ||
|
||
module.exports = function(context) { | ||
var nodePath = process.env.EMBER_NODE_PATH; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we just try to observer NODE_PATH
directly then? I imagine this would align ember-cli with node's own behavior more closely? Or is this going to far?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@steffanpenner NODE_PATH brings extra baggage with it. It will try to load globally installed modules and node_modules installed in $HOME which we might want to avoid. My goal here is t be able to say I have a clean controlled node_modules path but it is not necessarily at the project root.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sounds reasonable, thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Default NODE_PATH
behavior is described here. https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
If this value is unset we could actually do whatever we wanted with it, but I think doing something different than what's described in the node docs would be confusing to developers familiar with the default behavior, so keeping our own envvar seems like the best option.
It sounds like bower will be going away in the future, so if it is working well for now it is likely safe to punt making any changes. |
@mixonic sounds good, only benefit would be it would be in one nice little spot to rip out when this happens, and we would have specs which might make that transition easier. |
var nodeModulesPath = path.resolve(nodePath); | ||
|
||
if (contextPath.indexOf(nodeModulesPath) === 0) { | ||
return path.resolve(contextPath,'node_modules'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to use contextPath
when it is more specific than nodeModulesPath
.
For example given a contextPath
of /Projects/cat-time
and a nodeModulesPath
of /Projects
, the /Projects/cat-time
directory would be used (/Projects
has an index of 0
on /Projects/cat-time
).
This seems backwards? And perhaps we should wrap this in a small semantic helper called hasSubdirectoryOf
etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mixonic I think this is the correct behavior based on what the code currently does from my reading. If node_modules
path is /Projects/node_modules
and a contextPath
of /Projects/node_modules/my-add-on
is passed in, we want to return /Projects/node_modules/my-add-on/node_modules
Right now this is reflected in the tests in this way. Happy to break it out into an intention revealing function though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, we discussed. The more specific path is correct, as it may be a specific subdirectory/nested dep in node_modules/
e7a7abc
to
86b79a8
Compare
This has been updated to use a |
86b79a8
to
2fe39fa
Compare
2fe39fa
to
77f0b84
Compare
Did some Real World testing, and this requires a few ecosystem changes:
|
77f0b84
to
4ff0f71
Compare
// 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_MODULES_PATH. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be NODE_PATH
4ff0f71
to
c5c3f8d
Compare
Here's a test app that works with its node_modules directory outside of the project, along with instructions: https://github.com/bantic/test-app It removes the ember-cli-dependency-checker, but we'll update the dep checker to be more tolerant of a different node_modules location. |
0caf386
to
b249454
Compare
f0d0737
to
096178b
Compare
Sanity checked and good to go. /cc @rwjblue the contains |
// * https://nodejs.org/api/modules.html#modules_all_together | ||
// | ||
// By requiring with an absolute path this logic is bypassed. | ||
// |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can this be converted into the YUIdoc form, this will match other documented functions.
we are slowly making progress on improving doc coverage: https://inch-ci.org/github/ember-cli/ember-cli?pending_build=47203
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I'll update that tonight or tomorrow morning
On Apr 7, 2015, at 6:58 PM, Stefan Penner notifications@github.com wrote:
In lib/cli/node-modules-path.js:
+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 localnode_modules/
directory. This
+// is in contrast to a plainrequire('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.
+//
can this be converted into the YUIdoc form, this will match other documented functions.we are slowly making progress on improving doc coverage: https://inch-ci.org/github/ember-cli/ember-cli?pending_build=47203
—
Reply to this email directly or view it on GitHub.
a64df18
to
4c4809e
Compare
@stefanpenner updated the comments to be yuidoc style. We also have a PR to ember-cli-dependency-checker pending that will update it to respect these path changes. The test-app is updated to use it. It now runs fine with a node_modules directory outside of the project root and stock ember-cli addons except that we are using customized-and-PR'd versions for dependency checker, ic-ajax and htmlbars. |
@bantic - ember-cli-ic-ajax@0.1.2 and ember-cli-htmlbars@0.7.5 are released, and should solve the need to run custom versions, please confirm? |
@rwjblue confirmed! Thanks. Updated the test app to use these versions and it works great. |
@stefanpenner I think we're waiting on a +1 and merge from you. Iterating on changes this week is ideal, let us know if we need to change anything. |
kicking appveyor. I don't have time to thorough review this this week, so I will take your confidence as sufficient in merging once appveyor is happy. I don't want to block the train, but if we discover issues down the road I will pester the 3 of you ;) |
4c4809e
to
30241ac
Compare
30241ac
to
1509caf
Compare
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.
This uses the cli utility helper in node-modules-path to determine the nodeModulesPath. Also modifies private method `AddonDiscovery.discoverFromDependencies` to get the nodeModules path from the project (or addon if inside AddonDiscovery.discoverChildAddons) as its second argument. This property is intended to provide a way for 3rd-party addons (like ember-cli-dependency-checker) to know the project's node modules path without having to discover it in an ad hoc way.
1509caf
to
b844284
Compare
rebased and force pushed. |
[ENHANCEMENT] Support custom node_module paths
This enables custom node_module paths through an environment variable EMBER_NODE_PATH. Places that previously constructed node_modules paths manually now use a shared function
nodeModulesPath
.Because this behavior is implicit right now I am not 100% sure if the tests I wrote capture all of the desired behavior.
This PR is intended to resolve #3735
cc @stefanpenner