原文连接javascript
前言前端
hot reload分析java
react静态资源热加载分析node
react服务器配置分析react
待解决webpack
总结git
由react
客户端渲染的前端界面配合webpack-dev-server
, react-hot-loader
很容易实现前端开发过程当中的局部刷新。然而配合node服务器的react-isomorphic
实现局部刷新,同时更新client
, server
端的代码并不是易事。
以下介绍一种可行的实施方案:github
适用于
koa2
,react-hot-loader3
,react-router
无关紧要。webDemo代码地址:https://github.com/lanjingling0510/blog/tree/master/react-isomorphic-hot-exampleexpress
react静态资源的热加载配置并不复杂。webpack-dev-server
负责从新编译代码,react-hot-loader
负责热加载。
Note:
webpack-dev-server
也能够用开一个express
服务器配合webpack-dev-middleware
和webpack-hot-middleware
中间件实现
配置webpack.client-dev.js
:
plugins: [ new webpack.HotModuleReplacementPlugin() ] // ... entry: [ 'react-hot-loader/patch', 'webpack-dev-server/client?http://127.0.0.1:8080', 'webpack/hot/only-dev-server', './src/client/home', // 入口路径 ]
修改babel
配置文件
"plugins": [ "react-hot-loader/babel" ]
修改入口文件
import React from 'react'; import ReactDOM from 'react-dom'; // 共享的组件页面 import Home from '../shared/page/Home'; // 热加载组件 import ReactHotLoader from '../shared/component/ReactHotLoader'; const container = document.getElementById('react-container'); function renderApp(TheApp) { ReactDOM.render( <ReactHotLoader> <TheApp /> </ReactHotLoader>, container ); } renderApp(Home); // 下面的代码用来支持咱们热加载应用 if (__DEV__ && module.hot) { // 接受这个文件的修改用来热加载 module.hot.accept('./home.js'); // 应用任何的改变将形成热加载,从新渲染。 module.hot.accept( '../shared/page/Home', () => renderApp(require('../shared/page/Home').default) ); }
开发模式下,server端的配置比较复杂,须要考虑的事情以下:
监听server代码的变更。
须要从新编译server代码
从新开启server服务器,并保证require最新的server代码
保证server端口按需开关,不冲突
监听server代码
// 监听server文件的变化,若是被修改则调用compileHotServer const watcher = chokidar.watch([ path.resolve(__dirname, '../src'), path.resolve(__dirname), ], {ignored: path.resolve(__dirname, '../src/client')}); watcher.on('ready', () => { watcher .on('add', compileHotServer) .on('addDir', compileHotServer) .on('change', compileHotServer) .on('unlink', compileHotServer) .on('unlinkDir', compileHotServer); });
关闭全部与客户端的链接,关闭server服务器,从新编译server代码
// 关闭全部链接,关闭服务器,从新编译 function compileHotServer() { compiling ++; // listenerManager实例包含当前web服务器对象和客户端链接的socket集合 if (listenerManager) { listenerManager.dispose(true).then(runCompiler); } else { runCompiler(); } } // webpack从新编译 function runCompiler() { compiler.run(() => undefined); }
从新开启server服务器
// server代码编译完成 // 开启server服务器 compiler.plugin('done', stats => { compiling --; if (compiling !== 0) return; if (stats.hasErrors()) { console.log(stats.toString()); return; } console.log('? ? Build server bundle done.'); // 确保新的server bundles 代码不在module cache当中 Object.keys(require.cache).forEach((modulePath) => { if (modulePath.indexOf(compiler.options.output.path) !== -1) { delete require.cache[modulePath]; } }); try { const listener = require(compiledOutputPath).default; listenerManager = new ListenerManager(listener, 'server'); } catch (err) { console.log(err); } });
. react-router
包含的页面组件更新后,提示[react-router] You cannot change <Router routes>; it will be ignored
,但不影响刷新
经过以上配置,能够实现修改代码后,实现server和client代码的更新以及hot reload。
代码开发过程当中,须要开启两个端口,分别用来提供client端静态资源的编译和后台的server。
若是在开发模式下,有更完善的react isomoriphic
服务器渲染热加载的解决方案,欢迎你们积极贡献 ?