“Cannot use import statement outside a module” JS error while adding a custom meta block?
-
20-05-2021 - |
Question
I am following the "Store Post Meta with a Block" guide from the official Block Editor Handbook to add a custom post meta block using the supplied sample code (below). However, the block does not load and a Uncaught SyntaxError: Cannot use import statement outside a module
error is displayed from the myguten.js
file in the console when loading the block editor page.
How can I resolve this? Is the WordPress Block Editor Handbook code incorrect?
myguten-meta-block.php
:
// register custom meta tag field
function myguten_register_post_meta() {
register_post_meta( 'post', 'myguten_meta_block_field', array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
) );
}
add_action( 'init', 'myguten_register_post_meta' );
function myguten_enqueue() {
wp_enqueue_script(
'myguten-script',
plugins_url( 'myguten.js', __FILE__ ),
array( 'wp-blocks', 'wp-element', 'wp-components', 'wp-data', 'wp-core-data', 'wp-block-editor' )
);
}
add_action( 'enqueue_block_editor_assets', 'myguten_enqueue' );
myguten.js
:
import { registerBlockType } from '@wordpress/blocks';
import { TextControl } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { useEntityProp } from '@wordpress/core-data';
import { useBlockProps } from '@wordpress/block-editor';
registerBlockType( 'myguten/meta-block', {
title: 'Meta Block',
icon: 'smiley',
category: 'text',
edit( { setAttributes, attributes } ) {
const blockProps = useBlockProps();
const postType = useSelect(
( select ) => select( 'core/editor' ).getCurrentPostType(),
[]
);
const [ meta, setMeta ] = useEntityProp( 'postType', postType, 'meta' );
const metaFieldValue = meta[ 'myguten_meta_block_field' ];
function updateMetaValue( newValue ) {
setMeta( { ...meta, myguten_meta_block_field: newValue } );
}
return (
<div { ...blockProps }>
<TextControl
label="Meta Block Field"
value={ metaFieldValue }
onChange={ updateMetaValue }
/>
</div>
);
},
// No information saved to the block
// Data is saved to post meta via the hook
save() {
return null;
},
} );
Pas de solution correcte
Autres conseils
You should use @wordpress/scripts so you can profit from modern JavaScript language features and JSX and transpile it to browser-compatible code. It's really not complicated to use.
Just install it via npm install @wordpress/scripts --save
and than you can transpile your source file like this wp-scripts build src/myguten.js.js --output--path=js
.
It's not only modern language features but versioning and dependency management that comes with it too. Readmore: https://medium.com/write-better-wordpress-code/properly-add-modern-javascript-to-gutenberg-14bde8679d83
I discovered this was occurring because I was using the supplied ESNext JavaScript code from the guide.
Although it is never once mentioned in the "Store Post Meta with a Block" guide, this page in a later section confirms the ESNext code must be "compiled" before it can be used.
Using the sample ES5 code from this page of the guide works.
( function ( wp ) {
var el = wp.element.createElement;
var registerBlockType = wp.blocks.registerBlockType;
var TextControl = wp.components.TextControl;
var useSelect = wp.data.useSelect;
var useEntityProp = wp.coreData.useEntityProp;
var useBlockProps = wp.blockEditor.useBlockProps;
registerBlockType( 'myguten/meta-block', {
title: 'Meta Block',
icon: 'smiley',
category: 'text',
edit: function ( props ) {
var blockProps = useBlockProps();
var postType = useSelect( function ( select ) {
return select( 'core/editor' ).getCurrentPostType();
}, [] );
var entityProp = useEntityProp( 'postType', postType, 'meta' );
var meta = entityProp[ 0 ];
var setMeta = entityProp[ 1 ];
var metaFieldValue = meta[ 'myguten_meta_block_field' ];
function updateMetaValue( newValue ) {
setMeta(
Object.assign( {}, meta, {
myguten_meta_block_field: newValue,
} )
);
}
return el(
'div',
blockProps,
el( TextControl, {
label: 'Meta Block Field',
value: metaFieldValue,
onChange: updateMetaValue,
} )
);
},
// No information saved to the block
// Data is saved to post meta via attributes
save: function () {
return null;
},
} );
} )( window.wp );