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

Add Javascript and TypeScript build for jetpack-wpcom-mu #34158

Merged
merged 39 commits into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
12335c0
Jetpack Mu WPcom: Migrate Error Handling
obenland Nov 16, 2023
9159934
Update script paths
obenland Nov 16, 2023
5900f65
Add initial JS build code for jetpack-mu-wpcom
daledupreez Nov 16, 2023
2f9d0c3
changelog
daledupreez Nov 16, 2023
56441c4
Loosen dependencies
daledupreez Nov 16, 2023
102379d
Add build/ to .gitignore
daledupreez Nov 16, 2023
de56417
Add clean script
daledupreez Nov 16, 2023
5135060
Add dependencies for error-reporting
daledupreez Nov 16, 2023
6f90e42
Update versions
daledupreez Nov 16, 2023
e1a1b30
Changelog
daledupreez Nov 16, 2023
1934951
Add build scripts
daledupreez Nov 16, 2023
aa4ff50
Try using PKG_DIR
obenland Nov 16, 2023
e9498ed
Add build/ directory to production output
daledupreez Nov 16, 2023
9c210ab
Import namespaced class
obenland Nov 16, 2023
55f4420
Merge branch 'add/js-build-for-jetpack-wpcom-mu' of https://github.co…
obenland Nov 16, 2023
bcf0831
Bail early if ETK has enqueued its script
obenland Nov 16, 2023
d606b39
Switch to more direct webpack build
daledupreez Nov 16, 2023
2edd95c
Remove @wordpress/scripts and dependencies
daledupreez Nov 16, 2023
284fd65
Ignore the .cache directory
daledupreez Nov 16, 2023
c0aa7a9
Update to using base dir and file to enqueue scripts
obenland Nov 16, 2023
f9e2410
Merge branch 'add/js-build-for-jetpack-wpcom-mu' of https://github.co…
obenland Nov 16, 2023
df9cb53
Remove JS/TS file exclusion and update build dir path
daledupreez Nov 16, 2023
c9ad3da
Ensure we set up production builds correctly
daledupreez Nov 16, 2023
232e5a9
Merge remote-tracking branch 'origin/trunk' into add/js-build-for-jet…
daledupreez Nov 16, 2023
90b72ea
Add docs for new build commands
obenland Nov 16, 2023
ec003ec
Better reflect folder structure
obenland Nov 16, 2023
13c5e76
Reset change pnpm-lock.yaml
daledupreez Nov 16, 2023
6d861f4
Update pnpm lock file
daledupreez Nov 16, 2023
f968f67
Update mu-wpcom-plugin
daledupreez Nov 16, 2023
9e0791f
Launchpad: Add `new_prompt` query param to Write first post task (#34…
sixhours Nov 16, 2023
2c0a191
Subscribe modal: remove filters and enable for Jetpack sites (#33909)
simison Nov 16, 2023
9ee445e
Merge branch 'trunk' into add/js-build-for-jetpack-wpcom-mu
daledupreez Nov 16, 2023
882158e
Add trailing slash
obenland Nov 16, 2023
348f3c4
Merge branch 'add/js-build-for-jetpack-wpcom-mu' of https://github.co…
obenland Nov 16, 2023
1696a90
Update build docs
daledupreez Nov 16, 2023
519deda
Merge branch 'trunk' into add/js-build-for-jetpack-wpcom-mu
okmttdhr Nov 24, 2023
7dbc2d0
Merge branch 'trunk' into add/js-build-for-jetpack-wpcom-mu
okmttdhr Dec 4, 2023
5ae7897
Update pnpm-lock.yaml
okmttdhr Dec 4, 2023
5e1e8c8
Update composer.lock
okmttdhr Dec 4, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 81 additions & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions projects/packages/jetpack-mu-wpcom/.gitattributes
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# Files not needed to be distributed in the package.
.gitattributes export-ignore
.github/ export-ignore
package.json export-ignore
.gitattributes export-ignore
.github/ export-ignore
package.json export-ignore

# Files to include in the mirror repo, but excluded via gitignore
# Remember to end all directories with `/**` to properly tag every file.
# /src/js/example.min.js production-include
src/build/** production-include

# Files to exclude from the mirror repo, but included in the monorepo.
# Remember to end all directories with `/**` to properly tag every file.
Expand Down
2 changes: 2 additions & 0 deletions projects/packages/jetpack-mu-wpcom/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.cache/
src/build/
vendor/
node_modules/
wordpress/
25 changes: 25 additions & 0 deletions projects/packages/jetpack-mu-wpcom/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,31 @@ If you plan on using this package in your WordPress plugin, we would recommend t

Need to report a security vulnerability? Go to [https://automattic.com/security/](https://automattic.com/security/) or directly to our security bug bounty site [https://hackerone.com/automattic](https://hackerone.com/automattic).

## Build System

_Note: `cd` to `projects/packages/jetpack-mu-wpcom` before running these commands_

- `npm run build-js`<br>
Compiles the plugins for development - the files are not minified and we produce a source map.

- `npm run build-production-js`<br>
Compiles the plugins for production - we produce minified files without source maps.

- `npm run clean`<br>
Removes all build files.

The entry point is:

- **Plugin**: `projects/packages/jetpack-mu-wpcom/src/features/{{feature-name}}/index.js`

The output is:

- **Plugin**: `/projects/packages/jetpack-mu-wpcom/src/build/{{feature-name}}/{{feature-name}}.js`

### Adding files to the build system

If you're adding a new feature that includes Javascript or Typescript, you will need to add the primary source file to the `entry` section in `projects/packages/jetpack-mu-wpcom/webpack.config.js`, where we'll use the key as the core file name, and the value as the primary input file for that module.

## License

jetpack-mu-wpcom is licensed under [GNU General Public License v2 (or later)](./LICENSE.txt)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Add initial JS and TS build logic
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Added Editor error handling from ETK
4 changes: 2 additions & 2 deletions projects/packages/jetpack-mu-wpcom/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
"test-php": [
"@composer phpunit"
],
"build-production": "echo 'Add your build step to composer.json, please!'",
"build-development": "echo 'Add your build step to composer.json, please!'",
"build-production": "pnpm run build-production-js",
"build-development": "pnpm run build-js",
"post-install-cmd": "WorDBless\\Composer\\InstallDropin::copy",
"post-update-cmd": "WorDBless\\Composer\\InstallDropin::copy"
},
Expand Down
22 changes: 18 additions & 4 deletions projects/packages/jetpack-mu-wpcom/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,24 @@
"author": "Automattic",
"scripts": {
"build": "echo 'Not implemented.'",
"build-js": "echo 'Not implemented.'",
"build-js": "pnpm clean && webpack",
"build-production": "echo 'Not implemented.'",
"build-production-js": "echo 'Not implemented.'",
"clean": "true"
"build-production-js": "NODE_ENV=production BABEL_ENV=production pnpm build-js",
"clean": "rm -rf src/build/"
},
"devDependencies": {}
"optionalDependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@automattic/jetpack-webpack-config": "workspace:*",
"typescript": "^5.0.4",
"webpack": "5.76.0",
"webpack-cli": "4.9.1"
},
"dependencies": {
"@sentry/browser": "7.80.1",
"@wordpress/api-fetch": "6.42.0",
"@wordpress/hooks": "3.45.0"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class Jetpack_Mu_Wpcom {

const PACKAGE_VERSION = '5.1.0-alpha';
const PKG_DIR = __DIR__ . '/../';
const BASE_DIR = __DIR__ . '/';
const BASE_FILE = __FILE__;

/**
* Initialize the class.
Expand Down Expand Up @@ -65,6 +67,8 @@ public static function load_features() {
require_once __DIR__ . '/features/100-year-plan/enhanced-ownership.php';
require_once __DIR__ . '/features/100-year-plan/locked-mode.php';

require_once __DIR__ . '/features/error-reporting/error-reporting.php';

require_once __DIR__ . '/features/media/heif-support.php';
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
<?php
/**
* Error reporting from wp-admin / Gutenberg context for Simple Sites and WoA.
*
* @package automattic/jetpack-mu-wpcom
*/

use Automattic\Jetpack\Jetpack_Mu_Wpcom;

/**
* Whether the site is eligible for Error Reporting, which is a feature that's specific to WPCOM.
*
* By default, sites should not be eligible.
*
* @return bool True if current site is eligible for error reporting, false otherwise.
*/
function wpcom_is_site_eligible_for_error_reporting() {
/**
* Can be used to toggle the Error Reporting functionality.
*
* @param bool true if Error Reporting should be enabled, false otherwise.
*/
return apply_filters( 'a8c_enable_error_reporting', false );
}

/**
* Inline error handler that will capture errors before the main handler has a chance to.
*
* Errors are pushed to a global array called `_jsErr` which is then verified in the main handler.
*
* @see index.js
*/
function wpcom_head_error_handler() {
?><script type="text/javascript">
window._headJsErrorHandler = function( errEvent ) {
window._jsErr = window._jsErr || [];
window._jsErr.push( errEvent );
}
window.addEventListener( 'error', window._headJsErrorHandler );
</script>
<?php
}

/**
* Limit the attribute to script elements that point to scripts served from s0.wp.com.
*
* We might want to add stats.wp.com and widgets.wp.com here, too. See https://wp.me/pMz3w-cCq#comment-86959.
* "Staticized" (aka minified or concatenaded) scripts don't go through this pipeline, so they are not processed
* by this filter. The attribute is added to those directly in jsconcat, see D57238-code.
*
* @param string $tag String containing the def of a script tag.
*/
function wpcom_add_crossorigin_to_script_elements( $tag ) {
$end_of_tag = strpos( $tag, '>' );
if ( false === $end_of_tag ) {
return $tag;
}

/*
* Get JUST the <script ...> tag, not anything else. $tag can include the content of the script as well.
* Assumes that $tag begins with <script..., which does seem to be the case in our testing.
*/
$script_tag = substr( $tag, 0, $end_of_tag + 1 );

// If the src of that script tag points to an internal domain, set crossorigin=anonymous.
if ( preg_match( '/<script.*src=.*(s0\.wp\.com|stats\.wp\.com|widgets\.wp\.com).*>/', $script_tag ) ) { // phpcs:disable WordPress.WP.EnqueuedResources.NonEnqueuedScript
// Update the src of the <script...> tag.
$new_tag = str_replace( ' src=', " crossorigin='anonymous' src=", $script_tag );

// Then, find the original script_tag within the ENTIRE $tag, and replace it with the updated version. Now the script includes crossorigin=anonymous.
return str_replace( $script_tag, $new_tag, $tag );
}

return $tag;
}

/**
* Temporary function to feature flag Sentry by segment.
*
* We'll be testing it on production (simple sites) for a while to see if it's feasible to
* activate it for all sites and perhaps get rid of our custom solution. If it works well,
* we'll activate for all simple sites and look into activating it for WoA, too.
*
* @param int $user_id The user id.
* @return bool
*/
function wpcom_user_in_sentry_test_segment( $user_id ) {
$current_segment = 10; // Segment of existing users that will get this feature in %.
$user_segment = $user_id % 100;

/*
* We get the last two digits of the user id and that will be used to decide in what
* segment the user is. i.e if current_segment is 10, then only ids that end in < 10
* will be considered part of the segment.
*/
return $user_segment < $current_segment;
}
Comment on lines +77 to +97
Copy link
Member

@okmttdhr okmttdhr Nov 24, 2023

Choose a reason for hiding this comment

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

Am I correct in understanding that this feature is disabled because user_id on Atomic is not linked to WordPress.com? I'm asking for my learning purposes 🙂 @daledupreez @obenland
PCYsg-Ewq-p2

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@okmttdhr, I think that @fullofcaffeine is best-placed to comment on why we're only running this on WPCOM Simple and haven't rolled the functionality out more broadly.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hi @okmttdhr! Yes, it's not running on AT. The original plan is to run on AT at some point, and we tried - see p4TIVU-9DI-p2#comment-10922 - but there were some problems. At the time, though, we hadn't implemented Sentry yet, and Sentry should work fine on AT, too. The challenge, though is how to treat errors from AT as AT is the wild west :D - sites can run all sorts of third-party code - so we should have a RFC before proceeding, and Sentry atm is not top-priority for WPCOM, AFAIK.


/**
* Return whether Sentry should be activated for a given user.
*
* In this phase, a12s have the possibility of configuring what error reporter to use
* through the sticker. a12s should not be covered by the segment logic.
*
* Regular users have the error reporter chosen based on the segmentation logic, only.
*
* @param int $user_id The user id. Used to check if the user is A8C or in the Sentry test segment.
* @param int $blog_id The blog ID. Usually the value of `get_current_blog_id`. Used to check if the sticker is applied if user is A8C.
*/
function wpcom_should_activate_sentry( $user_id, $blog_id ) {
return ( is_automattician( $user_id ) && has_blog_sticker( 'error-reporting-use-sentry', $blog_id ) )
|| ( ! is_automattician( $user_id ) && wpcom_user_in_sentry_test_segment( $user_id ) );
}

/**
* Enqueue assets
*/
function wpcom_enqueue_error_reporting_script() {
// Bail if ETK has enqueued its script.
if ( wp_script_is( 'a8c-fse-error-reporting-script' ) ) {
return;
}

$asset_file = include Jetpack_Mu_Wpcom::BASE_DIR . 'build/error-reporting/error-reporting.asset.php';
$script_dependencies = isset( $asset_file['dependencies'] ) ? $asset_file['dependencies'] : array();
$script_version = isset( $asset_file['version'] ) ? $asset_file['version'] : filemtime( Jetpack_Mu_Wpcom::BASE_DIR . 'build/error-reporting/error-reporting.js' );
$script_id = 'wpcom-error-reporting-script';

wp_enqueue_script(
$script_id,
plugins_url( 'build/error-reporting/error-reporting.js', Jetpack_Mu_Wpcom::BASE_FILE ),
$script_dependencies,
$script_version,
true
);

wp_localize_script(
$script_id,
'WPcom_Error_Reporting_Config',
array(
'shouldActivateSentry' => wpcom_should_activate_sentry( get_current_user_id(), get_current_blog_id() ) ? 'true' : 'false',
'releaseName' => defined( 'WPCOM_DEPLOYED_GIT_HASH' ) ? 'WPCOM_' . WPCOM_DEPLOYED_GIT_HASH : 'WPCOM_NO_RELEASE',
)
);
}

if ( wpcom_is_site_eligible_for_error_reporting() ) {
add_action( 'admin_print_scripts', 'wpcom_head_error_handler', 0 );
add_filter( 'script_loader_tag', 'wpcom_add_crossorigin_to_script_elements', 99, 2 );

// We load as last as possible for performance reasons. The head handler will capture errors until the main handler is loaded.
add_action( 'admin_enqueue_scripts', 'wpcom_enqueue_error_reporting_script', 100 );
}
Loading
Loading