Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gutenberg: Add a HMR & React Fast Refresh development mode. #23013

Closed
wants to merge 1 commit into from

Conversation

epiqueras
Copy link
Contributor

@epiqueras epiqueras commented Jun 9, 2020

Description

Closes #23013.

Background

Webpack Hot Module Replacement (HMR) is fundamentally at odds with the way we do script overriding in Gutenberg.

After lots of experimentation and failed attempts, I found that the best way to support it is to provide an alternative development mode on a per-page/app basis. For example, the site editor is its own page/app, and this PR enables an HMR mode for its development.

It should be trivial to reuse the same configurations for the post, widgets, and navigation editors.

I also included the new React Fast Refresh experience. The developer experience with this is fantastic. Even error resilience and recovery are flawless, both for runtime and syntax errors. It's nice to be able to iterate on a screen without resetting state.

Implementation

This PR introduces a new Webpack config for running the new dev server as an extension of the one provided by @wordpress/scripts.

Pages that wish to support an HMR mode, need to create a hot.js entry point like this PR does for edit-site. This entry point should initialize the page and load its root stylesheet.

On the server, we use a new config global, GUTENBERG_HMR, to determine whether to load the new script from the dev server or not. We manipulate this config variable effortlessly in the scripts introduced by this PR by using wp-env. It will enable it before running the new development mode, and disable it before running the old one. This makes it easy to switch between the two, but it does assume you are using wp-env to manage your environment.

How to test this?

  • Set up your environment using wp-env if you haven't yet.
  • Run npm run dev:edit-site.
  • Go to the site editor and see how it updates in response to your code changes without reloading.

Screenshots

gif

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • My code has proper inline documentation.
  • I've included developer documentation if appropriate.
  • I've updated all React Native files affected by any refactorings/renamings in this PR.

@epiqueras epiqueras added the [Type] Build Tooling Issues or PRs related to build tooling label Jun 9, 2020
@epiqueras epiqueras self-assigned this Jun 9, 2020
@epiqueras epiqueras requested a review from noahtallen June 9, 2020 04:15
@github-actions
Copy link

github-actions bot commented Jun 9, 2020

Size Change: 0 B

Total Size: 1.13 MB

