Skip to content

Improve plugin resolution when path does not start with ./#4451

Merged
azz merged 6 commits intoprettier:masterfrom
kachkaev:fix-plugin-resolution
May 10, 2018
Merged

Improve plugin resolution when path does not start with ./#4451
azz merged 6 commits intoprettier:masterfrom
kachkaev:fix-plugin-resolution

Conversation

@kachkaev
Copy link
Copy Markdown
Member

@kachkaev kachkaev commented May 9, 2018

I noticed that passing --plugin=path/to/plugin rather than --plugin=./path/to/plugin crashes Prettier. This happens because it tries to resolve path/to/plugin as a node module rather than a relative path. The error says:

"Cannot find module 'path/to/plugin' from '/path/to/cwd'"

This PR fixes that and thus makes usage of --plugin more predictable. ~~~It is unlikely that someone would want to refer to a local node module, because a plugin from there would be autoloaded anyway (as long as the instance of Prettier is local).~~~ The new behaviour supports both node module names and paths without leading ./.

I also tweak a couple of minor things given the opportunity, please see the commit log.

@azz
Copy link
Copy Markdown
Member

azz commented May 9, 2018

What about if someone wants to use a plugin that doesn't match the auto-load pattern? e.g. prettier --plugin=@company/prettier-plugin-bespoke?

@kachkaev
Copy link
Copy Markdown
Member Author

kachkaev commented May 9, 2018

Please note that I'm keeping requirePath: resolve.sync(pluginName, { basedir: resolvedPluginSearchDir }) for plugins found in pluginSearchDirs. That's because there we get a list of node modules there and we do want to resolve them as modules.

@kachkaev
Copy link
Copy Markdown
Member Author

kachkaev commented May 9, 2018

@azz good point. I guess we should decide between allowing people to use --plugin=@company/prettier-plugin-bespoke instead of --plugin=node_modules/@company/prettier-plugin-bespoke and saving others from confusion when whey type --plugin=src/index.js instead of --plugin=./src/index.js. I personally struggled in the second scenario, which brought me to proposing this change.

Practically speaking, how likely would people use @company/prettier-plugin-bespoke for Prettier plugin names given that these are not auto-loadable and so more difficult to setup in projects? Use of --plugin option seems to me like a hook to mainly use in development.

@azz
Copy link
Copy Markdown
Member

azz commented May 9, 2018

Maybe we can just offer a better error message if you forget the ./?

@kachkaev
Copy link
Copy Markdown
Member Author

kachkaev commented May 9, 2018

That can be a good option too. So do I just try/catch and then throw a custom error message if the original one starts with Cannot find module? Let's see what others think as well.

@suchipi
Copy link
Copy Markdown
Member

suchipi commented May 9, 2018

We could search locally if the provided string ends in .js, and assume node modules otherwise

@suchipi
Copy link
Copy Markdown
Member

suchipi commented May 9, 2018

We may also want to support the string ending in .:
--plugin=.

@kachkaev
Copy link
Copy Markdown
Member Author

kachkaev commented May 9, 2018

What if we do this?

let requirePath;
try {
  // try local files
  requirePath = resolve.sync(path.resolve(process.cwd(), pluginName));
} catch (e) {
  // try node modules
  requirePath = resolve.sync(pluginName, { basedir: process.cwd() });
}

If the second attempt fails, Prettier will crash. This can make things smooth for both types of uses IMO. The reason why we may want resolve.sync(pluginName, { basedir: process.cwd() }) to be second is because we don't want the final error message to be confusing because of the absolute path in it.

As of --plugin=., I guess it's already supported. I can add a test with plugins/automatic/node_modules/prettier-plugin-bar as cwd.

@suchipi
Copy link
Copy Markdown
Member

suchipi commented May 9, 2018

That's a clean solution, I like it 👍

@kachkaev kachkaev changed the title Fix plugin resolution when path does not start with ./ Improve plugin resolution when path does not start with ./ May 9, 2018
@kachkaev
Copy link
Copy Markdown
Member Author

kachkaev commented May 9, 2018

@suchipi that's done now, just waiting for the tests to pass (Travis builds are a bit bumpy today).

Copy link
Copy Markdown
Member

@suchipi suchipi left a comment

Choose a reason for hiding this comment

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

Looks great

@azz azz merged commit bc78541 into prettier:master May 10, 2018
@lipis lipis added this to the 1.13 milestone May 13, 2018
@lock lock Bot added the locked-due-to-inactivity Please open a new issue and fill out the template instead of commenting. label Aug 11, 2018
@lock lock Bot locked as resolved and limited conversation to collaborators Aug 11, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

locked-due-to-inactivity Please open a new issue and fill out the template instead of commenting.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants