Gutenberg blocks without the build step

You can create Gutenberg blocks in ES6 code without the build step, this makes it easier to maintain and develop. I switched over my Code Syntax Highlighting block and am much happier for it.

All of the Gutenberg examples by default use ES5 code, which already does not require transpiling with webpack, but they also include ES6/ESNext syntax which does require the extra step.

The ES6 standard allows for cleaner code using a simpler syntax, and is a bit more powerful. It is becoming the most common style of JavaScript you see in tutorials and examples; and almost all of it includes the extra step to build using webpack and/or babel.

I’m here to tell you, life is much easier without that build step.

One caveat, even though ES6 standard came out in 2015, there is still one pesky browser which does not support it, I’m looking at you IE11. If you are concerned about maximum compatibility you will need the build step to transpile ES6 code to be compatible.

I’m going to follow Github’s lead and drop support for IE11, which they did in July 2018. Remember they are owned by Microsoft, the creator of IE11 who also wants everyone off that browser.

Even more importantly, the Gutenberg block I’m building only runs on the backend, or editor view, the code is not run for user’s reading a site, just the owner. So presumably, the author has a bit more control over their browser.

Make your code browser compatible

There are basically two pieces to address for ditching the Javascript build step for Gutenberg blocks, or most other React based systems, imports and JSX.

Imports

First imports, Browsers don’t support importing code the same way. So depending on what module you are importing, you will have to enqueue the script, which is simply the WordPress way to add a script tag. However, before you start including external code, try these other options first.

Use WordPress built-in modules

One of the nice things with Gutenberg is that most of the modules and imports you might need are already included in WordPress core. You can define your dependencies when you enqueue and they will be available to use. See the list of WordPress packages available, clicking into any package will show its documentation.

So in my example below, I’m going to use the wp.element.createElement function, I simply need to include wp-element in my dependencies list for enqueueing my block, which looks like this:

// Block.
wp_enqueue_script(
    'mkaz-code-syntax',
    plugins_url( $block_path, __FILE__ ),
    array( 'wp-blocks', 'wp-editor', 'wp-element', 'wp-i18n' ),
    filemtime( plugin_dir_path( __FILE__ ) . $block_path )
);

Do without

If what you want isn’t covered by the WordPress packages, I would next recommend trying to see if you can do without, life is better with less dependencies if possible. ES6 introduces many capabilities so pure Javascript is pretty powerful, see the following:

Use modules

ES6 does support loading modules, though the syntax is not as straight-forward, especially using WordPress. I’ve not had a need yet to use this technique, but here are a couple of resources for using modules in browsers

Remove JSX

The JSX syntax is used by React and Gutenberg to make it easier to create elements, in fact it looks so much like regular HTML, that it seems like that is all you are doing. However, there is a translation layer that converts what looks like HTML to what it truly is, JavaScript.

You can skip this translation, and just write it in JavaScript from the start. React has the createElement function which helps with this, WordPress wraps the function in the wp-element module.

The function signature is:

createElement( tag, props, children )

So in JSX syntax you might use:

return <div style={ color: 'red' }>Red text</div>;

Using the createElement function, you would use:

return wp.element.createElement( 'div', { color: 'red' }, 'Red text' );

You can create a convenience function at the top of your file:

const el = wp.element.createElement;

And then the code could simply be:

return el( 'div', { color: 'red' }, 'Red text' );

If you want to nest two tags:

JSX:

return <pre><code> your code here </code></pre>;

Using createElement:

return el( 'pre', {}, el( 'code', {}, 'your code here' ) );

I agree the JSX code looks a bit cleaner, however, with code formatting and indentation, it is still easy to follow what is happening in the createElement code.

You can see my Code Syntax Highlighting block which now has no build step. You can see the changes I made in PR #23 to remove.

Benefits

So why would you want to remove the build step? JSX syntax is cleaner, and it gives maximum compatability. For me, it is nice to not have that extra setup step, especially for a project I might not be developing often. It is lovely to just edit the JavaScript file and reload.

I don’t need to run npm install, update any dependencies, run watch or anything. No npm at all is worth it alone.

There is no minified code, so console errors display the line number that actually contain the error, no extra source maps or other pieces to worry about.

The build step also brings with it so many extra things. Removing this step, I was able to delete: .babelrc, webpack.config.js, package.json, node_modules, and .npmrc. Almost half the files in my repo were just around building the code.

Just editing JavaScript and reloading the browser, so simple. It almost makes coding in JavaScript fun, almost.