ℹ️ View Unchanged
Filename Size Change
build/a11y/index.js 1.14 kB 0 B
build/annotations/index.js 3.62 kB 0 B
build/api-fetch/index.js 3.4 kB 0 B
build/autop/index.js 2.83 kB 0 B
build/blob/index.js 620 B 0 B
build/block-directory/index.js 6.77 kB 0 B
build/block-directory/style-rtl.css 892 B 0 B
build/block-directory/style.css 892 B 0 B
build/block-editor/index.js 106 kB 0 B
build/block-editor/style-rtl.css 11.4 kB 0 B
build/block-editor/style.css 11.4 kB 0 B
build/block-library/editor-rtl.css 7.88 kB 0 B
build/block-library/editor.css 7.89 kB 0 B
build/block-library/index.js 127 kB 0 B
build/block-library/style-rtl.css 7.72 kB 0 B
build/block-library/style.css 7.72 kB 0 B
build/block-library/theme-rtl.css 684 B 0 B
build/block-library/theme.css 686 B 0 B
build/block-serialization-default-parser/index.js 1.88 kB 0 B
build/block-serialization-spec-parser/index.js 3.1 kB 0 B
build/blocks/index.js 48.1 kB 0 B
build/components/index.js 194 kB 0 B
build/components/style-rtl.css 19.5 kB 0 B
build/components/style.css 19.5 kB 0 B
build/compose/index.js 9.31 kB 0 B
build/core-data/index.js 11.4 kB 0 B
build/data-controls/index.js 1.29 kB 0 B
build/data/index.js 8.45 kB 0 B
build/date/index.js 5.47 kB 0 B
build/deprecated/index.js 771 B 0 B
build/dom-ready/index.js 569 B 0 B
build/dom/index.js 3.17 kB 0 B
build/edit-navigation/index.js 8.25 kB 0 B
build/edit-navigation/style-rtl.css 918 B 0 B
build/edit-navigation/style.css 919 B 0 B
build/edit-post/index.js 303 kB 0 B
build/edit-post/style-rtl.css 5.6 kB 0 B
build/edit-post/style.css 5.6 kB 0 B
build/edit-site/index.js 15.5 kB 0 B
build/edit-site/style-rtl.css 2.96 kB 0 B
build/edit-site/style.css 2.96 kB 0 B
build/edit-widgets/index.js 9.34 kB 0 B
build/edit-widgets/style-rtl.css 2.4 kB 0 B
build/edit-widgets/style.css 2.4 kB 0 B
build/editor/editor-styles-rtl.css 425 B 0 B
build/editor/editor-styles.css 428 B 0 B
build/editor/index.js 44.8 kB 0 B
build/editor/style-rtl.css 4.26 kB 0 B
build/editor/style.css 4.27 kB 0 B
build/element/index.js 4.65 kB 0 B
build/escape-html/index.js 733 B 0 B
build/format-library/index.js 7.72 kB 0 B
build/format-library/style-rtl.css 502 B 0 B
build/format-library/style.css 502 B 0 B
build/hooks/index.js 2.13 kB 0 B
build/html-entities/index.js 621 B 0 B
build/i18n/index.js 3.56 kB 0 B
build/is-shallow-equal/index.js 711 B 0 B
build/keyboard-shortcuts/index.js 2.51 kB 0 B
build/keycodes/index.js 1.94 kB 0 B
build/list-reusable-blocks/index.js 3.12 kB 0 B
build/list-reusable-blocks/style-rtl.css 226 B 0 B
build/list-reusable-blocks/style.css 226 B 0 B
build/media-utils/index.js 5.3 kB 0 B
build/notices/index.js 1.79 kB 0 B
build/nux/index.js 3.41 kB 0 B
build/nux/style-rtl.css 616 B 0 B
build/nux/style.css 613 B 0 B
build/plugins/index.js 2.56 kB 0 B
build/primitives/index.js 1.5 kB 0 B
build/priority-queue/index.js 789 B 0 B
build/redux-routine/index.js 2.85 kB 0 B
build/rich-text/index.js 14.8 kB 0 B
build/server-side-render/index.js 2.68 kB 0 B
build/shortcode/index.js 1.7 kB 0 B
build/token-list/index.js 1.28 kB 0 B
build/url/index.js 4.06 kB 0 B
build/viewport/index.js 1.85 kB 0 B
build/warning/index.js 1.14 kB 0 B
build/wordcount/index.js 1.17 kB 0 B

compressed-size-action

@@ -0,0 +1,67 @@
/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any way we can bundle this in wp-scripts and offer support for third-party plugin devs too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely, I just wanted to stabilize it first.

Should I bundle it in in this PR or wait for more people who develop Gutenberg to use it and report potential issues?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, sounds like a reasonable plan to me.

cc @gziolo for awareness too.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice one. It’s super exciting to see that it can be integrated into Gutenberg 👍

@ItsJonQ
Copy link

ItsJonQ commented Jun 9, 2020

@epiqueras Absolutely amazing!! I tested this locally, and it worked as expected!

  • Used wp-env globally to wp-env start
  • Ran npm run dev:edit-site
  • Visit https://localhost:8888
  • Enabled Full site editing in Gutenberg experiments
  • Go to Site Editor
  • Change files
  • See the change ✨

@chrisvanpatten
Copy link
Contributor

I'm super excited about this, but I couldn't get it to work; I was getting "connection refused" errors on localhost:8081 so the editor couldn't load the file. I couldn't find any evidence that the port had already been allocated to another process either.

There were some warnings related to exports from Reakit not being found, but I'm not sure if those would be preventing the server from starting up or if it could be something else.

@epiqueras
Copy link
Contributor Author

That's probably why. Delete node modules and reinstall.

@chrisvanpatten
Copy link
Contributor

chrisvanpatten commented Jul 2, 2020

That's probably why. Delete node modules and reinstall.

I've done that three times now, once via npm ci and twice by deleting the folder. Also did npm cache clear --force and still nothing.

Here's the full set of errors…

WARNING in ./packages/components/build-module/alignment-matrix-control/index.js 82:23-32
"export 'Composite' was not found in 'reakit'
 @ ./packages/components/build-module/index.js
 @ ./packages/edit-site/src/plugins/index.js
 @ ./packages/edit-site/src/index.js
 @ ./packages/edit-site/hot.js
 @ multi ./node_modules/@pmmmwh/react-refresh-webpack-plugin/src/runtime/ReactRefreshEntry.js ./node_modules/@pmmmwh/react-refresh-webpack-plugin/src/runtime/ErrorOverlayEntry.js?sockPort=8081 ./packages/edit-site/hot.js

