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

core(plugins): resolve plugins and audits from cwd #9950

Closed
wants to merge 6 commits into from

Conversation

paulirish
Copy link
Member

@paulirish paulirish commented Nov 9, 2019

This is an alternative to #9948

"Your colleagues will hate you for it!"


my goals here

  1. plugin developers have a sane flow
  2. plugin users have zero surprises or anything odd.

and two things that are explicitly not optimized:

  1. lighthouse core developers don't have a straightforward mechanism of developing plugins within the core repo
  2. plugin developers who also have a lighthouse checkout may face weirdness if they want to hack on lighthouse at the same time as the plugin.

@connorjclark
Copy link
Collaborator

no hate 💓

@paulirish's approach only considers plugin authors being able to run their own plugin super easily. Call it focused 🤓

My approach allows for the same, but also supports using a plugin from anywhere on the filesystem. Call it flexible 🏃‍♂️. This is possible with the other approach, but requires usage of yarn link, a tool I find to be low in DX (how do you see what packages are currently linked? hint: it's not supported).

No doubt, the focused 🤓 approach is less code and fixes the largest pain point we know about for plugin development. I think it's probably what we should go with. But I'll point out the differences anyway.

common supported usecase: run my plugin under development

Note that it is assumed that lighthouse is installed as a dependency/devDependency.

focused 🤓

# be in their plugin repo

# run
yarn lighthouse https://www.example.com --plugins=. --only-categories=.

# run just their plugin
yarn lighthouse https://www.example.com --plugins=. --only-categories=.

flexible 🏃‍♂️

# be in their plugin repo

# run
yarn lighthouse --plugins=.

# run just their plugin
yarn lighthouse --plugins=. --only-categories=lighthouse-plugin-yt
yarn lighthouse --plugins=. --only-categories=`basename "$PWD"`
# would like to support `.` but I didn't special case it yet

using any plugin

flexible 🏃‍♂️

# 1) global installation (could also be local checkout `node lighthouse-cli ...`)
# for some reason I am a user with plugins but don't want to publish them to npm. that's okay because I can just point lighthouse to my local copy of it
lighthouse --plugins=~/code/lighthouse-plugins/lighthouse-plugin-yt

# 2) back in a plugin repo, but imagine it is a plugin monorepo because I have a lot of opinions and need many lighthouse plugins
yarn lighthouse --plugins=./plugins/lighthouse-plugin-trending
yarn lighthouse --plugins=./plugins/lighthouse-plugin-voice

# 3) run both
yarn lighthouse --plugins=./plugins/lighthouse-plugin-trending,./plugins/lighthouse-plugin-voice
# ...

focused 🤓

# 1) can do the same thing but I need to cd to the folder first, or use yarn link
cd ~/code/lighthouse-plugins/lighthouse-plugin-yt
yarn lighthouse https://www.example.com --plugins=. --only-categories=.

# 2) can do the same thing but I need to cd to the folder first, or use yarn link
cd plugins/lighthouse-plugin-trending && yarn lighthouse https://www.example.com --plugins=. --only-categories=.
cd plugins/lighthouse-plugin-voice && yarn lighthouse https://www.example.com --plugins=. --only-categories=.


# 3) can't do the same thing without some yarn links

possible shorthand

Filtering to just the plugin whose directory you are currently in is stranger in my approach, but I can think of a third approach that's better than both (from the perspective of a plugin author). Something like --debug-local-plugin as a shorthand for the options above (it would just set --plugins and only-categories for you).

@connorjclark
Copy link
Collaborator

connorjclark commented Nov 9, 2019

this works with none of our changes:

# be in plugin directory
NODE_PATH=.. yarn lighthouse https://paulirish.github.io/lite-youtube-embed/ --plugins=lighthouse-plugin-yt --only-categories=lighthouse-plugin-yt

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

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

I'm definitely a fan of the simpler approach for now. I don't know if we want to encourage plugin use outside of the module system, but we obviously do need to improve plugin development ergonomics

@@ -4,5 +4,8 @@
"main": "./plugin.js",
"peerDependencies": {
"lighthouse": "^5.0.0"
},
"devDependencies": {
"lighthouse": "latest"
Copy link
Member

Choose a reason for hiding this comment

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

this could cause problems, though it sounds like y'all have talked this through? If the version of LH that the plugin depends on is different than the one running the plugin, weird things happen with e.g. ICU, logging, sentry, the report generator, etc. At least as a devDependency it'll only be during plugin development.

Copy link
Member Author

Choose a reason for hiding this comment

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

nah it should be a more specific version range

lighthouse-cli/cli-flags.js Outdated Show resolved Hide resolved
@@ -161,6 +161,9 @@ function assertValidGatherer(gathererInstance, gathererName) {
* @param {string} pluginName
*/
function assertValidPluginName(configJSON, pluginName) {
// For local plugin development
if (pluginName === '.') return;
Copy link
Member

Choose a reason for hiding this comment

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

what about

Suggested change
if (pluginName === '.') return;
if (pluginName === '.') {
pluginName = path.basename(process.cwd());
}

to make sure we don't encourage plugins not named lighthouse-plugin- whatever? (I guess the most correct thing would be to read from package.json, but I don't know how much of a pain that would be)

Copy link
Member

Choose a reason for hiding this comment

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

or do the basename thing in bin.js...maybe we don't want folks testing with . as a category? It makes for some weird LHR differences than when running a plugin as a user

Copy link
Member Author

Choose a reason for hiding this comment

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

i like reading the real thing from the folder, yeah.

if (moduleIdentifier.startsWith('lighthouse-plugin-')) {
// See if the module resolves in the context of the current working directory.
// Most useful to handle the case of Lighthouse plugin development.
const cwdPath = path.resolve(process.cwd(), '../', moduleIdentifier);
Copy link
Member

Choose a reason for hiding this comment

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

if we don't like this, the doubled up lighthouse-plugin-whatever could be taken care of in config-plugin.js. It we passed in the resolved plugin path, we could then rewrite the audit paths as absolute in _parseAuditsList (or relative to some known entity, like the lh root or cwd or whatever).

It should allow getting rid of making plugins prefix their audits with the plugin name (and it could allow relative paths to any plugin).

Not sure if we want to do any of that, though.

Copy link
Member Author

Choose a reason for hiding this comment

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

yah that's a good idea.


IMO the audit path that we expect in plugin.js doesn't make sense to me. eg.

https://github.com/connorjclark/lighthouse-plugin-yt/blob/136869d31885b3894d12882350989c8c9112c4b6/plugin.js#L6

wdyt about for v6 we would change that so that the audit paths defined in plugin.js are relative

oh wait. i think that'd simplify plugin dev but it'd break plugin use? seems like it would in theory.

@connorjclark @brendankenny does that sound right? that we essentially need the plugin-name in the path so the resolution for a user works?

Copy link
Collaborator

Choose a reason for hiding this comment

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

We can do this change w/o breaking plugin users. Just need to try one more path in our resolution strategy (prefix the name of the plugin to the audit module path, if the initial resolution didnt work)

@connorjclark
Copy link
Collaborator

my vote is to close both of these PRs and just update our plugin docs with:

#9950 (comment)

@paulirish
Copy link
Member Author

this works with none of our changes:

# be in plugin directory
NODE_PATH=.. yarn lighthouse https://paulirish.github.io/lite-youtube-embed/ --plugins=lighthouse-plugin-yt --only-categories=lighthouse-plugin-yt

this sounds pretty cool, though i am scared. it's quite simple.

@connorjclark
Copy link
Collaborator

connorjclark commented Nov 9, 2019

even this works (running from lighthouse dir, master)

NODE_PATH=~/code/ node lighthouse-cli/ https://www.example.com --plugins=lighthouse-plugin-yt --only-categories=lighthouse-plugin-yt  --view

I feel like I gained a super power

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants