Open nicholasio opened 2 years ago
todo: look into making this work for css for blocks as well.
Just in case it helps here is where / how we are generating the entrypoints of the CSS of blocks:
https://github.com/10up/10up-toolkit/blob/develop/packages/toolkit/config/webpack/entry.js#L43-L84
Upon further investigation (and after trying to come up with PoC for the original proposal) I realized we likely don't need this. For every css-only entry point 10up-toolkit is already generating a corresponding JS file that if enqueued would enable HMR for css.
So this can be solved at the wp-scaffold land. For front-end css the current approach to import css inside js entrypoints still works.
For blocks all we need to do is enqueue a the js version for every css entry point.
For instance, let's say we have the following block.json
{
"editorScript": "file:./index.js",
"editorStyle": "file:./editor.css",
"style": "file:./style.css",
"viewScript": "file:./view.js",
"script": "file:./script.js",
"version": "ddb93b251ea43170aa6fbfdff63ed3d0d2598792d0d65ee83373d9b740602f5a"
}
Toolkit currently generates the following files:
The style.js and editor.js files if loaded in WordPress will enable HMR for editor styles and front-end styles. We could modify how we're registering the blocks and manually enqueue those files if they exist and if SCRIPT_DEBUG
is true.
Alternatively, we could look if there's a way to use https://github.com/WordPress/wordpress-develop/blob/6.3/src/wp-includes/blocks.php#L393C30-L393C49 to ship an filter with toolkit hmr php file to handle this automagically.
quick PoC, dropping this in 10up-theme enables HMR for editor styles in the example block (without linaria).
add_filter( 'block_type_metadata_settings', function( $settings, $metadata ) {
if ( isset( $metadata['editorStyle'] ) && str_starts_with( $metadata['editorStyle'], 'file:' ) ) {
$editorStylePath = $metadata['editorStyle'];
$file = $metadata['file'];
$editorScriptFileName = basename( $metadata['editorScript'] );
$editorStyleFileName = str_replace( '.css', '.js', basename( $editorStylePath ) );
$dir = dirname( $file );
$js_hmr_file = $dir. '/' . str_replace( '.css', '.js', $editorStyleFileName );
if ( file_exists( $js_hmr_file ) && $editorScriptFileName !== $editorStyleFileName ) {
wp_register_script(
'css-hmr-editor-test-example',
TENUP_THEME_DIST_URL . 'blocks/example/editor.js',
[]
);
$settings['editor_script_handles'][] = 'css-hmr-editor-test-example';
}
}
return $settings;
}, 10, 2);
We can probably make this more generic and ship this alongside toolkit's fast-refresh.php
file
@nicholasio I tested this and generalized the PHP a bit. But sadly it was still not hot reloading the CSS for me 🤔
add_filter(
'block_type_metadata_settings',
static function( $settings, $metadata ) {
if ( isset( $metadata['editorStyle'] ) && str_starts_with( $metadata['editorStyle'], 'file:' ) ) {
$editor_style_path = $metadata['editorStyle'];
$file = $metadata['file'];
$editor_script_file_name = basename( $metadata['editorScript'] );
$editor_style_file_name = str_replace( '.css', '.js', basename( $editor_style_path ) );
$dir = dirname( $file );
$js_hmr_file = $dir . '/' . str_replace( '.css', '.js', $editor_style_file_name );
$script_index = count( $settings['editor_script_handles'] ) ?? 0;
$script_handle = generate_block_asset_handle( $metadata['name'], 'editorScript', $script_index );
if ( file_exists( $js_hmr_file ) && $editor_script_file_name !== $editor_style_file_name ) {
$script_asset = include str_replace( '.js', '.asset.php', $js_hmr_file );
$script_url = get_block_asset_url( $js_hmr_file );
wp_register_script(
$script_handle,
$script_url,
$script_asset['dependencies'],
$script_asset['version'],
true
);
$settings['editor_script_handles'][] = $script_handle;
}
}
return $settings;
},
10,
2
);
function get_block_asset_url( $path ) {
static $template_paths_norm = array();
$template = get_template();
if ( ! isset( $template_paths_norm[ $template ] ) ) {
$template_paths_norm[ $template ] = wp_normalize_path( get_template_directory() );
}
if ( str_starts_with( $path, trailingslashit( $template_paths_norm[ $template ] ) ) ) {
return get_theme_file_uri( str_replace( $template_paths_norm[ $template ], '', $path ) );
}
}
Is your enhancement related to a problem? Please describe.
Enable CSS Hot Reloading without explicit JS Entry points.
This needs a PoC but the overall idea would be to generate a dev-only custom JS entry point and automatically enqueue it via the generated PHP code so that end users don't have to manually create js entry points for every CSS entry point.
Designs
No response
Describe alternatives you've considered
No response
Code of Conduct