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

Implement webpack hot module reloading. #4121

Closed
wants to merge 9 commits into from
Closed

Implement webpack hot module reloading. #4121

wants to merge 9 commits into from

Conversation

abotteram
Copy link
Contributor

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:

  • My code is tested.
  • My code follows the WordPress code style.
  • [] My code follows has proper inline documentation.

@andreiglingeanu
Copy link
Contributor

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.
Copy link
Member

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 the hot 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]' );
Copy link
Member

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.
Copy link
Member

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 ] );
Copy link
Member

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 ) {
Copy link
Member

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 ) => {
Copy link
Member

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 of elRender, and assume the first argument is the Editor 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' )
Copy link
Member

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 ),
Copy link
Member

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 ];
Copy link
Member

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?

Copy link
Member

@aduth aduth left a 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)

@atimmer
Copy link
Member

atimmer commented Jan 3, 2018

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants