The @wordpress/scripts package makes it easy to bundle your JavaScript for a plugin or theme and is especially helpful when developing custom blocks. In this post, I’ll show you how you can easily set up @wordpress/scripts and take advantage of the dependency management benefits it offers.
For this tutorial, we’ll be adding @wordpress/scripts to a simple block theme so we can develop some custom blocks and include those in our theme files. The project’s file structure is below for your reference:
themes/
my-block-theme/
assets/
src/
blocks/
custom-block-1/
block.json
edit.js
index.js
save.js
style.css
custom-block-2/
block.json
edit.js
index.js
save.js
style.css
patterns/
parts/
templates/
functions.php
style.cssPlaintextThe idea here is to use @wordpress/scripts as our “build process” for building the various files for these blocks and any others we might make in the project. This package uses Webpack and Babel (among other things) to build the files for your blocks and manage the necessary dependencies for those blocks. Once the block files are built, they just need to be enqueued in the block editor (along with any other scripts they depend on) and then your blocks will start being available for use.
To follow along with this tutorial, you’ll need a WordPress local environment set up on your computer and NodeJS/NPM need to be installed.
Need help setting up a local environment?
Check out my FREE course that shows you everything you need to get started developing locally with WordPress.
View CourseInstalling the @wordpress/scripts package
Before you can install any NPM packages, you need a package.json file. This file determines what npm packages your project is using and lets you define various tasks or scripts that you can use to build code, run tests, and more. The example theme here doesn’t have a package.json file yet but we can generate one easily using a simple command.
Start by opening a terminal in the theme’s folder (themes/my-block-theme):
npm initBashFrom here you’ll be prompted to enter some values. If you’re not sure what to enter for a given prompt, just hit enter to accept the default. Once you’ve done this, a new package.json file will be created in the folder where you ran the command and will look something like this:
{
"name": "my-block-theme",
"version": "1.0.0",
"description": "",
"main": "src/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Ian Svoboda",
"license": "ISC"
}JSONNext, install the @wordpress/scripts package as a dev dependency1 using the following command:
npm i @wordpress/scripts@latest -DBashOnce this completes, your package.json file will have a new “devDependencies” key that includes this package:
{
"name": "my-block-theme",
"version": "1.0.0",
"description": "",
"license": "ISC",
"author": "Ian Svoboda",
"main": "src/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"devDependencies": {
"@wordpress/scripts": "^31.2.0"
}
}JSONSetting up npm scripts
Next, you’ll need to add a few scripts to run this package’s commands. The scripts package has a lot of different built-in scripts, but for our purpose here you just need two. You can copy the below lines into the “scripts” key like so:
{
"name": "my-block-theme",
"version": "1.0.0",
"description": "",
"license": "ISC",
"author": "Ian Svoboda",
"main": "src/index.js",
"scripts": {
"build": "wp-scripts build",
"start": "wp-scripts start"
},
"devDependencies": {
"@wordpress/scripts": "^31.2.0"
}
}JSONThese can then be run in your terminal when needed like so:
npm run start
# or
npm run buildBashHere’s a quick explanation about the differences for each:
build
Build all files with all necessary optimization for production including minification and “tree-shaking”, which ensures your files are as small and quick to load as possible. This command should be run before you deploy your files to your website.
start
Build all files without optimizations and watch for changes. This is what you’ll be using as your actively working on the project.
Building the block files
By default, @wordpress/scripts will look in your src/ folder for any block.json files and then process the files referenced in those block.json files. This is great because it means there’s no extra work to do by default.
In our case, there are 2 custom blocks in this theme. They may have been generated using npx @wordpress/create-block, or maybe they were copied into the project from elsewhere. But since they’re in the src folder already, they will be found automatically by the build and start scripts. Sweet!
Run the npm run build command, and a new build folder will be placed in your theme folder that contains a folder for each of the custom blocks containing the built files for that block.
The exact files inside the build folder will vary depending on the block and how it’s configured. In addition to those built files, there will be one or more *.asset.php files that weren’t in your block’s original source folder. These are generated as part of the extraction of WordPress dependencies and are used to enqueue your block’s scripts in WordPress.
Registering blocks and enqueueing scripts
If you look closely, you may notice that your custom blocks are already registering the block using the registerBlockType function in the block’s index.js file. This is a “client-side registration” since JavaScript runs in the browser (aka the client) and not on the server like PHP does. But in order for that client-side registration to happen, the JavaScript file(s) need to be enqueued in WordPress.
I previously wrote an article that explains how to do this in more detail and it explains why registering on the client and the server is the current best practice. I’d recommend you give that a read also! For now though, we can proceed using a snippet of PHP to automatically register our blocks server-side, which will enqueue their files and ensure WordPress can “see” the blocks.
Add the below snippet to your theme’s functions.php file. Note: if you already have something in this file, you may need to erase the leading <?php!
<?php
function register_plugin_blocks() {
// Get the directory containing all blocks in the build folder.
$blocks_dir = __DIR__ . '/build/blocks/';
// Check if the directory is valid.
if ( is_dir( $blocks_dir ) ) {
$block_json_files = glob( $blocks_dir . '*/block.json' );
foreach ( $block_json_files as $filename ) {
register_block_type( $filename );
}
}
}
add_action( 'init', 'register_plugin_blocks' );And with that, your custom blocks are now visible in the block editor! This is a “set it and forget it” setup that will work automatically for any new blocks you add to the theme as well.
Happy Coding!
References
- @wordpress/scripts
- webpack
- Block Registration
- How to easily register all blocks in your theme or plugin
- How to use Dependency Extraction in webpack to make your scripts smaller
- This means that the package is used to build the project but isn’t used in the project itself. ↩︎