It fails when a handle has `wp_add_inline_script` associated with it
irshadahmad21 opened this issue · 0 comments
When associating some inline script for a handle using wp_add_inline_script
with $position
set to 'before'
, it results in failure of setting type="module"
for the script handle. Rather the type="module"
is added to the inline script, not the entrypoint.
Steps:
- Use this code
add_action( 'wp_enqueue_scripts', function (): void {
Vite\enqueue_asset(
__DIR__ . '/js/dist',
'js/src/main.ts',
[
'handle' => 'my-script-handle',
]
);
} );
// Add the inline script for the handle
wp_add_inline_script(
'my-script-handle',
sprintf( 'var myPluginData = %s;', $var, wp_json_encode( [ 'someData' => 'someValue' ] ) ),
'before'
);
- Run
vite
- Go to the page where the script is supposed to load
Expected behavior:
The script should load correctly.
Actual behavior:
It fails with an error in the console - Uncaught SyntaxError: Cannot use import statement outside a module
Reason
set_script_type_attribute
function assumes that there is only one <script>
tag rendered.
Lines 113 to 117 in bce4607
The fact is that the $tag
can contain more than one script handles:
<script id="my-script-handle-js-before">
var myPluginData = {"someData":"someValue"};
</script>
<script src="http://localhost:5173/js/src/main.ts" id="my-script-handle-js"></script>
So, when using $processor->next_tag( 'script' )
, it selects the first script, which is not desired here.
Solution
script_loader_tag
filter passes a third argument as $src
, which can be used to check if it matches the src
attribute of the script.
function set_script_type_attribute( string $target_handle, string $tag, string $handle, string $src ): string {
if ( $target_handle !== $handle ) {
return $tag;
}
$processor = new WP_HTML_Tag_Processor( $tag );
$script_fount = false;
do {
$script_fount = $processor->next_tag( 'script' );
} while ($processor->get_attribute( 'src' ) !== $src );
if ( $script_fount ) {
$processor->set_attribute( 'type', 'module' );
}
return $processor->get_updated_html();
}