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

Update Optimization Detective plugin build process #1080

Merged
merged 13 commits into from
Mar 22, 2024

Conversation

thelovekesh
Copy link
Member

Summary

Follow up #1063 (comment)

Copy link

github-actions bot commented Mar 22, 2024

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 props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: thelovekesh <[email protected]>
Co-authored-by: westonruter <[email protected]>
Co-authored-by: felixarntz <[email protected]>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@thelovekesh thelovekesh added Infrastructure Issues for the overall performance plugin infrastructure [Type] Enhancement A suggestion for improvement of an existing feature no milestone PRs that do not have a defined milestone for release labels Mar 22, 2024
@thelovekesh thelovekesh force-pushed the update/build-process branch from 2118490 to 767c895 Compare March 22, 2024 09:53
@thelovekesh
Copy link
Member Author

@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:

  • The size of the main webpack file and thus maintenance overhead will increase as more plugins employ build steps.
  • It will be difficult to share the sharedConfig across all plugins and build phases if any plugin expands the shared configuration.
  • Handling the dependencies option will get challenging.

In 767c895, I have made the necessary changes. LMKWYT and I'll make the necessary adjustments.

@westonruter
Copy link
Member

@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",
Copy link
Member

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

Copy link
Member Author

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.

Copy link
Member

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

😉

Copy link
Member Author

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?

Copy link
Member

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?

Copy link
Member

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.

Copy link
Member

@westonruter westonruter Mar 22, 2024

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(

Copy link
Member Author

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.

Copy link
Member

Choose a reason for hiding this comment

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

Added in 4656cbf

Copy link
Member

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?

@thelovekesh
Copy link
Member Author

@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?

I have done it in a single commit(767c895) for others to test it and to revert if required.

@westonruter westonruter changed the title Update Optimization Detective plguin build process Update Optimization Detective plugin build process Mar 22, 2024
Comment on lines -30 to -48
- 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
Copy link
Member

@westonruter westonruter Mar 22, 2024

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.

Copy link
Member

@felixarntz felixarntz left a 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
Comment on lines 38 to 39
"prebuild:plugin:optimization-detective": "npm run build:optimization-detective",
"build:plugin:optimization-detective": "webpack --mode production --env plugin=optimization-detective",
Copy link
Member

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",
Copy link
Member

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)'",
Copy link
Member

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?

Comment on lines 38 to 55
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' );
Copy link
Member

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.

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 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.

Copy link
Member

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.

Copy link
Member

Choose a reason for hiding this comment

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

OK. Reverted in 6ae5fb0

Copy link
Member

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;
Copy link
Member

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.

Copy link
Member

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?

Copy link
Member

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.

Copy link
Member

Choose a reason for hiding this comment

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

Reverted in 0e07d11

@westonruter westonruter requested a review from felixarntz March 22, 2024 18:54
@@ -25,6 +25,21 @@
return;
}

if ( ! file_exists( __DIR__ . '/detection/web-vitals.asset.php' ) ) {
Copy link
Member Author

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.

Copy link
Member

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.

Copy link
Member

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.

Copy link
Member

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.

@westonruter
Copy link
Member

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 .wp-env.json to remove all standalone plugins from the plugins key, so it remains just ["."]:

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 .wp-env.override.json before proceeding with npm run wp-env start.

Copy link
Member

@felixarntz felixarntz left a 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.

Comment on lines +65 to +66
- name: Remove standalone plugins from wp-env config
run: jq '.plugins = [.plugins[0]]' .wp-env.json > .wp-env.override.json
Copy link
Member

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(
Copy link
Member

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?

Copy link
Member

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.

Copy link
Member

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.

Copy link
Member

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.

@westonruter westonruter merged commit 8d096f1 into feature/image-loading-optimization Mar 22, 2024
32 checks passed
@westonruter westonruter deleted the update/build-process branch March 22, 2024 20:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Infrastructure Issues for the overall performance plugin infrastructure no milestone PRs that do not have a defined milestone for release [Type] Enhancement A suggestion for improvement of an existing feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants