-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Implement webpack hot module reloading. #4121
Conversation
…g into try/implement-webpack-hmr
That is amazing! |
define( 'GUTENBERG_WEBPACK_HMR', true ); | ||
``` | ||
|
||
Build the project ( `npm run build` ), and start the hmr development server by running `npm run hot`. Any changes to files used by the editor ( `/editor` ), should be reflected in the browser without reloading the page. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Should it be a requirement to
npm run build
first, or can this be part of thehot
script? - Should HMR be built into
npm run dev
? - At first I was confused into thinking
/editor
was the URL path, not the relative path from the repository. Not sure I have any suggestions here, aside from either assigning as a link to the absolute repository path or prefixing to clarify relative filesystem path (./editor
)
If the Webpack server is running on a different port than 3000, you need to configure Gutenberg to refer to the correct port. You can do this using the `GUTENBERG_WEBPACK_DEV_SERVER` constant: | ||
|
||
```php | ||
define( 'GUTENBERG_WEBPACK_DEV_SERVER', 'http://localhost:[your-port]' ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we overload the GUTENBERG_WEBPACK_HMR
into supporting the default and overriding?
i.e.
<?php
// These are the same:
define( 'GUTENBERG_WEBPACK_HMR', true );
define( 'GUTENBERG_WEBPACK_HMR', 'http://localhost:3000' );
define( 'GUTENBERG_WEBPACK_DEV_SERVER', 'http://localhost:[your-port]' ); | ||
``` | ||
|
||
*Warning*: This is still an experimental development feature. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I foresee this note lingering long past when it should, and would discourage introducing it in the first place.
); | ||
return; | ||
if ( module.hot ) { | ||
delete( blocks[ name ] ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
delete
is a keyword, not a function, and while I expect this should work as-is, the syntax could lead to confusion. I'd suggest:
delete blocks[ name ];
'Block "' + name + '" is already registered.' | ||
); | ||
return; | ||
if ( module.hot ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a huge fan of any code aside from the entry point file being HMR-aware, but I suppose this is a consequence of us having implemented the block registry as a shared singleton?
@@ -46,6 +46,15 @@ window.jQuery( document ).on( 'heartbeat-tick', ( event, response ) => { | |||
} | |||
} ); | |||
|
|||
const render = ( Component, props, target ) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file is starting to get muddied with various rendering implementations. I'd suggest:
- Create a DocBlock explaining the purpose of this function
- Maybe rename as
renderEditor
, so we can avoid import assignment ofelRender
, and assume the first argument is theEditor
component (since it's not used any other way).
array( 'wp-element', 'wp-components', 'wp-utils', 'wp-hooks', 'wp-i18n', 'tinymce-latest', 'tinymce-latest-lists', 'tinymce-latest-paste', 'tinymce-latest-table', 'media-views', 'media-models', 'shortcode' ), | ||
filemtime( gutenberg_dir_path() . 'blocks/build/index.js' ) | ||
GUTENBERG_WEBPACK_HMR ? false : filemtime( gutenberg_dir_path() . 'blocks/build/index.js' ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mixed whitespace, this should be tabbed, not spaced.
@@ -146,10 +157,11 @@ function gutenberg_register_scripts_and_styles() { | |||
); | |||
wp_register_script( | |||
'wp-blocks', | |||
gutenberg_url( 'blocks/build/index.js' ), | |||
gutenberg_url( 'blocks/build/index.js', GUTENBERG_WEBPACK_HMR ), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a bit odd to me that we pass the GUTENBERG_WEBPACK_HMR
constant value in as an argument, as though we'd want to treat the function as generic and unaware of the constants, but then proceed to use GUTENBERG_WEBPACK_DEV_SERVER
within the function implementation. I'd suggest going consistent one way or the other (either passing both as arguments, or referencing both within the function).
const entryPointName = entryPointNames[ i ]; | ||
config.entry[ entryPointName ] = [ ...hrEntries, config.entry[ entryPointName ] ]; | ||
} | ||
config.entry.hooks = [ config.entry.hooks ]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain what this line is doing? Nevermind, I understand it now to be exempting hooks. Can you then explain why we need to exempt hooks?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
package-lock.json
needs to be updated. Are you running a version of npm lower than 5 ? (npm --version
)
This is a lot of work and hard to make sure it keeps working as new things are added. We've decided to not pursue this any further. For context see this chat: https://wordpress.slack.com/archives/C02QB2JS7/p1515003858000212. If anyone else wants to take a stab at it, this code is all yours. |
Description
This PR implements webpack hot module reloading (HMR) for the editor.
Currently, the hot reloading works only for the actual editor itself and not other parts that are exposed through global variables such as blocks. I will be looking into how to do that at a later stage.
How Has This Been Tested?
I've tested this mainly by editing react components that are being used by the actual editor in
/editor/index.js
.Screenshots (jpeg or gifs if applicable):
Types of changes
New development feature.
Checklist: