tern icon indicating copy to clipboard operation
tern copied to clipboard

Reverse order of resolving

Open joeheyming opened this issue 8 years ago • 15 comments
trafficstars

First of all, I really really like tern. It really solves a lot of problems for me.

Basically, I have a webpack project where I have multiple javascript modules. /project/ /project/externalModule/ /project/externalModule2/ /project/mainModule

Due to reasons outside of my control, a developer set up the project such that mainModule is built with webpack, but the module has externalModule1 and 2 installed under /project/mainModule/node_modules

I set up a dummy webpack config as follows: { alias: [ externalModule1: path.resolve('/project/externalModule1') externalModule2: path.resolve('/project/externalModule2') ] }

The issue I'm having is that the "Module" plugin is resolving before the webpack plugin: https://github.com/ternjs/tern/blob/master/plugin/modules.js#L55 because the order of resolvers is: modules => es_modules => webpack

I believe the order should be reversed: webpack => es_modules => modules

I did a quick change to the plugin: https://github.com/ternjs/tern/blob/master/plugin/webpack.js#L79 I changed push to unshift.

When I did this, and execute M-. in emacs, it goes to the correct alias I defined in the webpack config.js. Whereas before, it would to to /project/mainModule/node_modules/externalModule1/someFile.js

But I want it to resolve to /project/externalModule1/someFile.js

What are the implications of changing the order of resolving? Can we configure .tern_project to reverse the ordering?

Thanks

joeheyming avatar Sep 04 '17 16:09 joeheyming

cc @chemzqm since he wrote most of webpack.js

joeheyming avatar Sep 04 '17 16:09 joeheyming

https://github.com/ternjs/tern/pull/928

joeheyming avatar Sep 04 '17 16:09 joeheyming

I think change push to unshift would be fine, no need for another option, since the webpack resolver should always come first.

chemzqm avatar Sep 05 '17 01:09 chemzqm

@chemzqm Yeah I made that code up as a "straw man" to be shot down. I really just wanted to make webpack resolve first with unshift. I'll submit a new pull request

joeheyming avatar Sep 05 '17 05:09 joeheyming

https://github.com/ternjs/tern/pull/929

joeheyming avatar Sep 05 '17 05:09 joeheyming

Is it not possible to just change the order in which you list the resolution plugins to get the same effect? I.e. load webpack before node_resolve?

marijnh avatar Sep 05 '17 08:09 marijnh

@marijnh no obviously way to do that, since other plugins are loaded in callback, like:

tern.registerPlugin("webpack", function(server, options) {
  server.loadPlugin("commonjs")
  server.loadPlugin("es_modules")
  server.mod.modules.resolvers.unshift(function (name, parentFile) {
  })
})

chemzqm avatar Sep 05 '17 11:09 chemzqm

Which resolver, exactly, do you need to be in front of? The node one isn't loaded by commonjs or es_modules

marijnh avatar Sep 05 '17 11:09 marijnh

I'm sorry @marijnh. I'm still learning this code base and I was initially wrong with my assumptions.

I looked at the code base and find two locations where resolvers.push happens: plugins/webpack.js, and plugins/node_resolve.js

I'm not exactly sure why node_resolve is being loaded automatically. My .tern-project only contains the webpack plugin and the modules plugin.

As far as I can tell, the "node_resolve" plugin is loaded by the "node" plugin. But I can't figure out why the node plugin is being loaded other than that it maybe is a default plugin somehow.

joeheyming avatar Sep 05 '17 17:09 joeheyming

it maybe is a default plugin somehow.

Only doc_comments is loaded by default. Do you maybe have a .tern-config in your home directory that loads node?

marijnh avatar Sep 06 '17 07:09 marijnh

ah, I see. I do have node specified in my home directory tern-config.

Even with my config, I would assume others would expect webpack to resolve before node.

joeheyming avatar Sep 06 '17 17:09 joeheyming

I think having these take precedence according to the order in which you specify them makes sense (though in the case of .tern-config and .tern-project interacting, that might not be entirely obvious).

You can turn off the node plugin by adding "node": null to your project plugin config.

marijnh avatar Sep 07 '17 07:09 marijnh

ok, you are correct. I have a tern config file with node. But, I do wish to continue with that config. I do both node development and webpack development. Let's say I'm editing a gruntfile.js, I would want node completions and imports. But when I'm in a webpack module, or node_modules, I'll want webpack.

So, I'm arguing that the order still matters. Webpack should be resolved first, with node second.

joeheyming avatar Sep 09 '17 16:09 joeheyming

Changing the way in which plugins append themselves will only result in even weirder conflicts in other situations. Having them loaded in the order they are specified seems like an easier to understand approach. Attached patch changes the way plugin specs from different config files are merged--does that solve your problem?

marijnh avatar Sep 10 '17 15:09 marijnh

@marijnh I applied your fix (and reverted my fix). And I am still getting the issue where my aliases are getting resolved by 'node' first instead of webpack. As soon as I apply my fix, the resolving works.

I don't think it is too unreasonable to define a need for certain resolvers to take precedence over others.

joeheyming avatar Oct 02 '17 17:10 joeheyming