kucrut / vite-for-wp

Vite integration for WordPress plugins and themes development.
GNU General Public License v2.0
260 stars 29 forks source link

It fails when a handle has `wp_add_inline_script` associated with it #76

Closed irshadahmad21 closed 5 months ago

irshadahmad21 commented 11 months ago

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:

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

https://github.com/kucrut/vite-for-wp/blob/bce4607bb57f4892da93492908caeb75ce2782a2/vite-for-wp.php#L113-L117

The fact is that the `$tag` can contain more than one script handles:
```html
<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();
}