Draftail extension wagtailcolourpicker stops working with webpack 4 (since wagtail 2.11)
See original GitHub issueIssue Summary
wagtailcolourpicker is a colour picker for Wagtail’s DraftJS editor. The project is archived but @Vadim-Karpenko managed it to work with later wagtail versions.
https://github.com/Vadim-Karpenko/wagtailcolourpicker
The plugin works fine with wagtail v2.10.2 but failed with v2.11. After some digging, I found that it failed with the webpack 4 upgrades for the v2.11. The last working commit is accdbd21742219a1e78660755b2630ca1b77334a, and failed since de2d66e08e6555dd69ca02eeb1a5d9f6ef5f07f7.
When clicking the text color icon on the draftail editor, the editor crashed with the below information.
Error: Element 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.
Check the render method of `DraftailEditor`.
Error: Element 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.
Check the render method of `DraftailEditor`.
at createFiberFromTypeAndProps (http://127.0.0.1:8001/static/wagtailadmin/js/vendor.js?v=63f5a5ce:35332:21)
at createFiberFromElement (http://127.0.0.1:8001/static/wagtailadmin/js/vendor.js?v=63f5a5ce:35355:15)
at updateElement (http://127.0.0.1:8001/static/wagtailadmin/js/vendor.js?v=63f5a5ce:24947:19)
at updateFromMap (http://127.0.0.1:8001/static/wagtailadmin/js/vendor.js?v=63f5a5ce:25108:20)
at reconcileChildrenArray (http://127.0.0.1:8001/static/wagtailadmin/js/vendor.js?v=63f5a5ce:25292:24)
at reconcileChildFibers (http://127.0.0.1:8001/static/wagtailadmin/js/vendor.js?v=63f5a5ce:25672:14)
at reconcileChildren (http://127.0.0.1:8001/static/wagtailadmin/js/vendor.js?v=63f5a5ce:28136:28)
at updateHostComponent (http://127.0.0.1:8001/static/wagtailadmin/js/vendor.js?v=63f5a5ce:28669:3)
at beginWork (http://127.0.0.1:8001/static/wagtailadmin/js/vendor.js?v=63f5a5ce:29994:14)
at HTMLUnknownElement.callCallback (http://127.0.0.1:8001/static/wagtailadmin/js/vendor.js?v=63f5a5ce:11555:14)
in div (created by DraftailEditor)
in DraftailEditor
in EditorFallback
Steps to Reproduce
- Start a new project with
wagtail start mysite
- Install a wagtail debug version, so you can see more React debug information
- Clone wagtail to a folder, say “…/wagtail”
- Checkout a commit
git checkout de2d66e08e6555dd69ca02eeb1a5d9f6ef5f07f7
- Build a debug version,
npm install --no-save && npm run watch
- Install the version,
pip install -e '../wagtail[testing,docs]'
- Install wagtailcolourpicker. To make it easier to debug, let’s install from the source “…/wagtailcolourpicker”
cd ..
git clone git@github.com:Vadim-Karpenko/wagtailcolourpicker.git
cd mysite
pip install -e '../wagtailcolourpicker'
- Add
"wagtailcolourpicker"
to theINSTALLED_APPS
- Add some colors to settings
WAGTAILCOLOURPICKER_COLOURS = {
"black": "#000000",
"blue": "#004d99",
"cyan": "#22b8cf",
"orange": "#fd7e14",
"purple": "#4f0862",
"spruce green": "#077452",
"red": "#c80813",
"white": "#fff",
}
WAGTAILCOLOURPICKER_COLOURS_FEATURES = ["colour_%s" % x[0] for x in WAGTAILCOLOURPICKER_COLOURS.items()]
WAGTAILADMIN_RICH_TEXT_EDITORS = {
"default": {
"WIDGET": "wagtail.admin.rich_text.DraftailRichTextArea",
"OPTIONS": {
"features": [
"bold",
"italic",
"underline",
"h2",
"h3",
"h4",
"ol",
"ul",
"hr",
"link",
"document-link",
"image",
"embed",
"textcolour",
*WAGTAILCOLOURPICKER_COLOURS_FEATURES,
]
},
},
}
- Create a model with a RichTextBlock
from django.db import models
from wagtail.admin.edit_handlers import StreamFieldPanel
from wagtail.core.blocks import RichTextBlock
from wagtail.core.fields import StreamField
from wagtail.core.models import Page
class HomePage(Page):
pass
class BasicPage(Page):
body = StreamField([
('rich_text', RichTextBlock())
])
# show in menu ticked by default
show_in_menus_default = True
content_panels = Page.content_panels + [
StreamFieldPanel('body'),
]
- Run
python manage.py migrate
- Start the server
- Go to the admin backend, create the new page. Click the
Text Colour
icon on the draftail editor toolbar. You will see the error above.
Any other relevant information. For example, why do you consider this a bug and what did you expect to happen instead?
Now rebuild the wagtail with commit accdbd21742219a1e78660755b2630ca1b77334a, you will see the plugin works again.
- I have confirmed that this issue can be reproduced as described on a fresh Wagtail project: (yes)
Technical details
- Python version: Python 3.6.9
- Django version: v3.1.5
- Wagtail version: See above
- Browser version: Chrome 87
Issue Analytics
- State:
- Created 3 years ago
- Comments:8 (3 by maintainers)
Top GitHub Comments
I’m currently completely swamped so haven’t had time to look at this any further, even though this seems like a big bug to me. It probably makes Wagtail 2.11 unusable for people who rely on those APIs.
If others want to take a look please feel free to – for me I’ll return to this on Friday 19th of Feb, one week from now.
Thank you for the report @favoyang! It’s pretty clear from your description that something is broken since the Webpack 4 config changes, although it’s unclear to me what exactly.
Investigating this with a dummy extension, the issue seems to be with the
draftail.js
bundle being executed twice – once before the plugin loads, and once after. That second run will reset the client-side registry of Draftail plugins, thereby causing the crash when the editor attempts to display the correct plugin’ssource
component.I’ll spend more time on this tomorrow to figure out why the Webpack switch caused this, and what options we have to fix it.