-
Notifications
You must be signed in to change notification settings - Fork 102
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
Update Optimization Detective plugin build process #1080
Update Optimization Detective plugin build process #1080
Conversation
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.
To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
2118490
to
767c895
Compare
@westonruter @felixarntz I have updated the build steps. With this, I would suggest separating the standalone plugins' building process from the primary PL plugin. I recommend this for the following reasons:
In 767c895, I have made the necessary changes. LMKWYT and I'll make the necessary adjustments. |
@thelovekesh Sounds good to me but I'm a bit confused: are you saying you did do it already or have yet to do it? |
package.json
Outdated
@@ -28,11 +28,14 @@ | |||
"changelog": "./bin/plugin/cli.js changelog", | |||
"since": "./bin/plugin/cli.js since", | |||
"readme": "./bin/plugin/cli.js readme", | |||
"build": "wp-scripts build", | |||
"build": "npm-run-all 'build:!(plugin)'", | |||
"build:optimization-detective": "wp-scripts build -c plugins/optimization-detective/webpack.config.js", |
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.
The standalone plugin deploy workflow is just doing:
npm run build:plugin:${{ matrix.plugin }}
So won't this mean that the assets aren't included in the plugin build there?
Separately, in Optimization Detective, when first cloning the repo for development, isn't there a check to see if the web-vitals script is present and if not an admin notice is shown with instructions to build the plugin? Won't that need to be updated?
Will this be getting run automatically when doi
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.
It will be run automatically on the pre-hook. See diff.
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.
Oh I see (and sorry for my truncated com
😉
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.
Separately, in Optimization Detective, when first cloning the repo for development, isn't there a check to see if the web-vitals script is present, and if not an admin notice is shown with instructions to build the plugin? Won't that need to be updated?
I think we did it in the can-load.php
file which no longer exists. We need to add this check in the main plugin file and die with an admin notice if the required assets are not there. Shall I add this as the part of same PR?
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.
Oh right. If we think it's important to add, or alternatively what if the asset build happens automatically after npm install?
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, they would get a fatal error on the frontend when attempting to require the asset PHP file. In PHP7 can't this Error be caught? If so, we could then show an error in the console about needing to build.
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.
How about this:
--- a/plugins/optimization-detective/detection.php
+++ b/plugins/optimization-detective/detection.php
@@ -35,8 +35,17 @@ function od_get_detection_script( string $slug, OD_URL_Metrics_Group_Collection
*/
$detection_time_window = apply_filters( 'od_detection_time_window', 5000 );
- $web_vitals_lib_data = require __DIR__ . '/detection/web-vitals.asset.php';
- $web_vitals_lib_src = add_query_arg( 'ver', $web_vitals_lib_data['version'], plugin_dir_url( __FILE__ ) . '/detection/web-vitals.js' );
+ try {
+ $web_vitals_lib_data = require __DIR__ . '/detection/web-vitals.asset.php';
+ } catch ( Error $error ) {
+ return wp_get_inline_script_tag(
+ sprintf(
+ 'console.error( %s );',
+ wp_json_encode( '[Optimization Detective] ' . __( 'Unable to load web-vitals.asset.php. Please make sure you have run `npm install && npm run build:optimization-detective`.', 'optimization-detective' ) )
+ )
+ );
+ }
+ $web_vitals_lib_src = add_query_arg( 'ver', $web_vitals_lib_data['version'], plugin_dir_url( __FILE__ ) . '/detection/web-vitals.js' );
$current_url = od_get_current_url();
$detect_args = array(
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.
If we are going to add it, I think the plugin screen would be the best place as users will come to know about this as soon as the plugin is activated. But above approach also looks good to me.
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.
Added in 4656cbf
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.
See my other comment: This NPM script is confusing, why not put it directly into prebuild:plugin:optimization-detective
instead?
I have done it in a single commit(767c895) for others to test it and to revert if required. |
- name: Setup Node.js (.nvmrc) | ||
uses: actions/setup-node@v3 | ||
with: | ||
node-version-file: '.nvmrc' | ||
cache: npm | ||
- name: Install npm dependencies | ||
run: npm ci | ||
- name: Build assets | ||
run: npm run build | ||
- name: Get directory | ||
id: get-plugin-directory | ||
if: ${{ github.event_name == 'workflow_dispatch' }} | ||
run: | | ||
echo "directory=$(node ./bin/plugin/cli.js get-plugin-dir --slug=${{ inputs.slug }})" >> $GITHUB_OUTPUT | ||
- name: Get plugin version | ||
id: get-version | ||
if: ${{ github.event_name == 'workflow_dispatch' }} | ||
run: | | ||
echo "version=$(node ./bin/plugin/cli.js get-plugin-version --slug=${{ inputs.slug }})" >> $GITHUB_OUTPUT |
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.
I see this is removed because it is duplicated with the deploy job below.
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.
@thelovekesh A bit of feedback below. Let's try to limit the build workflow changes in the feature branch to things that only affect this plugin. Otherwise it should be explored in a PR against trunk
, to avoid siloed decisions and decrease the risk of merge conflicts in the future.
package.json
Outdated
"prebuild:plugin:optimization-detective": "npm run build:optimization-detective", | ||
"build:plugin:optimization-detective": "webpack --mode production --env plugin=optimization-detective", |
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.
I find this very confusing. Why is there build:plugin:optimization-detective
and build:optimization-detective
, the latter of which is then called by prebuild:plugin:optimization-detective
? Can we simplify this?
It's not obvious how build:plugin:optimization-detective
and build:optimization-detective
differ. I think one of them should be removed and implemented in a more low-level fashion that doesn't lead to confusion about the available scripts.
package.json
Outdated
@@ -28,11 +28,14 @@ | |||
"changelog": "./bin/plugin/cli.js changelog", | |||
"since": "./bin/plugin/cli.js since", | |||
"readme": "./bin/plugin/cli.js readme", | |||
"build": "wp-scripts build", | |||
"build": "npm-run-all 'build:!(plugin)'", | |||
"build:optimization-detective": "wp-scripts build -c plugins/optimization-detective/webpack.config.js", |
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.
See my other comment: This NPM script is confusing, why not put it directly into prebuild:plugin:optimization-detective
instead?
package.json
Outdated
"build": "wp-scripts build", | ||
"build": "npm-run-all 'build:!(plugin)'", |
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.
What's the purpose of this? Why not use wp-scripts build
, which is intended to take away a lot of the maintenance burden of custom build workflows? Are there concrete limitations that make using it infeasible?
try { | ||
$web_vitals_lib_data = require __DIR__ . '/detection/web-vitals.asset.php'; | ||
} catch ( Error $error ) { | ||
$error_message = '[Optimization Detective] '; | ||
$error_message .= sprintf( | ||
/* translators: 1: File path. 2: CLI command. */ | ||
__( 'Unable to load %1$s. Please make sure you have run %2$s.', 'optimization-detective' ), | ||
'detection/web-vitals.asset.php', | ||
'`npm install && npm run build:optimization-detective`' | ||
); | ||
if ( WP_DEBUG && WP_DEBUG_DISPLAY ) { | ||
$error_message .= ' ' . __( 'PHP Error:', 'optimization-detective' ) . ' ' . $error->getMessage(); | ||
} | ||
return wp_get_inline_script_tag( | ||
sprintf( 'console.error( %s );', wp_json_encode( $error_message ) ) | ||
); | ||
} | ||
$web_vitals_lib_src = add_query_arg( 'ver', $web_vitals_lib_data['version'], plugin_dir_url( __FILE__ ) . '/detection/web-vitals.js' ); |
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.
Shouldn't this rather be a check in the plugin main file? If that file is missing, the plugin needs to be built, just how e.g. other plugins commonly check for existence of composer.json
or vendor
dir. The lack of this should be obvious to the end user, IMO better in an admin notice that shows immediately rather than a hard-to-detect PHP error that is only shown in JavaScript and only if the detection script is attempted to be loaded.
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 is the only place where the file is actually accessed. Also, the check is only relevant during development. It seems wasteful to do a file_exists()
check with every request in production when in a production build the files are always present.
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.
Also, the check is only relevant during development.
So is checking for things like composer.json
or vendor
, but it's commonly included in many plugins' main file. My main feedback here is that I don't see why this file missing should not be treated in the same way as such cases. It's needed for the plugin to function correctly, as far as I understand.
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.
OK. Reverted in 6ae5fb0
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.
Moved to main file in 3aae425
}; | ||
}; | ||
|
||
module.exports = optimizationDetective; |
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.
Which parts of this file are actually needed?
Background is I don't recall that we discussed having individual webpack scripts per plugin before, and since the only plugin that needs a build process to function at all so far is this one, I think we should go with a more pragmatic solution. Why not include this Optimization Detective specific web-vitals step in the main webpack.config.js
? In other words, the way this was before.
We can consider optimizing it later, let's just get to an MVP solution now. Decisions that affect the build infrastructure of the entire repo shouldn't be made in a plugin's feature branch PR.
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.
Per #1080 (comment) it seems like you're saying 767c895 should be reverted?
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.
@westonruter Yes, I think that's a much simpler solution for now, especially since this is the only plugin that needs a build process.
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.
Reverted in 0e07d11
@@ -25,6 +25,21 @@ | |||
return; | |||
} | |||
|
|||
if ( ! file_exists( __DIR__ . '/detection/web-vitals.asset.php' ) ) { |
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.
@westonruter Can't we wrap it in is_admin()
? Users will face this problem while activating the plugin. So having this in admin should suffice? In production this check will be redundant anyway.
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.
Good idea! Did that in ae07548 as well as checking if WP-CLI.
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.
@westonruter @thelovekesh Alternatively we could consider using require
in a try catch
like you had before, given you mentioned the file_exists
check as a potential concern.
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.
I think this is good now as otherwise it would need to require
the PHP file on every request when it may not be needed.
Note: the PL plugin unit tests are currently failing because wp-env is activating all standalone plugins in the workflow, even though they haven't been built (and so Optimization Detective is rightfully throwing an error since the web-vitals.js is absent). So to fix this we can update the workflow to edit the diff --git a/.wp-env.json b/.wp-env.json
index be6a3114..c59e89af 100644
--- a/.wp-env.json
+++ b/.wp-env.json
@@ -1,14 +1,6 @@
{
"core": null,
- "plugins": [
- ".",
- "./plugins/auto-sizes",
- "./plugins/dominant-color-images",
- "./plugins/embed-optimizer",
- "./plugins/optimization-detective",
- "./plugins/speculation-rules",
- "./plugins/webp-uploads"
- ],
+ "plugins": ["."],
"env": {
"tests": {
"config": { And as discussed with @thelovekesh, this file can be written to |
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.
LGTM, just one follow up.
- name: Remove standalone plugins from wp-env config | ||
run: jq '.plugins = [.plugins[0]]' .wp-env.json > .wp-env.override.json |
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.
👍
! file_exists( __DIR__ . '/detection/web-vitals.asset.php' ) | ||
) { | ||
// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error | ||
trigger_error( |
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.
Why not use wp_trigger_error()
? Or even more obvious with an admin notice, like for instance in https://github.com/ampproject/amp-wp/blob/develop/amp.php#L178?
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.
The problem with wp_trigger_error()
is that it does nothing if WP_DEBUG
isn't enabled (which seems somewhat strange especially if E_USER_ERROR
had been passed).
As for a more robust error notices like in the AMP plugin, I think that might be overkill for Optimization Detective. There are a lot more dependencies for the AMP plugin which can cause errors to happen a lot more often, so more users will be seeing that notice, even end users. For Optimization Detective, the only users seeing the error would be developers cloning from GitHub. So I think what we have now is sufficient.
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.
Makes sense regarding wp_trigger_error()
. Or rather not - well...
Regarding the AMP plugin, as to what I had mentioned before, there's also https://github.com/ampproject/amp-wp/blob/develop/amp.php#L162 which shows an admin notice for when the plugin isn't built. That's just as much applicable here, which is why I was proposing it.
But not a necessity to have either way.
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, for that we just included it among the other load error checks since the infrastructure was already there. But since that is a build time error rather than a runtime error, it technically isn't needed for the production build.
8d096f1
into
feature/image-loading-optimization
Summary
Follow up #1063 (comment)