Nothing Special   »   [go: up one dir, main page]

Skip to content
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

Resolve node modules correctly #7401

Merged
merged 1 commit into from
Oct 26, 2017
Merged

Conversation

ef4
Copy link
Contributor
@ef4 ef4 commented Oct 25, 2017

ember-cli attempts to provides its own module resolution semantics which are only a subset of node's. These resolution semantics are complex and we spend many lines of code implementing them, all for no benefit over node's native resolution algorithm.

As a side effect of this behavior, we cannot take advantage of nice things like yarn workspaces.

This PR refactors ember-cli to use complete node modules resolution (as reimplemented in userspace by the resolve package. As far as I can tell, I have preserved all existing behavior, including the (dubious and ripe for deprecation) EMBER_NODE_PATH environment variable.

The entire node-modules-path package can be dropped as a dependency once we decide to stop offering the (private-but-used-by-addons) project.nodeModulesPath property.

I think addons should be told to use project.require (already public) or project.resolveSync (would need to be marked public) wherever they were previously using project.nodeModulesPath. It's just fundamentally not correct to try to encode the modules location as a single path.

for (let depName in this.dependencies()) {
try {
this.resolveSync(depName);
return true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like it will return true on the first found package. Is it intentional or should we check all the deps?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah sorry, missed you comment few lines above

Copy link
Member
@rwjblue rwjblue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good overall, I left a few questions inline...

let nodeModulesPath = require('node-modules-path');
let value = nodeModulesPath(this.root);
this._nodeModulesPath = { value };
this.ui.writeDeprecateLine('An addon is trying to access addon.nodeModulesPath. This is not a reliable way to discover npm modules. Instead, consider using require("resolve").sync(something, { basedir: addon.root })');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should include the stack here (or add an extra debug level) so folks have a chance at tracking this down

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also open issues for the addons we can see:

https://emberobserver.com/code-search?codeQuery=nodeModulesPath

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a stack-based message to identify the culprit.

@param {String} file File to resolve
@return {String} Absolute path to file
*/
resolve(file) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts on adding a private API deprecation here also? Might not matter though because I didn't find any usages of project.resolve in emberobserver...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked too, I couldn't find anything. I vote for leaving it out and you can assign the future issue to me when something blows up. :-)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good to me!

@@ -323,7 +329,7 @@ class Project {
*/
resolveSync(file) {
return resolve.sync(file, {
basedir: this.root,
basedir: process.env.EMBER_NODE_PATH || this.root,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't grok what this environment variable is about, can you explain?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only used in one addon (per https://emberobserver.com/code-search?codeQuery=EMBER_NODE_PATH) and that looks like a copy-paste of ember-cli's own tests?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would be totally happy to eliminate this feature, I just can't tell who's depending on it. I think it's more of an app feature than an addon feature.

It was added here: #3771

I think it was a roundabout way of doing what this PR is also doing: allow people to put their node_modules in the other places that you would expect to work based on node behavior.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, agreed. Would you mind triggering a deprecation if we detect that process.env.EMBER_NODE_PATH is set?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets take this as a separate issue (and not block this PR on it)...

ember-cli attempts to provides its own module resolution semantics which are only a subset of node's. These resolution semantics are complex and we spend many lines of code implementing them, all for no benefit over node's native resolution algorithm.

As a side effect of this behavior, we cannot take advantage of nice things like [yarn workspaces](ember-cli#7335).

This PR refactors ember-cli to use complete node modules resolution (as reimplemented in userspace by the [resolve](http://npmjs.com/package/resolve) package. As far as I can tell, I have preserved all existing behavior, including the (dubious and ripe for deprecation) EMBER_NODE_PATH environment variable.

The entire `node-modules-path` package can be dropped as a dependency once we decide to stop offering the (private-but-used-by-addons) `project.nodeModulesPath` property.

I think addons should be told to use `project.require` (already public) or `project.resolveSync` (would need to be marked public) wherever they were previously using `project.nodeModulesPath`. It's just fundamentally not correct to try to encode the modules location as a single path.
Copy link
Member
@Turbo87 Turbo87 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, please!

@rwjblue
Copy link
Member
rwjblue commented Oct 26, 2017

Thank you @ef4!

@ro0gr
Copy link
Contributor
ro0gr commented Nov 1, 2017

Today I've converted our solution to monorepo. It works great with current master.
Thanks @ef4!

@ef4
Copy link
Contributor Author
ef4 commented Nov 1, 2017

That's great! I'm surprised it worked actually, because there are some standard addons that still need to be updated like ember-cli-dependency-checker.

@MiguelMadero
Copy link
Contributor

This is working great for us, with some minor tweaks. PR(s) coming

// Blueprint tests set this flag.
return true;
}
for (let depName in this.dependencies()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ef4 seems like this introduced some issues. I have a potential fix on #7414

webark added a commit to webark/ember-normalize that referenced this pull request Jan 4, 2018
based off of ember-cli/ember-cli#7401 `nodeModulesPath` has been depreciated, and `resolveSync` is a preferred alternative. `nodeModulesPath` has been removed in Ember Cli 3.x and it's use here breaks 3.x builds.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants