PHPackages                             humanmade/wp-scripts-asset-loader - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. humanmade/wp-scripts-asset-loader

ActiveWordpress-muplugin[Utility &amp; Helpers](/categories/utility)

humanmade/wp-scripts-asset-loader
=================================

Use WP Scripts to load compile and load global assets, custom blocks, and extend block assets

0.2.2(2mo ago)42.7k↓13.3%1[3 issues](https://github.com/humanmade/wp-scripts-asset-loader/issues)GPL-2.0-or-laterPHP

Since Dec 17Pushed 2mo agoCompare

[ Source](https://github.com/humanmade/wp-scripts-asset-loader)[ Packagist](https://packagist.org/packages/humanmade/wp-scripts-asset-loader)[ RSS](/packages/humanmade-wp-scripts-asset-loader/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (10)Dependencies (2)Versions (12)Used By (0)

wp-scripts-asset-loader
=======================

[](#wp-scripts-asset-loader)

Load assets generated by WP Scripts, allows overloading block.json to extend existing blocks and generate granular theme / plugin CSS as well as register new blocks

Overview
--------

[](#overview)

This package relies on using `@wordpress/scripts` as the build tool, with a custom approach to handling `block.json` files that enables both:

1. **Generating global CSS/JS assets** for a theme or plugin
2. **Extending existing blocks** (core WordPress blocks and third-party blocks)
3. **Registering new custom blocks** (theme-specific blocks)

This system allows you to add custom styles and scripts to core blocks without registering them as new blocks, while also supporting fully custom block registration and global CSS and JS via the same method.

The benefit is maintaining granular files that only load when needed, plus proper hash based asset versioning and compiling.

Build Tool: @wordpress/scripts
------------------------------

[](#build-tool-wordpressscripts)

This asset loader relies on the `@wordpress/scripts` package, which provides:

- Webpack configuration for bundling JavaScript and CSS
- Babel transpilation for modern JavaScript
- PostCSS processing for CSS (including autoprefixer)
- Development server with hot module replacement
- Production optimization (minification, tree-shaking)

Source Directory Structure
--------------------------

[](#source-directory-structure)

The assets source code is organized in the `src/` directory:

```
src/
├── blocks/
│   ├── my-namespace/           # Custom theme blocks
│   │   └── custom-block/
│   │       ├── block.json
│   │       ├── custom-block.js
│   │       ├── custom-block.scss
│   │       └── render.php
│   ├── core/           # Core block extensions
│   │   ├── button/
│   │   │   ├── block.json
│   │   │   ├── button.js
│   │   │   └── button.css
│   │   ├── paragraph/
│   │   ├── image/
│   │   └── ...
│   └── hubspot/        # Third-party block extensions
│       └── form/
│           ├── block.json
│           └── ...
└── global/
    ├── block.json
    ├── main.js
    ├── main.scss
    ├── editor.js
    ├── editor.scss
    └── js/

```

Build Output Structure
----------------------

[](#build-output-structure)

After running `npm run build`, compiled assets are output to the `build/` directory:

```
build/
├── blocks/
│   ├── my-namespace/
│   │   └── custom-block/
│   │       ├── block.json
│   │       ├── custom-block.js
│   │       ├── custom-block.asset.php
│   │       ├── custom-block.css
│   │       └── render.php
│   ├── core/
│   │   ├── button/
│   │   │   ├── block.json
│   │   │   ├── button.js
│   │   │   ├── button.asset.php
│   │   │   └── button.css
│   │   └── ...
│   └── hubspot/
└── global/
    ├── editor.js
    ├── editor.asset.php
    ├── editor.css
    ├── main.js
    ├── main.asset.php
    └── main.css

```

The block.json System
---------------------

[](#the-blockjson-system)

The theme uses `block.json` files to define both custom blocks and block extensions. The build process automatically discovers all `block.json` files in the source directory.

### Two Types of block.json Files

[](#two-types-of-blockjson-files)

#### 1. Custom Block Registration (with `title`)

[](#1-custom-block-registration-with-title)

Custom blocks include a `title` field in their `block.json`, which signals that this is a new block to register:

```
{
  "$schema": "https://schemas.wp.org/trunk/block.json",
  "apiVersion": 3,
  "name": "my-namespace/custom-block",
  "title": "Today's Date",
  "category": "text",
  "icon": "calendar-alt",
  "description": "Display today's date with customizable format.",
  "attributes": {
    "format": {
      "type": "string",
      "default": "F j, Y"
    }
  },
  "editorScript": "file:./custom-block.js",
  "style": "file:./custom-block.css",
  "render": "file:./render.php"
}
```

**Key characteristics:**

- Contains `title` field (this is the indicator)
- Contains full block metadata (category, icon, description, attributes)
- Registered via `register_block_type()` in PHP
- Creates a new block in the block inserter

#### 2. Block Extensions (without `title`)

[](#2-block-extensions-without-title)

Block extensions only contain the block name and asset references, without a `title`:

```
{
  "name": "core/button",
  "script": "file:./button.js",
  "style": "file:./button.css"
}
```

**Key characteristics:**

- No `title` field (this signals it's an extension)
- Only contains block name and asset paths
- Does not register a new block
- Adds custom styles/scripts to existing blocks
- Styles loaded via `wp_enqueue_block_style()`
- Scripts added via `block_type_metadata` filter

How wp-scripts Processes block.json
-----------------------------------

[](#how-wp-scripts-processes-blockjson)

The `@wordpress/scripts` build process:

1. **Discovery**: Scans the `src/` directory for any `block.json` files
2. **Entry Points**: For each `block.json`, creates webpack entry points for:
    - `editorScript` - JavaScript for the block editor
    - `script` - JavaScript for both editor and frontend
    - `viewScript` - JavaScript for frontend only
    - `style` - CSS for both editor and frontend
    - `editorStyle` - CSS for editor only
3. **Compilation**:
    - JavaScript files are transpiled with Babel and bundled
    - SCSS/CSS files are processed with PostCSS
    - Asset dependency files (`.asset.php`) are generated
4. **Output**: Compiled files maintain the same directory structure in `build/`

The Custom Override: extend\_block\_type\_metadata
--------------------------------------------------

[](#the-custom-override-extend_block_type_metadata)

The theme overloads the standard WordPress block registration process using the `block_type_metadata` filter.

### Usage

[](#usage)

```
new WP_Script_Asset_Loader(
    'my-asset-handle',
    '/path/to/build',
    'https://example.com/wp-content/themes/my-asset-handle/build'
);
```

Adding Global Assets
--------------------

[](#adding-global-assets)

To add global JavaScript or CSS assets for your theme or plugin, create a `block.json` in the `src/global/` directory and corresponding source files:

```
{
  "name": "my-theme-or-plugin/global",
  "script": "file:./main.js",
  "style": "file:./main.scss",
  "editorScript": "file:./editor.js",
  "editorStyle": "file:./editor.scss"
}
```

Adding New Custom Blocks
------------------------

[](#adding-new-custom-blocks)

To create a new custom block:

1. **Create block directory**:

    ```
    mkdir -p src/blocks/my-namespace/my-block
    ```
2. **Create block.json with title**:

    ```
    {
      "$schema": "https://schemas.wp.org/trunk/block.json",
      "apiVersion": 3,
      "name": "my-namespace/my-block",
      "title": "My Block",
      "category": "widgets",
      "icon": "star-filled",
      "editorScript": "file:./my-block.js",
      "style": "file:./my-block.scss"
    }
    ```
3. **Create JavaScript file** (`my-block.js`):

    ```
    import { registerBlockType } from '@wordpress/blocks';
    import { useBlockProps } from '@wordpress/block-editor';
    import './my-block.scss';

    const Edit = () => {
        const blockProps = useBlockProps();
        return My Block Content;
    };

    registerBlockType('my-namespace/my-block', {
        edit: Edit,
    });
    ```
4. **Create styles** (`my-block.scss`):

    ```
    .wp-block-my-namespace-my-block {
        padding: 1rem;
        background: var(--wp--preset--color--gold);
    }
    ```
5. **Build**:

    ```
    npm run build
    ```

The block will be automatically registered.

Extending Existing Blocks
-------------------------

[](#extending-existing-blocks)

To extend a core or third-party block:

1. **Create block directory**:

    ```
    mkdir -p src/blocks/core/heading
    ```
2. **Create block.json WITHOUT title**:

    ```
    {
      "name": "core/heading",
      "script": "file:./heading.js",
      "style": "file:./heading.scss"
    }
    ```
3. **Create JavaScript file** (`heading.js`):

    ```
    import { addFilter } from '@wordpress/hooks';
    import './heading.scss';

    // Modify the heading block's edit component
    addFilter(
        'editor.BlockEdit',
        'my-namespace/heading-extension',
        (BlockEdit) => (props) => {
            if (props.name !== 'core/heading') {
                return ;
            }
            // Add custom behavior
            return ;
        }
    );
    ```
4. **Create styles** (`heading.scss`):

    ```
    .wp-block-heading {
        &.custom-style {
            color: var(--wp--preset--color--gold);
        }
    }
    ```
5. **Build**:

    ```
    npm run build
    ```

The scripts will be automatically merged into the `core/heading` block registration via the `block_type_metadata` filter.

Build Process Internals
-----------------------

[](#build-process-internals)

### Entry Point Generation

[](#entry-point-generation)

`@wordpress/scripts` automatically generates webpack entry points from `block.json` files:

**For this block.json:**

```
{
  "name": "core/button",
  "script": "file:./button.js",
  "style": "file:./button.css"
}
```

**Webpack creates entries:**

- `blocks/core/button/button.js` → `build/blocks/core/button/button.js`
- `blocks/core/button/button.css` → `build/blocks/core/button/button.css`

### Asset Dependency Files

[](#asset-dependency-files)

For each JavaScript entry, wp-scripts generates a `.asset.php` file:

```