WARNING in ./packages/components/build-module/alignment-matrix-control/index.js 89:25-39
"export 'CompositeGroup' was not found in 'reakit'
 @ ./packages/components/build-module/index.js
 @ ./packages/edit-site/src/plugins/index.js
 @ ./packages/edit-site/src/index.js
 @ ./packages/edit-site/hot.js
 @ multi ./node_modules/@pmmmwh/react-refresh-webpack-plugin/src/runtime/ReactRefreshEntry.js ./node_modules/@pmmmwh/react-refresh-webpack-plugin/src/runtime/ErrorOverlayEntry.js?sockPort=8081 ./packages/edit-site/hot.js

WARNING in ./packages/components/build-module/alignment-matrix-control/cell.js 30:19-32
"export 'CompositeItem' was not found in 'reakit/Composite'
 @ ./packages/components/build-module/alignment-matrix-control/index.js
 @ ./packages/components/build-module/index.js
 @ ./packages/edit-site/src/plugins/index.js
 @ ./packages/edit-site/src/index.js
 @ ./packages/edit-site/hot.js
 @ multi ./node_modules/@pmmmwh/react-refresh-webpack-plugin/src/runtime/ReactRefreshEntry.js ./node_modules/@pmmmwh/react-refresh-webpack-plugin/src/runtime/ErrorOverlayEntry.js?sockPort=8081 ./packages/edit-site/hot.js

WARNING in ./packages/components/build-module/alignment-matrix-control/index.js 66:18-35
"export 'useCompositeState' was not found in 'reakit'
 @ ./packages/components/build-module/index.js
 @ ./packages/edit-site/src/plugins/index.js
 @ ./packages/edit-site/src/index.js
 @ ./packages/edit-site/hot.js
 @ multi ./node_modules/@pmmmwh/react-refresh-webpack-plugin/src/runtime/ReactRefreshEntry.js ./node_modules/@pmmmwh/react-refresh-webpack-plugin/src/runtime/ErrorOverlayEntry.js?sockPort=8081 ./packages/edit-site/hot.js

WARNING in ./packages/components/build-module/alignment-matrix-control/index.js 110:29-46
"export 'useCompositeState' was not found in 'reakit'
 @ ./packages/components/build-module/index.js
 @ ./packages/edit-site/src/plugins/index.js
 @ ./packages/edit-site/src/index.js
 @ ./packages/edit-site/hot.js
 @ multi ./node_modules/@pmmmwh/react-refresh-webpack-plugin/src/runtime/ReactRefreshEntry.js ./node_modules/@pmmmwh/react-refresh-webpack-plugin/src/runtime/ErrorOverlayEntry.js?sockPort=8081 ./packages/edit-site/hot.js
ℹ 「wdm」: Compiled with warnings.

@david-szabo97
Copy link
Member

david-szabo97 commented Nov 7, 2020

I was looking for HMR in Gutenberg but sadly found nothing. This would make the development a lot better!

  • I had the same problem as Chris, but running npm run build:packages before npm run dev:edit-site did the trick.
  • I also noticed that npm run dev:edit-site only rebuilds when something in /packages/edit-site changed. Can we get this working with all the modules? For example, if I make a change in packages/block-editor/src/components/inserter/menu.js then it should trigger the build. A quick hack that worked for me is running npm run dev and npm run dev:edit-site concurrently. First wait for npm run dev to finish then start the npm run dev:edit-site in another instance.

Changing the edit-site:dev to:

"dev:edit-site": "npm run build:packages && npm run hmr:on && concurrently \"wp-scripts start\" \"npm run dev:packages\" \"webpack-dev-server packages/edit-site/hot.js --config webpack.config.dev.js\"",

seems to fix the problem above.

@noahtallen
Copy link
Member

Superseded by #26922

@noahtallen noahtallen closed this Nov 12, 2020
@gziolo gziolo deleted the add/hmr-dev-mode branch November 13, 2020 05:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Status] In Progress Tracking issues with work in progress [Type] Build Tooling Issues or PRs related to build tooling
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants