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

Investigate hot module replacement and live reloading for fast iteration #845

Closed
samreid opened this issue Jan 30, 2020 · 12 comments
Closed

Comments

@samreid
Copy link
Member

samreid commented Jan 30, 2020

From #820, using ES6 modules we can use the following iteration features:

  • Live Reloading, which automatically refreshes the browser on code changes
  • Hot Module Replacement, which maintains state in the simulation and allows you to change code as you develop

For this investigation, we should look into webpack-dev-server and parcel for both live reload and hot module replacement.

The goal is to optimize our iteration time while minimizing overhead.

My initial investigation into hot module replacement in webpack works like so:

  • migrate and modulify the simulations
  • change the code of ExampleScreenView to:
// Copyright 2013-2019, University of Colorado Boulder

/**
 * View for the 'Example' screen.
 *
 * @author Chris Malley (PixelZoom, Inc.)
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Steele Dalton (PhET Interactive Simulations)
 */


// modules
import BarMagnetNode from '../../../../example-sim/js/example/view/BarMagnetNode.js';
import Bounds2 from '../../../../dot/js/Bounds2.js';
import ControlPanel from '../../../../example-sim/js/example/view/ControlPanel.js';
import exampleSim from '../../../../example-sim/js/exampleSim.js';
import inherit from '../../../../phet-core/js/inherit.js';
import ModelViewTransform2 from '../../../../phetcommon/js/view/ModelViewTransform2.js';
import ScreenView from '../../../../joist/js/ScreenView.js';
import Vector2 from '../../../../dot/js/Vector2.js';

/**
 * Constructor for the ExampleScreenView, it creates the bar magnet node and control panel node.
 *
 * @param {ExampleModel} model - the model for the entire screen
 * @constructor
 */
function ExampleScreenView( model ) {

  ScreenView.call( this, {
    layoutBounds: new Bounds2( 0, 0, 768, 504 )
  } );

  // model-view transform
  const center = new Vector2( this.layoutBounds.width / 2, this.layoutBounds.height / 2 );
  const modelViewTransform = ModelViewTransform2.createOffsetScaleMapping( center, 1 );

  let barMagnetNode = new BarMagnetNode( model.barMagnet, modelViewTransform );
  this.addChild( barMagnetNode );
  this.addChild( new ControlPanel( model, {
    x: 50,
    y: 50
  } ) );

  if ( module.hot ) {
    module.hot.accept( './BarMagnetNode.js', () => {
      this.removeChild( barMagnetNode );
      barMagnetNode = new BarMagnetNode( model.barMagnet, modelViewTransform );
      this.addChild( barMagnetNode );
    } );
  }
}

exampleSim.register( 'ExampleScreenView', ExampleScreenView );

export default inherit( ScreenView, ExampleScreenView );
import Text from '../../../../scenery/js/nodes/Text.js';
// ....
this.addChild(new Text('Testing Hot Module Replacement',{fontSize:20,center:this.center,maxWidth:140}));
  • Watch as the browser immediately updates without having to refresh, reload or show splash screen.
@chrisklus
Copy link
Contributor

A duplicate issue, #864, was closed. Content from that issue:

@jonathanolson said:

For es6 modules, it would be good to see if webpack-dev-server can create faster iteration times.

(SR, JO, ??, low overhead during sim dev, 2 hours?) [Sprintable, post-publication. But good to do early on while concrete is wet.] Experiment with live reloading and hot module replacement. To optimize iteration time. See #845
JO: Unclear whether single entry point vs multiple vs all (sims) would be best

@chrisklus said:

start off by looking at webpack.config.js, deleted in 1d3ab17.

@jonathanolson jonathanolson self-assigned this Feb 26, 2020
@jonathanolson
Copy link
Contributor

I'm going to probably restore that file in my investigation (one of the things I plan to look into today)

@zepumph
Copy link
Member

zepumph commented Feb 28, 2020

@samreid and I found that the webpack-dev-server wasn't allowing other devices to access the server (like for ipad testing etc).

After some research, we found that we could allow this by having the ip address be 0.0.0.0 allows responses to other network traffic besides this computer.

Further reading:
https://stackoverflow.com/questions/35412137/how-to-get-access-to-webpack-dev-server-from-devices-in-local-network

webpack/webpack-dev-server#147

Can we commit something like:

Index: js/grunt/webpackDevServer.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- js/grunt/webpackDevServer.js	(revision 328924a37ab3d5450f3e3ee4db047b27fe7d61e0)
+++ js/grunt/webpackDevServer.js	(date 1582921761755)
@@ -109,7 +109,8 @@
     hot: true
   } );
 
-  server.listen( port, '127.0.0.1', () => {
+  // '0.0.0.0' allows other network traffic to access this server
+  server.listen( port, '0.0.0.0', () => {
     repos.forEach( repo => console.log( `http://localhost:${port}/dist/${repo}_phet.html?brand=phet&ea` ) );
-  });
+  } );
 };

If there are worries, perhaps we can make it an option?

@jonathanolson
Copy link
Contributor

Sounds good to me, committed above.

samreid added a commit that referenced this issue Mar 3, 2020
@samreid
Copy link
Member Author

samreid commented Mar 3, 2020

In the commit, I added a command line option for devtool. I'm currently using

grunt webpack-dev-server --devtool=none

for faster iteration times. @jonathanolson can you please review?

samreid added a commit that referenced this issue Mar 4, 2020
samreid added a commit to phetsims/phet-core that referenced this issue Mar 4, 2020
samreid added a commit to phetsims/greenhouse-effect that referenced this issue Mar 4, 2020
samreid added a commit to phetsims/phet-core that referenced this issue Mar 4, 2020
@jonathanolson
Copy link
Contributor

Reviewed the first commit, looks good. How is the hot module replacement going? I had to comment it out yesterday because I kept getting errors on launch.

@samreid
Copy link
Member Author

samreid commented Mar 5, 2020

The latter 2 commits should help with that. The problem was that

unbuilt:
window.module undefined
module undefined

webpack-dev-server
window.module undefined
module defined
module.hot defined

I added isHMR to help with that. I used HMR to work on Greenhouse Effect views and Wave Interference sonification and it worked really well. It was nice to be able to hear the audio change as I saved from the IDE, without having to reload or reconfigure the sim.

@jonathanolson
Copy link
Contributor

I realized I accidentally just committed hot:false, and reverted it. I'll test it out, that sounds really nice!

Do you have an example of adding it into code? Would like to try it for density/buoyancy.

@samreid
Copy link
Member Author

samreid commented Mar 5, 2020

@samreid
Copy link
Member Author

samreid commented Mar 6, 2020

I also committed a usage in Wave Interference

@jbphet
Copy link
Contributor

jbphet commented Jun 4, 2020

Discussed in the 6/4/2020 dev meeting, and @samreid will make some updates on this and close it.

samreid added a commit to phetsims/phet-core that referenced this issue Jun 9, 2020
@samreid
Copy link
Member Author

samreid commented Jun 9, 2020

Documented, closing.

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

No branches or pull requests

5 participants