Egg React SSR 服务端渲染 Webpack 构建流程

2019-11-03 admin

1. 本地Egg项目启动

  • 首先执行node index.js 或者 npm run dev 启动 Egg应用
  • 在 Egg Agent 里面启动koa服务, 同时在koa服务里面启动Webpack编译服务
  • 挂载Webpack内存文件读取方法覆盖本地文件读取的逻辑
app.react.render = (name, locals, options) => {
   const filePath = path.isAbsolute(name) ? name : path.join(app.config.view.root[0], name);
   const promise = app.webpack.fileSystem.readWebpackMemoryFile(filePath, name);
   return co(function* () {
     const code = yield promise;
     if (!code) {
       throw new Error(`read webpack memory file[${filePath}] content is empty, please check if the file exists`);
     }
     // dynamic execute javascript
     const wrapper = NativeModule.wrap(code);
     vm.runInThisContext(wrapper)(exports, require, module, __filename, __dirname);
     const reactClass = module.exports;
     if (options && options.markup) {
       return Promise.resolve(app.react.renderToStaticMarkup(reactClass, locals));
     }
     return Promise.resolve(app.react.renderToString(reactClass, locals));
   });
};
  • Worker 监听Webpack编译状态, 检测Webpack 编译是否完成, 如果未完成, 显示Webpack 编译Loading, 如果编译完成, 自动打开浏览器
  • Webpack编译完成, Agent 发送消息给Worker,  Worker检测到编译完成, 自动打开浏览器, Egg服务正式可用

2. 本地服务端渲染页面访问

  • 浏览器输入URL请求地址, 然后 Egg 接收到请求, 然后进入 Controller
  • Node层获取数据后(Node通过http/rpc方式调用Java后端API数据接口), 进入模板render流程
  • 进入render流程后, 通过worker进程通过调用 app.messenger.sendToAgent 发送文件名给Agent进程, 同时通过 app.messenger.on 启动监听监听agent发送过来的消
  • Agent进程获取到文件名后, 从Webpack编译内存里面获取文件内容, 然后Agent 通过 agent.messenger.sendToApp 把文件内容发送给Worker进程
  • Worker进程获取到内容以后, 进行React编译HTML, 编译成HTML后, 进入jss/css资源依赖流程
  • 如果启动代理模式(见easywebpack的setProxy),  HTML直接注入相对路径的JS/CSS, 如下:

页面可以直接使用 /public/client/js/vendor.js 相对路径,  /public/client/js/vendor.js 由后端框架代理转发到webpack编译服务, 然后返回内容给后端框架, 这里涉及两个应用通信. 如下:

<link rel="stylesheet" href="/public/client/css/home/android/home.css">
<script type="text/javascript" src="/public/client/js/vendor.js"></script>
<script type="text/javascript" src="/public/client/js/home.js"></script>
  • 如果非代理模式(见easywebpack的setProxy),  HTML直接注入必须是绝对路径的JS/CSS, 如下:

页面必须使用 http://127.0.0.1:9000/public/client/js/vendor.js 绝对路径

<link rel="stylesheet" href="http://127.0.0.1:9000/public/client/css/home/android/home.css">
<script type="text/javascript" src="http://127.0.0.1:9000/public/client/js/vendor.js"></script>
<script type="text/javascript" src="http://127.0.0.1:9000/public/client/js/home.js"></script>

其中 http://127.0.0.1:9000 是 Agent里面启动的Webpack编译服务地址, 与Egg应用地址是两回事

  • 最后, 模板渲染完成, 服务器输出HTML内容给浏览器.

3. 正式环境发布模式构建流程和运行模式

  • Webpack通过本地构建或者ci直接构建好服务端文件和客户端资源文件到磁盘
  • Egg render直接读取本地文件, 然后渲染成 HTML
  • 根据 manfifest.json 文件注入 jss/css资源依赖注入
  • 模板渲染完成, 服务器输出HTML内容给浏览器.

4. 关于 Egg 框架中的 Agent 和 Worker

  • 我们利用本地开发修改Node层代码修复重启时, 只会重启Worker进程, 不会重启Agent进程, 我们可以在Agent里面启动Webpack编译服务解决Webpack compiler实例问题.
  • 因为Egg App进程 和 Agent进程是两个进程, 当url访问时, 我们通过worker发送消息给agent进程, 获取服务端渲染的文件内容, 然后Agent再发送消息给Worker解决文件读取问题.
  • 本地开发webpack热更新内存存储读取和线上应用本机文件读取逻辑分离功能, 我们通过本地开发模式时, 通过读取Webpack内存内容覆盖本地文件读取的逻辑, 这样在开发模式和发布模式可以无缝对接.
  • worker和agent通信机制: https://eggjs.org/zh-cn/core/cluster-and-ipc.html
  • 实现egg项目服务器代码修改项目自动重启的功能可以使用egg-development插件.

[转载]原文链接:https://segmentfault.com/a/1190000020890126

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-78793.html

文章标题:Egg React SSR 服务端渲染 Webpack 构建流程

相关文章
当 Egg.js 遇上 Typescript
# 前言 TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. TypeScript 的静态类型检查,智能提示,IDE 友好性等特...
2018-04-14
webpack4 css打包压缩问题
这两天一直在练习这个webpack4, 发现有好多问题和坑,做开发嘛,一定要有喜欢出问题并喜欢解决问题,坚决踩个坑填个坑的不怕死小强精神! webpack4 在配置上其实是可以是想production和development的, &#x2F...
2018-05-18
nuxt.js部署vue应用到服务端过程
由于seo的需要,最近将项目移植道nuxt.js下采用ssr渲染 移植完成后,一路顺畅,但是到了要部署到服务器端上时候,还是个头疼的问题,但最终还是顺利完成。 现在记录一下部署中的过程。 注:部署时候过程中,参考了下:https://seg...
2018-04-18
[Vue CLI 3] 配置 webpack-bundle-analyzer 插件
首先还是简单介绍一下 webpack-bundle-analyzer 是做什么的: Visualize size of webpack output files with an interactive zoomable treemap. ...
2018-09-03
#react-native# Error: Command failed: gradlew.bat installDebug
这篇文章主要解决react-native中遇到的bug。 编译并运行 React Native 应用之前我们可以使用下面的方法清理gradlew 和之前的构建文件。 Error: Command failed: gradlew.bat in...
2019-02-28
webpack 换肤功能多主题/配色样式打包解决方案
色阶 本文主要详细介绍了,如何使用 webpack,打包多套不同主题的解决方案以及实践中所遇到的问题。 &lt;a id=“more”&gt;&lt;/a&gt; 起因 首先,简单的介绍一下什么是多主题,所谓多套主题/配色,就是我们很常见...
2018-04-23
vue和vue-cli构建使用 px2rem-loader ,全局自动转换px单位,完美解决引入第三方样式变小的问题
最近公司的的项目赶,作为前端的小白懒出新的高度,使出专业的技能 --复制粘贴!!(改别人的代码也是煎熬) 我经常做一些H5页面,这样就会遇到适配这个头疼的问题,我分享下我用经常用到的适配方案: 这里就不细说了 有大神总结 ,或者自行百度。 ...
2018-04-25
配置webpack中dev.env.js、prod.env.js,解决不同命令下项目启动和打包到指定的环境
前后端分离的项目开发中,我们有开发环境、测试环境、预生产环境和生产环境。 1、开发环境下调试接口的时候,一般都会有好几个接口地址(开发服务器上的,本地的,接口开发人员的,七七八八的接口地址),要根据情况手动来切换接口地址。 2、打包时要部...
2018-09-08
使用 TypeScript 构建 Koa2 项目的最佳实践
the best practice of building Koa2 with TypeScript. 中文 usage clone repo. git clone git@github.com:DhyanaChina/koa2-type...
2018-02-27
vue下使用 pdf.js 预览 和 打印 PDF文档 兼容React
我使用前端开发框架是vue,有一个打印PDF文档的需求. 这个需求最开始是交给后台,但是明显不切实际, 因为后台服务器,根本就无法连接打印机. 所以这个预览加打印文档的需求就交到了前端, 开始我有想过直接打开pdf文件, 但事实上直接打开p...
2018-06-06
回到顶部