How to Use @wordpress/scripts when Creating a Gutenberg Block

Let’s begin with the understanding that you can not use regular JavaScript when creating blocks for Gutenberg. Well, you could try that but the code will be hardly readable. Believe me, I know what I’m talking about because I started learning blocks in 2019 with regular JavaScript without using what I am going to show you in this tutorial.

In this lesson we are about to create a project for our custom Gutenberg block and configure the development environment using @wordpress/scripts tool. This tool is what I use personally when I create any blocks either for my plugins or for my client projects.

What is JSX and Why We Need It So Bad?

In order to answer to the “Why” question let’s just take a look at this example from one of my very first tutorials about Gutenberg blocks (I decided to not update that tutorial for a reason).

So, there you can find a regular JavaScript implementation like this:

return (
	wp.element.createElement( wp.element.Fragment, {},
		wp.element.createElement( wp.editor.InspectorControls, {},
			wp.element.createElement( wp.editor.PanelColorSettings,
				{
					title: 'Awesome Color Options',
					colorSettings: [
						{
							colors: colorSamples,
							value: props.formColor.color,
							label: 'Form Color',
							onChange: props.setFormColor,
						}
					]
				},
			),
		),
		wp.element.createElement( 'div', { className: formClasses },
			wp.element.createElement( 'div', { className: 'misha-form-wrap' },
				wp.element.createElement( 'div', {},
					'Enter your email...'
				),
				wp.element.createElement( 'div', { style: buttonStyles },
					'Subscribe'
				)
			)
		)
	)
);

Of course in the tutorial I have it simplified a bit by assigning some constants like const el = wp.element.createElement() or const Fragment = wp.element.Fragment.

And now check how the same piece of code looks when written with JSX:

return (
	<Fragment>
		<InspectorControls>
			<PanelColorSettings
				title="Awesome Color Options"
				colorSettings={[
					{
						colors: colorSamples,
						value: props.formColor.color,
						label: 'Form Color',
						onChange: props.setFormColor,
					}
				]}
			/>
		</InspectorControls>
		<div className={ formClasses }>
			<div className="misha-form-wrap">
				<div>Enter your email...</div>
				<div style={ buttonStyles }>Subscribe</div>
			</div>
		</div>
	</Fragment>
)

Don’t you think that the second piece of code looks simple and kind of familiar?

Transform everything to JSX

Writing JavaScript code in JSX is like writing HTML. It is used not only by Gutenberg block developers but by any React developers.

It allows to transform this code presence:

wp.element.createElement( MyElement, props, children...  )

To this:

<MyElement prop={}>children</MyElement>

So every React (or Gutenberg) component now looks like HTML tag. And when you need some HTML tags inside your block then you just write HTML almost without changes.

Using imports

Sometimes when creating a block, you will need some Gutenberg components for it. It could be <InspectorControls> if you are about to create a panel with block settings or maybe just registerBlockType() function which is required for any block by the way.

Just start your JavaScript file with some import tags in order to make the components you need to become available inside the file.

import { Fragment } from "@wordpress/element";

import {
	InspectorControls,
	PanelColorSettings
} from '@wordpress/block-editor';

Think of it like an analogy to include() function in PHP.

How to Start Using JSX?

Okay, we’ve decided, JSX is great, but what are the pitfalls? There is the only one – browsers do not understand JSX. So usually we have two JavaScript files – one is for developers and another one is for browsers and we use either Webpack or Gulp to automatically generate the file for browsers (and also minify it along the way or do some other stuff if needed).

It may look like this:

Example of file structure for WordPress Gutenberg block when using @wordpress/scripts tool
We work with src/index.js file but when all is done or we just need to preview the result, we run some Webpack commands and build/index.js is being generated.

Configuring Webpack could be not the easiest thing to do but we don’t need it, because @wordpress/scripts does everything for us.

I also believe that struggling with this step is what stops other developers from creating blocks the correct way, so they become afraid of NodeJS, React and JavaScript and stick to creating Gutenberg blocks with PHP using some plugins like ACF which should never ever be used for that purpose!

Installing @wordpress/scripts

The good news here is that we only need one NPM module to install.

npm install @wordpress/scripts --save-dev

But before that check that your Node JS version is higher than 14.0 by running a command node --version and also that NPM version is 6.14.4 or above by running npm --version.

Difference between “wp-scripts start” and “wp-scripts build”

Once installation is done we have a bunch of scripts to use, but for the block creation we really need only two of them:

In order to have the possibility to run these scripts in the command line we need to add them into the package.json file which is a part of your project now.

"scripts": {
	"build": "wp-scripts build",
	"start": "wp-scripts start"
}

Once done, we can run the scripts using NPM command npm run <script name>.

Understanding the file structure

A little bit above I showed you an example of file structure:

Example of file structure for WordPress Gutenberg block when using @wordpress/scripts tool

So you can just create these two files and it is going to be pretty much it.

But it also supports some custom script names, but in this case you have to locate your block.json file in the src folder and then set one of the parameters – editorScript, script or viewScript. Example:

{
	"editorScript" : "file:editor.js"
}

And this is the file structure:

custom entry points for @wordpress/scripts
In any case we have to create everything in the src folder ourselves, files in the build folder will be generated by the tool.

This approach could be helpful when you have multiple blocks within a single WordPress plugin (or theme), but it is not the only way. We are going to talk about it in a separate lesson.

Misha Rudrastyh

Misha Rudrastyh

Hey guys and welcome to my website. For more than 10 years I've been doing my best to share with you some superb WordPress guides and tips for free.

Need some developer help? Contact me

Follow me on X