diff --git a/.gitignore b/.gitignore index 7abe46d8..e2d42cac 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,7 @@ jspm_packages/ assets/build/**/*.css assets/build/**/*.map assets/build/**/*.js +assets/build/**/*.php # PHPUnit result cache .phpunit.result.cache diff --git a/includes/assets.php b/includes/assets.php index cc0ad19b..6793e273 100644 --- a/includes/assets.php +++ b/includes/assets.php @@ -109,26 +109,149 @@ public function register_scripts() { $suffix = defined( 'SCF_DEVELOPMENT_MODE' ) && SCF_DEVELOPMENT_MODE ? '' : '.min'; $version = acf_get_setting( 'version' ); - // Register scripts. - wp_register_script( 'acf-pro-input', acf_get_url( 'assets/build/js/pro/acf-pro-input' . $suffix . '.js' ), array( 'acf-input' ), $version, true ); - wp_register_script( 'acf-pro-field-group', acf_get_url( 'assets/build/js/pro/acf-pro-field-group' . $suffix . '.js' ), array( 'acf-field-group' ), $version, true ); - wp_register_script( 'acf-pro-ui-options-page', acf_get_url( 'assets/build/js/pro/acf-pro-ui-options-page' . $suffix . '.js' ), array( 'acf-input' ), $version, true ); + // Define path patterns. + $js_path_patterns = array( + 'pro' => 'assets/build/js/pro/%s' . $suffix . '.js', + 'base' => 'assets/build/js/%s' . $suffix . '.js', + ); + $css_path_patterns = array( + 'pro' => 'assets/build/css/pro/%s.css', + 'base' => 'assets/build/css/%s' . $suffix . '.css', + ); + $asset_path_patterns = array( + 'pro' => 'assets/build/js/pro/%s.asset.php', + 'base' => 'assets/build/js/%s.asset.php', + ); - // Register styles. - wp_register_style( 'acf-pro-input', acf_get_url( 'assets/build/css/pro/acf-pro-input.css' ), array( 'acf-input' ), $version ); - wp_register_style( 'acf-pro-field-group', acf_get_url( 'assets/build/css/pro/acf-pro-field-group.css' ), array( 'acf-input' ), $version ); + // Define script registrations. + $scripts = array( + 'acf-pro-input' => array( + 'handle' => 'acf-pro-input', + 'src' => acf_get_url( sprintf( $js_path_patterns['pro'], 'acf-pro-input' ) ), + 'asset_file' => acf_get_path( sprintf( $asset_path_patterns['pro'], 'acf-pro-input' ) ), + 'deps' => array( 'acf-input' ), + 'version' => $version, + 'in_footer' => true, + ), + 'acf-pro-field-group' => array( + 'handle' => 'acf-pro-field-group', + 'src' => acf_get_url( sprintf( $js_path_patterns['pro'], 'acf-pro-field-group' ) ), + 'asset_file' => acf_get_path( sprintf( $asset_path_patterns['pro'], 'acf-pro-field-group' ) ), + 'deps' => array( 'acf-field-group' ), + 'version' => $version, + 'in_footer' => true, + ), + 'acf-pro-ui-options-page' => array( + 'handle' => 'acf-pro-ui-options-page', + 'src' => acf_get_url( sprintf( $js_path_patterns['pro'], 'acf-pro-ui-options-page' ) ), + 'asset_file' => acf_get_path( sprintf( $asset_path_patterns['pro'], 'acf-pro-ui-options-page' ) ), + 'deps' => array( 'acf-input' ), + 'version' => $version, + 'in_footer' => true, + ), + 'acf' => array( + 'handle' => 'acf', + 'src' => acf_get_url( sprintf( $js_path_patterns['base'], 'acf' ) ), + 'asset_file' => acf_get_path( sprintf( $asset_path_patterns['base'], 'acf' ) ), + 'deps' => array( 'jquery' ), + 'version' => $version, + 'in_footer' => false, + ), + 'acf-input' => array( + 'handle' => 'acf-input', + 'src' => acf_get_url( sprintf( $js_path_patterns['base'], 'acf-input' ) ), + 'asset_file' => acf_get_path( sprintf( $asset_path_patterns['base'], 'acf-input' ) ), + 'deps' => array( 'jquery', 'jquery-ui-sortable', 'jquery-ui-resizable', 'acf', 'wp-a11y' ), + 'version' => $version, + 'in_footer' => false, + ), + 'acf-field-group' => array( + 'handle' => 'acf-field-group', + 'src' => acf_get_url( sprintf( $js_path_patterns['base'], 'acf-field-group' ) ), + 'asset_file' => acf_get_path( sprintf( $asset_path_patterns['base'], 'acf-field-group' ) ), + 'deps' => array( 'acf-input' ), + 'version' => $version, + 'in_footer' => false, + ), + 'acf-internal-post-type' => array( + 'handle' => 'acf-internal-post-type', + 'src' => acf_get_url( sprintf( $js_path_patterns['base'], 'acf-internal-post-type' ) ), + 'asset_file' => acf_get_path( sprintf( $asset_path_patterns['base'], 'acf-internal-post-type' ) ), + 'deps' => array( 'acf-input' ), + 'version' => $version, + 'in_footer' => false, + ), + 'acf-escaped-html-notice' => array( + 'handle' => 'acf-escaped-html-notice', + 'src' => acf_get_url( sprintf( $js_path_patterns['base'], 'acf-escaped-html-notice' ) ), + 'asset_file' => acf_get_path( sprintf( $asset_path_patterns['base'], 'acf-escaped-html-notice' ) ), + 'deps' => array( 'jquery' ), + 'version' => $version, + 'in_footer' => true, + ), + ); + + // Define style registrations. + $styles = array( + 'acf-pro-input' => array( + 'handle' => 'acf-pro-input', + 'src' => acf_get_url( sprintf( $css_path_patterns['pro'], 'acf-pro-input' ) ), + 'deps' => array( 'acf-input' ), + 'version' => $version, + ), + 'acf-pro-field-group' => array( + 'handle' => 'acf-pro-field-group', + 'src' => acf_get_url( sprintf( $css_path_patterns['pro'], 'acf-pro-field-group' ) ), + 'deps' => array( 'acf-input' ), + 'version' => $version, + ), + 'acf-global' => array( + 'handle' => 'acf-global', + 'src' => acf_get_url( sprintf( $css_path_patterns['base'], 'acf-global' ) ), + 'deps' => array( 'dashicons' ), + 'version' => $version, + ), + 'acf-input' => array( + 'handle' => 'acf-input', + 'src' => acf_get_url( sprintf( $css_path_patterns['base'], 'acf-input' ) ), + 'deps' => array( 'acf-global' ), + 'version' => $version, + ), + 'acf-field-group' => array( + 'handle' => 'acf-field-group', + 'src' => acf_get_url( sprintf( $css_path_patterns['base'], 'acf-field-group' ) ), + 'deps' => array( 'acf-input' ), + 'version' => $version, + ), + ); // Register scripts. - wp_register_script( 'acf', acf_get_url( 'assets/build/js/acf' . $suffix . '.js' ), array( 'jquery' ), $version ); - wp_register_script( 'acf-input', acf_get_url( 'assets/build/js/acf-input' . $suffix . '.js' ), array( 'jquery', 'jquery-ui-sortable', 'jquery-ui-resizable', 'acf', 'wp-a11y' ), $version ); - wp_register_script( 'acf-field-group', acf_get_url( 'assets/build/js/acf-field-group' . $suffix . '.js' ), array( 'acf-input' ), $version ); - wp_register_script( 'acf-internal-post-type', acf_get_url( 'assets/build/js/acf-internal-post-type' . $suffix . '.js' ), array( 'acf-input' ), $version ); - wp_register_script( 'acf-escaped-html-notice', acf_get_url( 'assets/build/js/acf-escaped-html-notice' . $suffix . '.js' ), array( 'jquery' ), $version, true ); + foreach ( $scripts as $script ) { + // Load asset file if it exists. + $asset = file_exists( $script['asset_file'] ) ? require $script['asset_file'] : null; + + // Merge dependencies if asset file exists. + $deps = $asset ? array_merge( $asset['dependencies'], $script['deps'] ) : $script['deps']; + $ver = $asset ? $asset['version'] : $script['version']; + + wp_register_script( + $script['handle'], + $script['src'], + $deps, + $ver, + $script['in_footer'] + ); + } // Register styles. - wp_register_style( 'acf-global', acf_get_url( 'assets/build/css/acf-global' . $suffix . '.css' ), array( 'dashicons' ), $version ); - wp_register_style( 'acf-input', acf_get_url( 'assets/build/css/acf-input' . $suffix . '.css' ), array( 'acf-global' ), $version ); - wp_register_style( 'acf-field-group', acf_get_url( 'assets/build/css/acf-field-group' . $suffix . '.css' ), array( 'acf-input' ), $version ); + foreach ( $styles as $style ) { + wp_register_style( + $style['handle'], + $style['src'], + $style['deps'], + $style['version'] + ); + } /** * Fires after core scripts and styles have been registered. diff --git a/package.json b/package.json index d860116c..1a37d29c 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "@babel/core": "^7.25.8", "@babel/preset-env": "^7.25.8", "@babel/preset-react": "^7.25.7", + "@wordpress/dependency-extraction-webpack-plugin": "^6.20.0", "babel-loader": "^9.2.1", "css-loader": "^7.1.2", "css-minimizer-webpack-plugin": "^7.0.0", @@ -25,9 +26,9 @@ "sass-loader": "^16.0.2", "sort-package-json": "^2.14.0", "terser-webpack-plugin": "^5.3.10", - "webpack": "^5.95.0", + "webpack": "^5.98.0", "webpack-cli": "^5.1.4", - "webpack-fix-style-only-entries": "^0.6.1" + "webpack-remove-empty-scripts": "^1.0.4" }, "engines": { "node": ">=20.15.1", diff --git a/webpack.config.js b/webpack.config.js index e9290315..f82cbb57 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -2,28 +2,34 @@ const path = require('path'); const TerserPlugin = require('terser-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); -const FixStyleOnlyEntriesPlugin = require("webpack-fix-style-only-entries"); +const RemoveEmptyScriptsPlugin = require('webpack-remove-empty-scripts'); +const DependencyExtractionWebpackPlugin = require('@wordpress/dependency-extraction-webpack-plugin'); // Common configuration for both builds const commonConfig = { entry: { // JavaScript files - 'js/acf-escaped-html-notice': './assets/src/js/acf-escaped-html-notice.js', + 'js/acf-escaped-html-notice': + './assets/src/js/acf-escaped-html-notice.js', 'js/acf-field-group': './assets/src/js/acf-field-group.js', 'js/acf-input': './assets/src/js/acf-input.js', - 'js/acf-internal-post-type': './assets/src/js/acf-internal-post-type.js', + 'js/acf-internal-post-type': + './assets/src/js/acf-internal-post-type.js', 'js/acf': './assets/src/js/acf.js', 'js/pro/acf-pro-blocks': './assets/src/js/pro/acf-pro-blocks.js', - 'js/pro/acf-pro-field-group': './assets/src/js/pro/acf-pro-field-group.js', + 'js/pro/acf-pro-field-group': + './assets/src/js/pro/acf-pro-field-group.js', 'js/pro/acf-pro-input': './assets/src/js/pro/acf-pro-input.js', - 'js/pro/acf-pro-ui-options-page': './assets/src/js/pro/acf-pro-ui-options-page.js', + 'js/pro/acf-pro-ui-options-page': + './assets/src/js/pro/acf-pro-ui-options-page.js', // CSS files 'css/acf-dark': './assets/src/sass/acf-dark.scss', 'css/acf-field-group': './assets/src/sass/acf-field-group.scss', 'css/acf-global': './assets/src/sass/acf-global.scss', 'css/acf-input': './assets/src/sass/acf-input.scss', - 'css/pro/acf-pro-field-group': './assets/src/sass/pro/acf-pro-field-group.scss', + 'css/pro/acf-pro-field-group': + './assets/src/sass/pro/acf-pro-field-group.scss', 'css/pro/acf-pro-input': './assets/src/sass/pro/acf-pro-input.scss', }, output: { @@ -37,8 +43,8 @@ const commonConfig = { use: { loader: 'babel-loader', options: { - presets: ['@babel/preset-react'] - } + presets: ['@babel/preset-react'], + }, }, }, { @@ -53,7 +59,7 @@ const commonConfig = { }, 'sass-loader', ], - } + }, ], }, }; @@ -71,10 +77,14 @@ const unminifiedConfig = { minimize: false, // No minification for this config }, plugins: [ - new FixStyleOnlyEntriesPlugin(), + new RemoveEmptyScriptsPlugin(), new MiniCssExtractPlugin({ filename: '[name].css', // Output CSS as .css }), + new DependencyExtractionWebpackPlugin({ + injectPolyfill: true, + useCombinedAssetFile: true, + }), ], }; @@ -101,11 +111,15 @@ const minifiedConfig = { ], }, plugins: [ - new FixStyleOnlyEntriesPlugin(), - new MiniCssExtractPlugin({ - filename: '[name].min.css', // Changed to output .min.css files - }), - ], + new RemoveEmptyScriptsPlugin(), + new MiniCssExtractPlugin({ + filename: '[name].min.css', // Changed to output .min.css files + }), + new DependencyExtractionWebpackPlugin({ + injectPolyfill: true, + useCombinedAssetFile: true, + }), + ], }; // Export both configurations