Make WordPress Core


Ignore:
Timestamp:
10/15/2025 05:38:25 AM (12 months ago)
Author:
westonruter
Message:

Bundled Themes: Introduce stylesheet minification for core block themes.

This introduces a build process to provide minified stylesheets for the Twenty Twenty-Two and Twenty Twenty-Five themes. The built minified CSS is not committed to version control. When SCRIPT_DEBUG is disabled, the minified style.min.css file will be enqueued to improve performance, including reducing render-blocking resources as well as facilitating inlining. See #63007.

  • Stylesheets are minified via the new core cssmin:themes Grunt task, which is automatically run as part of build:css.
  • The same build process is added to the themes (via package.json and package-lock.json) with build and watch commands; the postcss and cssnano development dependencies are used to handle CSS minification.
  • The functions.php in each theme is updated to enqueue style.min.css unless SCRIPT_DEBUG is enabled, in which case style.css is enqueued.
  • A notice comment is added to style.css to warn against editing the stylesheet since the minified version will likely be served instead.
  • A new contributing.txt file is added to each theme to document the build process for developers.
  • The test-and-zip-default-themes GitHub workflow is updated to install npm dependencies and build the minified assets before packaging the themes.
  • New PHPUnit tests are added to verify version number consistency across style.css, readme.txt, package.json, and package-lock.json files in default themes.

Developed in ​https://github.com/WordPress/wordpress-develop/pull/10081.

Props b1ink0, westonruter, shyamgadde, jonsurrell, sabernhardt, jorbin, peterwilsoncc, poena.
Fixes #63012.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/theme.php

    r60729 r60934  
    315315         * @ticket 48566
    316316         *
    317          * @dataProvider data_year_in_readme
     317         * @dataProvider data_provider_default_themes
    318318         */
    319319        public function test_year_in_readme( $theme ) {
    … …  
    337337        }
    338338
    339         public function data_year_in_readme() {
    340                 return array_map(
    341                         static function ( $theme ) {
    342                                 return array( $theme );
    343                         },
    344                         $this->default_themes
    345                 );
     339        /**
     340         * Data provider.
     341         *
     342         * @return array<string, array{ theme: string }>
     343         */
     344        public function data_provider_default_themes(): array {
     345                $data = array();
     346                foreach ( $this->default_themes as $default_theme ) {
     347                        $data[ $default_theme ] = array( 'theme' => $default_theme );
     348                }
     349                return $data;
     350        }
     351
     352        /**
     353         * Tests that the version number in style.css, readme.txt, and package.json all match.
     354         *
     355         * @ticket 63012
     356         *
     357         * @dataProvider data_provider_default_themes
     358         */
     359        public function test_version_consistency_in_package_json( string $theme ) {
     360                $wp_theme = wp_get_theme( $theme );
     361
     362                $path_to_style_css = $wp_theme->get_theme_root() . '/' . $wp_theme->get_stylesheet() . '/style.css';
     363                $this->assertFileExists( $path_to_style_css );
     364                $this->assertSame( 1, preg_match( '/^Version: (\d+\.\d+(?:\.\d+)?)$/m', file_get_contents( $path_to_style_css ), $matches ), 'Expected Version in style.css' );
     365                $style_version = $matches[1];
     366
     367                // Version in style.css does not use patch versions, so supply one of 0.
     368                $version_with_patch = $matches[1];
     369                if ( 1 === substr_count( $version_with_patch, '.' ) ) {
     370                        $version_with_patch .= '.0';
     371                }
     372
     373                $package_files         = array( 'package.json', 'package-lock.json' );
     374                $present_package_files = array();
     375                foreach ( $package_files as $package_file ) {
     376                        $path_to_package_json = $wp_theme->get_theme_root() . '/' . $wp_theme->get_stylesheet() . '/' . $package_file;
     377                        if ( file_exists( $path_to_package_json ) ) {
     378                                $present_package_files[] = $package_file;
     379
     380                                $data = json_decode( file_get_contents( $path_to_package_json ), true );
     381                                $this->assertIsArray( $data, "Expected $package_file to be an array." );
     382                                $this->assertArrayHasKey( 'name', $data, "Expected name key in $package_file." );
     383                                $this->assertSame( $theme, $data['name'], "Expected name field to be the theme slug in $package_file." );
     384                                $this->assertArrayHasKey( 'version', $data, "Expected version key in $package_file." );
     385                                $this->assertSame( $version_with_patch, $data['version'], "Expected version from style.css to match version in $package_file." );
     386
     387                                if ( 'package-lock.json' === $package_file && isset( $data['packages'][''] ) ) {
     388                                        $this->assertArrayHasKey( 'version', $data['packages'][''], "Expected version key in packages[''] in package-lock.json." );
     389                                        $this->assertSame( $version_with_patch, $data['packages']['']['version'], "Expected version from style.css to match packages[''].version in package-lock.json." );
     390                                }
     391                        }
     392                }
     393                if ( count( $present_package_files ) > 0 ) {
     394                        $this->assertCount( 2, $present_package_files, 'Expected package-lock.json to be present when package.json is present, and vice versa.' );
     395                }
     396
     397                // TODO: The themes twentyfifteen, twentysixteen, and twentyseventeen lack a Stable Tag in the readme.txt.
     398                $path_to_readme_txt = $wp_theme->get_theme_root() . '/' . $wp_theme->get_stylesheet() . '/readme.txt';
     399                $this->assertFileExists( $path_to_readme_txt );
     400                if ( 1 === preg_match( '/^Stable [Tt]ag: (\d+\.\d+(?:\.\d+)?)$/m', file_get_contents( $path_to_readme_txt ), $matches ) ) {
     401                        $readme_version = $matches[1];
     402                        $this->assertSame( $style_version, $readme_version, 'Expected version in style.css and stable tag in readme.txt to match.' );
     403                }
    346404        }
    347405
Note: See TracChangeset for help on using the changeset viewer.