admin管理员组

文章数量:1279182

I am trying to figure out how to only use css for the block/blocks actually used on the frontend. With my current setup everything is bundled into my build/frontend.css file and so just using one of multiple blocks loads all the css because it is all in the built frontend.css file. But if I for example only use a hero block, I only want the hero css to be loaded on the frontend, not the entire css file.

Here is a basic idea of my folder structure

build
  frontend.css
  frontend.js
src
  index.js
  frontend.css
  frontend.js
  hero
   -index.js
   -index.css
  callToAction
   -index.js
   -index.css
index.php

In my php file:

// only load the frontend css and js if there is a block using it
add_filter( 'should_load_separate_core_block_assets', '__return_true' );


add_action('init', 'custom_register_gutenberg_blocks');
function custom_register_gutenberg_blocks() {
    
    // register scripts - backend
    wp_register_script('custom-blocks-editor-scripts',
        plugins_url('build/index.js', __FILE__),
        array('wp-blocks', 'wp-i18n', 'wp-editor'),
        filemtime( plugin_dir_path( __FILE__ ) . 'build/index.js') // version
    );

    // register scripts - frontend
    wp_register_script('custom-blocks-frontend-scripts',
        plugins_url('build/frontend.js', __FILE__),
        array('wp-blocks', 'wp-i18n', 'wp-editor'),
    );

    // register styles - backend
    wp_register_style('custom-blocks-editor-style',
       plugins_url('build/index.css', __FILE__),
       array('wp-edit-blocks'),
    );

    // register styles - frontend
    wp_register_style('custom-blocks-frontend-styles', 
        plugins_url('build/frontend.css', __FILE__),
    );

   
    // Allow inlining small stylesheets on the frontend if possible.
    wp_style_add_data( 'custpm-blocks-frontend-styles', 'path', dirname( __FILE__ ) . '/frontend.css' );

   register_block_type('custom/hero', array(
        'editor_script' => 'custom-blocks-editor-scripts',
        'editor_style'  => 'custom-blocks-editor-style',
        'style' => 'custom-blocks-frontend-styles',
        'script' => 'custom-blocks-frontend-scripts',
        'render_callback' => 'custom_hero'
    ));
    
    function custom_hero($attributes) {
         ob_start(); ?>
           <div>
               Content output here
           </div>
        <?php return ob_get_clean();
    }
}

Then for example in my hero block I load the css file from the same folder

src/hero/index.js

import "./index.css";
import { registerBlockType } from "@wordpress/blocks";

registerBlockType("custom/hero", {
 // edit: (props) => {}
 // save: (props) => {}
});

So, the js files are loading the css just from their specific block folder but in the php I am calling the frontend.css file from the build folder.

I am trying to figure out how to only use css for the block/blocks actually used on the frontend. With my current setup everything is bundled into my build/frontend.css file and so just using one of multiple blocks loads all the css because it is all in the built frontend.css file. But if I for example only use a hero block, I only want the hero css to be loaded on the frontend, not the entire css file.

Here is a basic idea of my folder structure

build
  frontend.css
  frontend.js
src
  index.js
  frontend.css
  frontend.js
  hero
   -index.js
   -index.css
  callToAction
   -index.js
   -index.css
index.php

In my php file:

// only load the frontend css and js if there is a block using it
add_filter( 'should_load_separate_core_block_assets', '__return_true' );


add_action('init', 'custom_register_gutenberg_blocks');
function custom_register_gutenberg_blocks() {
    
    // register scripts - backend
    wp_register_script('custom-blocks-editor-scripts',
        plugins_url('build/index.js', __FILE__),
        array('wp-blocks', 'wp-i18n', 'wp-editor'),
        filemtime( plugin_dir_path( __FILE__ ) . 'build/index.js') // version
    );

    // register scripts - frontend
    wp_register_script('custom-blocks-frontend-scripts',
        plugins_url('build/frontend.js', __FILE__),
        array('wp-blocks', 'wp-i18n', 'wp-editor'),
    );

    // register styles - backend
    wp_register_style('custom-blocks-editor-style',
       plugins_url('build/index.css', __FILE__),
       array('wp-edit-blocks'),
    );

    // register styles - frontend
    wp_register_style('custom-blocks-frontend-styles', 
        plugins_url('build/frontend.css', __FILE__),
    );

   
    // Allow inlining small stylesheets on the frontend if possible.
    wp_style_add_data( 'custpm-blocks-frontend-styles', 'path', dirname( __FILE__ ) . '/frontend.css' );

   register_block_type('custom/hero', array(
        'editor_script' => 'custom-blocks-editor-scripts',
        'editor_style'  => 'custom-blocks-editor-style',
        'style' => 'custom-blocks-frontend-styles',
        'script' => 'custom-blocks-frontend-scripts',
        'render_callback' => 'custom_hero'
    ));
    
    function custom_hero($attributes) {
         ob_start(); ?>
           <div>
               Content output here
           </div>
        <?php return ob_get_clean();
    }
}

Then for example in my hero block I load the css file from the same folder

src/hero/index.js

import "./index.css";
import { registerBlockType } from "@wordpress/blocks";

registerBlockType("custom/hero", {
 // edit: (props) => {}
 // save: (props) => {}
});

So, the js files are loading the css just from their specific block folder but in the php I am calling the frontend.css file from the build folder.

Share Improve this question asked Nov 21, 2021 at 9:16 user8463989user8463989 5931 gold badge8 silver badges24 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 2

To get separate files for each block you'll need to bring your own webpack config

One as simple as this should work:

const defaultConfig = require('@wordpress/scripts/config/webpack.config');

module.exports = {
    ...defaultConfig,
    entry: {
        'hero': './src/hero',
        'call-to-action': './src/callToAction',
    },
};

Ryan Welcher has an example repo and a video walk-through of its creation (that link is to the part about creating the custom webpack config).

UPDATE: It turns out it is possible to get separate bundles without a custom webpack config but (with v19.1.0 of @wordpress/scripts) it will only work if the entry points have different filenames. That is, it will fail to include a file if another has the same name. For instance, this would build but foo/index.js would be left out:

"build:custom": "wp-scripts build foo/index.js bar/index.js"

Whereas this would work as expected:

"build:custom": "wp-scripts build foo/foo.js bar/bar.js"

本文标签: plugin developmentHow to only load css for used blocks on frontend