Skip to content

@wordpress/scripts: React.createElement type is invalid when two single block plugins are built using npm run build #24321

@bobbingwide

Description

@bobbingwide

Describe the bug
I've been attempting to develop a number of single block plugins.
I discovered that when all my plugins were built with npm run build then I got a variety of failures.

The first problem was

<p class="block-editor-warning__message">This block has encountered an error and cannot be previewed.</p>

which was accompanied by the following in the Console.

react.js?ver=16.9.0:260 Warning: React.createElement: type is invalid -- 
expected a string (for built-in components) or a class/function (for composite components) but got: undefined. 
You likely forgot to export your component from the file it's defined in, 
or you might have mixed up default and named imports.

For more information see: bobbingwide/sb-children-block#6

At other times I also saw:

Your site doesn't includes support for the "sb/sb-prevnext-block". 
You can leave this block intact, convert its content to a Custom HTML block, or remove it entirely. 

See bobbingwide/sb-prevnext-block#1

I have now reproduced the original problem with two very simple blocks

  1. esnext-example - the out of the box build
  2. sb-prevnext-block - with a tiny change to use <InspectorControls> - which also uses <Fragment>.

When sb-prevnext-block is built with npm start then it works.
When sb-prevnext-block is built with npm run build then it doesn't work.

I don't know if this is something that I am doing wrong, or something wrong with the build process.
I found similar problems had already been reported ( e.g. #23607 ) so I have developed the steps to reproduce the problem

Note: The problem is exacerbated by my ignorance of the build processes. In the two or so days I've spent battling this problem I have tried various alternative methods to perform the necessary imports. More often than not the solution worked when one of more of the plugins was built with npm start but failed when using npm run build.

I've tried to follow the instructions in the documentation, but still have many unanswered questions. I imagine that I have made a number of user errors along the way. If so, please can someone point them out so that I know what to do for the future.

To reproduce

Steps to reproduce the behavior:

  1. Generate the out of the box esnext-example plugin using npx @wordpress/create-block
  2. Activate the plugin, as the only activated plugin.
  3. Create a new page, using WordPress 5.4.2, with TwentyTwenty.
  4. Add the create-block/esnext-example block and Save.
  5. Generate the out of the box second plugin ( I used sb-prevnext-block plugin - see Create an sb/prevnext block to display Previous and Next links bobbingwide/sb-prevnext-block#1 )
  6. Activate this plugin as well
  7. Edit the page, add the sb/sb-prevnext-block and Save.
  8. The page should appear as in the screenshot.
  9. Now build the sb-prevnext-block plugin using npm run build.
  10. Refresh the page.
  11. The page should be as before.
  12. Now edit the src/edit.js file of the second plugin ( sb-prevnext-block in my case ) - see changes below.
  13. And rebuild with npm start.
  14. Refresh the page
  15. The page should be as before.
  16. Kill the build and rebuild with npm run build
  17. Refresh the page.
  18. The sb/sb-prevnext-block will fail.

Step 12. Changes to src\edit.js

  • Import Fragment and InspectorControls.
  • Wrap the original content in Fragment and insert an empty InspectorControls
The file will have its original line endings in your working directory
diff --git a/src/edit.js b/src/edit.js
index e72eb73..d3324d8 100644
--- a/src/edit.js
+++ b/src/edit.js
@@ -4,6 +4,8 @@
  * @see https://developer.wordpress.org/block-editor/packages/packages-i18n/
  */
 import { __ } from '@wordpress/i18n';
+import { Fragment} from '@wordpress/element';
+import { InspectorControls} from '@wordpress/editor';

 /**
  * Lets webpack process CSS, SASS or SCSS files referenced in JavaScript files.
@@ -26,8 +28,11 @@ import './editor.scss';
  */
 export default function Edit( { className } ) {
        return (
+               <Fragment>
+                       <InspectorControls></InspectorControls>
                <p className={ className }>
                        { __( 'PrevNext block <E2><80><93> hello from the editor!', 'sb' ) }
                </p>
+               </Fragment>
        );
 }

Step 16. Build output

> wp-scripts build

Hash: 8dce6bae283fa0442db6
Version: webpack 4.44.1
Time: 2018ms
Built at: 08/02/2020 7:46:34 PM
          Asset       Size  Chunks             Chunk Names
index.asset.php  159 bytes       0  [emitted]  index
      index.css   56 bytes       0  [emitted]  index
       index.js   2.43 KiB       0  [emitted]  index
style-index.css  101 bytes       1  [emitted]  style-index
Entrypoint index = style-index.css style-index.js index.css index.js index.asset.php
[0] external {"this":["wp","element"]} 42 bytes {0} [built]
[1] external {"this":["wp","i18n"]} 42 bytes {0} [built]
[2] external {"this":["wp","blocks"]} 42 bytes {0} [built]
[3] external {"this":["wp","editor"]} 42 bytes {0} [built]
[4] ./src/style.scss 39 bytes {1} [built]
[5] ./src/editor.scss 39 bytes {0} [built]
[6] ./src/index.js + 2 modules 4.01 KiB {0} [built]
    | ./src/index.js 2.04 KiB [built]
    | ./src/edit.js 1.26 KiB [built]
    | ./src/save.js 686 bytes [built]
    + 2 hidden modules

Expected behavior

Assuming that the code I've changed is correct, since it worked when built with npm start, then I'd expect the results to be the same as for the development build.

BUT, I have a number of questions

  • How should InspectorControls be imported and from where?
  • Ditto for Fragment... but I didn't get a problem when I only added Fragment
  • And again for ServerSideRender.
  • See table below.
  • When do I need to use npm install @wordpress/package-name --save?
  • Why do my SB blocks work when built with npm start when I haven't installed these packages?
In previous plugins I've used In the SB plugins I've been trying...
const Fragment = wp.element.Fragment; import { Fragment } from '@wordpress/element';
const {InspectorControls } } = wp.blockEditor; import { InspectorControls } from '@wordpress/block-editor';
ditto import { InspectorControls } from '@wordpress/editor';
const { ServerSideRender } = wp.editor import { ServerSideRender } from '@wordpress/editor';
ditto import { ServerSideRender } from '@wordpress/server-side-render';

All of the above seemed to be reasonable attempts to use the correct package name when referring to existing documentation.
References to be supplied.

Screenshots
Screenshot for step 8 - let's ignore the fact we can't see the text for now.
image

Screenshot for step 18.
image

Screenshot with WordPress 5.4.2 & Gutenberg 8.6.1
The text for the esnext-example block becomes visible with Gutenberg 8.6.1
image

Editor version (please complete the following information):
These are the results with the sb/sb-prevnext-block with the above modifications built using npm run build.

WordPress Gutenberg Results
5.4.2 No Fail
5.4.2 8.6.1 Fail
5.5-RC1 No Fail
5.5-RC1 8.6.1 Fail

The block works when built with npm start.

Desktop (please complete the following information):

  • OS: [e.g. iOS] Windows
  • Browser [e.g. chrome, safari] Chrome
  • Version [e.g. 22] l 84.0.4147.105 (Official Build) (64-bit)

Additional context
npm --version 6.14.5
node -v 10.13.0

From package.json

"devDependencies": {
		"@wordpress/scripts": "^12.1.1"
	},

Metadata

Metadata

Assignees

No one assigned

    Labels

    [Tool] WP Scripts/packages/scripts[Type] BugAn existing feature does not function as intended

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions