Open Chrico opened 2 years ago
Import Assertions - proposal for syntax to import ES modules with assertions for JSON is at stage 3, which means it will become a standard feature of the language pretty soon. I hope that it gets a nice integration with bundlers and that all unused properties of the imported JSON files would get eliminated during the phase of code minification.
You are correct about the WordPress core and the fact that only the name
is being used on the client. It's also reflected in the official documentation for building custom blocks:
import { registerBlockType } from '@wordpress/blocks';
import './style.scss';
import Edit from './edit';
import save from './save';
import metadata from './block.json';
registerBlockType( metadata.name, {
/**
* @see ./edit.js
*/
edit: Edit,
/**
* @see ./save.js
*/
save,
} );
Still, we don't have anything in place that would eliminate all other properties loaded from the block.json
file.
It's more nuanced for the Gutenberg plugin, where we sometimes have to read some newly added fields from block.json
until they are exposed from the server with wp.blocks.unstable__bootstrapServerSideBlockDefinitions()
in all supported WordPress versions. The interesting bit is when you use the standalone version of the block editor (with mobile apps based on React Native, or in Storybook) then all block settings are sourced from block.json
.
Concluding, it's definitely possible to remove unused code loaded from block.json
in the context of WordPress core but it might be quite a challenge to do it in a fashion that accounts for the edge cases I mentioned above.
Thanks for your feedback.
One question which comes up: Does your code example even work? When looking into the /packages/blocks/src/api/registration.js#L265-L269
function i can see, that only values are merged when you provide an object as first param to registerBlockType()
. So your example should be:
import { registerBlockType } from '@wordpress/blocks';
import './style.scss';
import Edit from './edit';
import save from './save';
import metadata from './block.json';
registerBlockType( {name: metadata.name}, {
/**
* @see ./edit.js
*/
edit: Edit,
/**
* @see ./save.js
*/
save,
} );
The first param takes the block name (string
) or the block metadata (object
). Both examples would work the same after all.
The first param takes the block name (string) or the block metadata (object). Both examples would work the same after all.
yes, but the sync with the server side settings via unstable__bootstrapServerSideBlockDefinitions()
only works when blockNameOrMetadata
is an object
, right? :)
The first param takes the block name (string) or the block metadata (object). Both examples would work the same after all.
yes, but the sync with the server side settings via
unstable__bootstrapServerSideBlockDefinitions()
only works whenblockNameOrMetadata
is anobject
, right? :)
It's called on the server first. If it's called from registerBlockType
for the second time, it's doing some checks to ensure it doesn't override values set on the server.
What problem does this address?
Right now Gutenberg allows to register via
block.json
-file the Blocks on server side. This data is printed as inline script in /lib/experimental/editor-settings.php#L71 towp.blocks.unstable__bootstrapServerSideBlockDefinitions()
.On client side, this function is being used to merge the client side code with the server side code, to be in sync. A common usage is:
client side
while the exported data of this
index.js
is being used in the end inregisterBlockType( { name, ...metadata }, settings );
.There is some data redundancy on client side when the
block.json
-file is loaded again viaimport metadata from './block.json'
and part of the final JS build, while the data is already loaded on server side, localized and availble.What is your proposed solution?
The proposed solution is to not import the complete
block.json
again and build into the final JS file. Instead it is enough to simply have:The rest of the
block.json
metadata is filled up from localized data comming from server side.I'm wondering if there is any chance to still have something like
import {name} from './block.json';
and optimize the build script to strip the JSON data down to just contain the{name: 'core/....'}
assigned to theblockName
-variable.Additional info
Doing some quick sum up of
block.json
-files (94 files) from/block-library/blocks/
brings us to nearly 100 Kb (not minified) of JSON data which is build into the final JS file: