Open lanjingling0510 opened 8 years ago
由react客户端渲染的前端界面配合webpack-dev-server, react-hot-loader很容易实现前端开发过程中的局部刷新。然而配合node服务器的react-isomorphic实现局部刷新,同时更新client, server端的代码并非易事。 如下介绍一种可行的实施方案:
react
webpack-dev-server
react-hot-loader
react-isomorphic
client
server
适用于 koa2, react-hot-loader3, react-router可有可无。 Demo代码地址:https://github.com/lanjingling0510/blog/tree/master/react-isomorphic-hot-example
适用于 koa2, react-hot-loader3, react-router可有可无。
koa2
react-hot-loader3
react-router
Demo代码地址:https://github.com/lanjingling0510/blog/tree/master/react-isomorphic-hot-example
react静态资源的热加载配置并不复杂。webpack-dev-server负责重新编译代码,react-hot-loader负责热加载。
Note:webpack-dev-server也可以用开一个express服务器配合webpack-dev-middleware和webpack-hot-middleware中间件实现
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文件的变化,如果被修改则调用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); });
// 关闭所有连接,关闭服务器,重新编译 function compileHotServer() { compiling ++; // listenerManager实例包含当前web服务器对象和客户端连接的socket集合 if (listenerManager) { listenerManager.dispose(true).then(runCompiler); } else { runCompiler(); } } // webpack重新编译 function runCompiler() { compiler.run(() => undefined); }
// 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,但不影响刷新
[react-router] You cannot change <Router routes>; it will be ignored
通过以上配置,可以实现修改代码后,实现server和client代码的更新以及hot reload。 代码开发过程中,需要开启两个端口,分别用来提供client端静态资源的编译和后台的server。
如果在开发模式下,有更完善的react isomoriphic服务器渲染热加载的解决方案,欢迎大家积极贡献 😁
react isomoriphic
在生产环境下需要如果使用呢?
嗨 @dxcweb ,hot reload只是在开发环境下来用,方便开发而已
待解决的可以看下这个:React Hot Loader 3 beta 升级指南
前言
由
react
客户端渲染的前端界面配合webpack-dev-server
,react-hot-loader
很容易实现前端开发过程中的局部刷新。然而配合node服务器的react-isomorphic
实现局部刷新,同时更新client
,server
端的代码并非易事。 如下介绍一种可行的实施方案:hot reload分析
react静态资源热加载分析
react静态资源的热加载配置并不复杂。
webpack-dev-server
负责重新编译代码,react-hot-loader
负责热加载。webpack.client-dev.js
:babel
配置文件react服务器配置分析
开发模式下,server端的配置比较复杂,需要考虑的事情如下:
待解决
.
react-router
包含的页面组件更新后,提示[react-router] You cannot change <Router routes>; it will be ignored
,但不影响刷新总结
通过以上配置,可以实现修改代码后,实现server和client代码的更新以及hot reload。 代码开发过程中,需要开启两个端口,分别用来提供client端静态资源的编译和后台的server。
如果在开发模式下,有更完善的
react isomoriphic
服务器渲染热加载的解决方案,欢迎大家积极贡献 😁