Skip to content

Commit

Permalink
i18n loader script: load script in the footer and defer it. (#38929)
Browse files Browse the repository at this point in the history
* i18n loader script: load script in the footer and defer it.

Related conversation: p55Cj4-3qL-p2

* Add 'add_data' mock

* Remove defer strategy

It won't be needed:
#38929 (review)

* Also add react-jsx-runtime to be loaded in footer

See #38929 (review)

Co-authored-by: Brad Jorsch <[email protected]>

* Add test to ensure add_data is being called

See #38929 (comment)

* Update changelog

---------

Co-authored-by: Brad Jorsch <[email protected]>
  • Loading branch information
jeherve and anomiex authored Aug 20, 2024
1 parent 7cdd5d2 commit 63cd636
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 6 deletions.
4 changes: 4 additions & 0 deletions projects/packages/assets/changelog/update-i18n-loader-footer
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: changed

i18n loader script & React JSX runtime: load scripts in the footer.
18 changes: 13 additions & 5 deletions projects/packages/assets/src/class-assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -510,31 +510,39 @@ public static function wp_default_scripts_hook( $wp_scripts ) {
}
$url = self::normalize_path( plugins_url( $path, __FILE__ ) );
$url = add_query_arg( 'minify', 'true', $url );
$wp_scripts->add( 'wp-jp-i18n-loader', $url, $asset['dependencies'], $asset['version'] );

$handle = 'wp-jp-i18n-loader';

$wp_scripts->add( $handle, $url, $asset['dependencies'], $asset['version'] );

// Ensure the script is loaded in the footer and deferred.
$wp_scripts->add_data( $handle, 'group', 1 );

if ( ! is_array( $data ) ||
! isset( $data['baseUrl'] ) || ! ( is_string( $data['baseUrl'] ) || false === $data['baseUrl'] ) ||
! isset( $data['locale'] ) || ! is_string( $data['locale'] ) ||
! isset( $data['domainMap'] ) || ! is_array( $data['domainMap'] ) ||
! isset( $data['domainPaths'] ) || ! is_array( $data['domainPaths'] )
) {
$wp_scripts->add_inline_script( 'wp-jp-i18n-loader', 'console.warn( "I18n state deleted by jetpack_i18n_state hook" );' );
$wp_scripts->add_inline_script( $handle, 'console.warn( "I18n state deleted by jetpack_i18n_state hook" );' );
} elseif ( ! $data['baseUrl'] ) {
$wp_scripts->add_inline_script( 'wp-jp-i18n-loader', 'console.warn( "Failed to determine languages base URL. Is WP_LANG_DIR in the WordPress root?" );' );
$wp_scripts->add_inline_script( $handle, 'console.warn( "Failed to determine languages base URL. Is WP_LANG_DIR in the WordPress root?" );' );
} else {
$data['domainMap'] = (object) $data['domainMap']; // Ensure it becomes a json object.
$data['domainPaths'] = (object) $data['domainPaths']; // Ensure it becomes a json object.
$wp_scripts->add_inline_script( 'wp-jp-i18n-loader', 'wp.jpI18nLoader.state = ' . wp_json_encode( $data, JSON_UNESCAPED_SLASHES ) . ';' );
$wp_scripts->add_inline_script( $handle, 'wp.jpI18nLoader.state = ' . wp_json_encode( $data, JSON_UNESCAPED_SLASHES ) . ';' );
}

// Deprecated state module: Depend on wp-i18n to ensure global `wp` exists and because anything needing this will need that too.
$wp_scripts->add( 'wp-jp-i18n-state', false, array( 'wp-deprecated', 'wp-jp-i18n-loader' ) );
$wp_scripts->add( 'wp-jp-i18n-state', false, array( 'wp-deprecated', $handle ) );
$wp_scripts->add_inline_script( 'wp-jp-i18n-state', 'wp.deprecated( "wp-jp-i18n-state", { alternative: "wp-jp-i18n-loader" } );' );
$wp_scripts->add_inline_script( 'wp-jp-i18n-state', 'wp.jpI18nState = wp.jpI18nLoader.state;' );

// Register the React JSX runtime script - used as a polyfill until we can update JSX transforms. See https://github.com/Automattic/jetpack/issues/38424.
// @todo Remove this when we drop support for WordPress 6.5, as well as the script inclusion in test_wp_default_scripts_hook.
$jsx_url = self::normalize_path( plugins_url( '../build/react-jsx-runtime.js', __FILE__ ) );
$wp_scripts->add( 'react-jsx-runtime', $jsx_url, array( 'react' ), '18.3.1', true );
$wp_scripts->add_data( 'react-jsx-runtime', 'group', 1 );
}

// endregion .
Expand Down
9 changes: 8 additions & 1 deletion projects/packages/assets/tests/php/test-assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,7 @@ function ( $v ) {

// @phan-suppress-next-line PhanDeprecatedFunction -- Keep using setMethods until we drop PHP 7.0 support.
$mock = $this->getMockBuilder( \stdClass::class )
->setMethods( array( 'add', 'add_inline_script' ) )
->setMethods( array( 'add', 'add_inline_script', 'add_data' ) )
->getMock();

// Unfortunately PHPUnit deprecated withConsecutive with no replacement, so we have to roll our own version.
Expand Down Expand Up @@ -785,6 +785,13 @@ function ( $value ) use ( $value_sets, $i ) {
array( 'wp-jp-i18n-state', 'wp.jpI18nState = wp.jpI18nLoader.state;' )
)
);
$mock->expects( $this->exactly( 2 ) )->method( 'add_data' )
->with(
...$with_consecutive(
array( 'wp-jp-i18n-loader', 'group', 1 ),
array( 'react-jsx-runtime', 'group', 1 )
)
);

// @phan-suppress-next-line PhanTypeMismatchArgument -- We don't have a WP_Scripts definition to create a mock from. 🤷
Assets::wp_default_scripts_hook( $mock );
Expand Down

0 comments on commit 63cd636

Please sign in to comment.