diff --git a/assets/apps/components/config/custom-plugins.js b/assets/apps/components/config/custom-plugins.js new file mode 100644 index 0000000000..26b9319401 --- /dev/null +++ b/assets/apps/components/config/custom-plugins.js @@ -0,0 +1,84 @@ +const path = require('path'); + +/** + * This plugin appends the non-entrypoint JS chunk file names to the asset files generated by the DependencyExtractionWebpackPlugin. + * + * This mostly used to load translation files for the non-entrypoint JS chunks. + */ +class ChunksNameAssetAppendPlugin { + apply(compiler) { + compiler.hooks.compilation.tap( + 'EntrypointChunksPlugin', + (compilation) => { + compilation.hooks.processAssets.tapAsync( + { + name: 'EntrypointChunksPlugin', + stage: compiler.webpack.Compilation + .PROCESS_ASSETS_STAGE_ANALYSE, + }, + (assets, callback) => { + // Get entrypoint names + const entrypoints = Array.from( + compilation.entrypoints.keys() + ); + + // Collecting non-entrypoint JS chunk file names + const jsChunkFiles = Object.keys(assets).filter( + (file) => + file.endsWith('.js') && + !entrypoints.includes( + path.basename(file, '.js') + ) + ); + + if (jsChunkFiles.length === 0) { + callback(); + return; + } + + // Manually constructing the array string for PHP + const jsChunkFilesArrayString = + 'array(' + + jsChunkFiles.map((file) => `'${file}'`).join(', ') + + ')'; + + // Process each asset + for (const assetName in assets) { + if (assetName.endsWith('.asset.php')) { + // Modify asset content + const assetContent = assets[assetName].source(); + const modifiedContent = assetContent.replace( + ' ${jsChunkFilesArrayString},` + ); + + /* eslint-disable no-console */ + console.log( + '\n\x1b[35m%s\x1b[0m \x1b[0m%s\x1b[0m \x1b[36m%s\x1b[0m \x1b[33m%s\x1b[0m\n', + '[Neve Webpack Plugin][ChunksNameAssetAppendPlugin]', + assetName, + 'has been changed to include the following file chunks name as array:', + jsChunkFilesArrayString + ); + + // Updating the asset in the compilation + compilation.updateAsset( + assetName, + new compiler.webpack.sources.RawSource( + modifiedContent + ) + ); + } + } + + callback(); + } + ); + } + ); + } +} + +module.exports = { + ChunksNameAssetAppendPlugin, +}; diff --git a/assets/apps/components/config/webpack.config.js b/assets/apps/components/config/webpack.config.js index 9c25fa2200..fa85ec59eb 100644 --- a/assets/apps/components/config/webpack.config.js +++ b/assets/apps/components/config/webpack.config.js @@ -1,5 +1,6 @@ const DependencyExtractionWebpackPlugin = require('@wordpress/dependency-extraction-webpack-plugin'); const config = require('@wordpress/scripts/config/webpack.config'); +const customPlugins = require('./custom-plugins'); const plugins = [ ...config.plugins.filter( @@ -19,6 +20,7 @@ const plugins = [ } }, }), + new customPlugins.ChunksNameAssetAppendPlugin(), ]; module.exports = (env) => { diff --git a/inc/core/admin.php b/inc/core/admin.php index 225ef585c7..6df98ea755 100644 --- a/inc/core/admin.php +++ b/inc/core/admin.php @@ -188,6 +188,19 @@ public function register_react_components() { ] ); wp_set_script_translations( 'neve-components', 'neve' ); + + foreach ( $deps['chunks'] as $chunk_file ) { + + $chunk_handle = 'neve-components-chunk-' . $chunk_file; + wp_register_script( $chunk_handle, trailingslashit( NEVE_ASSETS_URL ) . 'apps/components/build/' . $chunk_file, [], $deps['version'], true ); + wp_enqueue_script( $chunk_handle ); + + if ( function_exists( 'wp_set_script_translations' ) ) { + wp_set_script_translations( $chunk_handle, 'neve' ); + } + } + + wp_register_style( 'neve-components', trailingslashit( NEVE_ASSETS_URL ) . 'apps/components/build/style-components.css', [ 'wp-components' ], $deps['version'] ); wp_add_inline_style( 'neve-components', Dynamic_Css::get_root_css() ); } diff --git a/inc/customizer/loader.php b/inc/customizer/loader.php index 1389713447..6a3f79c4a5 100644 --- a/inc/customizer/loader.php +++ b/inc/customizer/loader.php @@ -165,18 +165,11 @@ public function enqueue_customizer_controls() { wp_register_style( 'react-controls', $bundle_path . 'style-controls.css', [ 'neve-components' ], $dependencies['version'] ); wp_style_add_data( 'react-controls', 'rtl', 'replace' ); wp_enqueue_style( 'react-controls' ); - - // Automatically detect, register, and enqueue js chunk scripts with translations. - $build_path = get_template_directory() . '/assets/apps/customizer-controls/build/'; - $js_chunk_files = glob( $build_path . '*.js' ); - foreach ( $js_chunk_files as $chunk_file ) { - if ( 'controls.js' === basename( $chunk_file ) ) { - continue; - } + foreach ( $dependencies['chunks'] as $chunk_file ) { - $chunk_handle = 'neve-customizer-chunk-' . basename( $chunk_file, '.js' ); - wp_register_script( $chunk_handle, $bundle_path . basename( $chunk_file ), [], $dependencies['version'], true ); + $chunk_handle = 'neve-customizer-chunk-' . $chunk_file; + wp_register_script( $chunk_handle, $bundle_path . $chunk_file, [], $dependencies['version'], true ); wp_enqueue_script( $chunk_handle ); if ( function_exists( 'wp_set_script_translations' ) ) {