I'm using react-hot-loader and I'm very confused about its example code:
import React from 'react' import ReactDOM from 'react-dom' import { AppContainer } from 'react-hot-loader' import App from './containers/App' ReactDOM.render( <AppContainer> <App/> </AppContainer>, document.getElementById('root') ); // Hot Module Replacement API if (module.hot) { module.hot.accept('./containers/App', () => { const NextApp = require('./containers/App').default; ReactDOM.render( <AppContainer> <NextApp/> </AppContainer>, document.getElementById('root') ); }); }
What I don't undestand is:
a) Why do I need to use App and NextApp ? Isn't App
the same as NextApp
, as they are imported from the same file ?
b) I thought best practices would be to keep requires
at the beginning of the code. But there I have already import App from '../containers/App
'. So:
import App from './containers/App' const NextApp = require('./containers/App').default;
Shouldn't App
and NextApp
be the same ?
c) To finish, is the following code lines equivalent ? What's the difference using a pure require
and a require .default
?
const NextApp = require('./containers/App'); const NextApp = require('./containers/App').default;
Sorry if those are very basic questions, but I need a hint on where to go to better understand this code.
1) require() In NodeJS, require() is a built-in function to include external modules that exist in separate files. require() statement basically reads a JavaScript file, executes it, and then proceeds to return the export object.
Use Import Instead of Require in Node App.
“Require” is built-in with NodeJSWith require , you can include them in your JavaScript files and use their functions and variables. However, if you are using require to get local modules, first you need to export them using module. exports .
Require is Non-lexical, it stays where they have put the file. Import is lexical, it gets sorted to the top of the file. It can be called at any time and place in the program. It can't be called conditionally, it always run in the beginning of the file.
To understand this better, you need to look at how webpack offers hot module loading for other non-react cases.
The idea is quite simple actually... Webpack detects changes happening to your code and recompiles the corresponding modules. However, it cannot safely replace the module references on the fly itself. This is why you need to implement the HMR interface yourself, hence the module.hot
call in your example code.
When a newer version of a module is available, Webpack goes up the modules chain (i.e., if X imported Y and Y has changed, webpack starts going from X > W > V...) till it finds a module which implemented HMR for Y or X or W or V etc. Then it reloads the entire chain from there.
If it reaches the root without any HMR accepting the change, it refreshes the entire page :).
Now The matter of App and NextApp... App is the statically imported version of you module. As modules are parsed and loaded only once by default, App points to a constant reference which never changes. This is why another variable NextApp is used in the example which receives the changed module within the HMR code.
Finally, the require and require.default... when dealing with ES6 imports (export default MyComponent), the exported module is of the format {"default" : MyComponent}. The import
statement correctly handles this assignment for you, however, you have to do the require("./mycomponent").default
conversion yourself. The HMR interface code cannot use import
as it doesn't work inline. If you want to avoid that, use module.exports
instead of export default
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With