zhangyuang / egg-react-ssr

最小而美的Egg + React + SSR 服务端渲染应用骨架,同时支持JS和TS
http://doc.ssr-fc.com/
MIT License
1.91k stars 212 forks source link

关于用loadable分割加载css的问题 #208

Closed lyxverycool closed 3 years ago

lyxverycool commented 3 years ago

如果用loadable进行路由分割会导致 模块css 加载异步,样式错乱,我看demo给的解决方法是 chunkName = url.split('/')[1] href={/static/css/${chunkName}.chunk.css} 感觉过于简单了,如果path和chunkname不一致就加载不到了,后续能不能优化一下,比如引用官方的 @loadable/server 按映射关系加载对应css.

zhangyuang commented 3 years ago

可以关注下这个https://github.com/ykfe/ssr/tree/feat/dynamic 最近在探索自动化loadable的最佳实践。 我这边先看看react-loadable和https://github.com/gregberge/loadable-components 的区别

zhangyuang commented 3 years ago

https://zhuanlan.zhihu.com/p/343743374

@lyxverycool 最佳策略已更新

lyxverycool commented 3 years ago

看了一下,这个好像是Serverless项目的方案吧,如果要搬到这个项目来修改成本有点高啊

zhangyuang commented 3 years ago

@lyxverycool 不需要搬运,原理是一模一样的。只是serverless的用了约定式路由很多东西框架可以在底层控制。这个项目只需要约定下webpackChunkName与文件夹名称或者页面名称保持一致就像。 chunkName = url.split('/')[1] href 这种做法只要保持约定一致也不会出错。

zhangyuang commented 3 years ago

其他的像isBrowser,preload这种两个项目都是一样的都使用了这些策略。

lyxverycool commented 3 years ago

好的,咨询大佬一个问题,如果是单纯的spa项目,不用node, 像这种 loader: () => import(/*webpackChunkName:"${currentWebpackChunkName}" 用变量的方式去命名chunkname是怎么做到的?我看官方的 "[request]" ,打包出来都是name-name-name这种,不支持传递变量. https://github.com/webpack/webpack/issues/4807

zhangyuang commented 3 years ago

https://webpack.js.org/api/module-methods/#magic-comments

zhangyuang commented 3 years ago

https://github.com/ykfe/ssr/blob/dev/packages/webpack/src/config/client.ts

lyxverycool commented 3 years ago

就是手动传入entry吧,感谢大佬

LYnnProspery commented 3 years ago

Css的文件哈希怎么拿到呢?

zhangyuang commented 3 years ago

@LYnnProspery 读 asset-manifest.json,或者建议直接用开箱即用版本 https://github.com/ykfe/ssr

LYnnProspery commented 3 years ago

都随着 镜像 or sfc的部署推到 云上本地环境,这个好解决。但是如果 不想推到本地而是通过 一个 nfs系统去拉html & renderjs的话,这个方案就不太适用

zhangyuang commented 3 years ago

没搞懂你想说什么。读 asset-manifest.json 是服务端通过 require 读取的。ssr不存在 html 文件

LYnnProspery commented 3 years ago

我的意思是,没有本地文件,ssr的服务只是一个 部署在 云上的 一个ssr服务,服务负责去 nfs(network-file-system)拉该次请求需要的html & 对应的renderjs,然后执行renderjs拿到 render的结果,在ssr服务进行拼装返回。

LYnnProspery commented 3 years ago

就是一个 解耦 server 和 前端资源的方案,这样前端更新不需要server重新部署,而且 文件的控制权和灰度 都能够放到其他地方

zhangyuang commented 3 years ago

你部署 ssr 服务肯定是带构建产物的啊。什么叫没有本地文件。and什么叫拉取 renderjs...

LYnnProspery commented 3 years ago

老哥 加个微信聊聊?

zhangyuang commented 3 years ago

你都没搞懂 ssr 的完整流程,除非你按照文档教你的方式来才能做到前端更新不需要server重新部署。正常情况不存在前端更新不需要server重新部署

zhangyuang commented 3 years ago

如果你不懂 ssr 流程建议你看这个项目 https://github.com/ykfe/ssr 下面有微信交流群

zhangyuang commented 3 years ago

简直无语,你先搞懂什么是构建产物行不行。建议你先自己搞懂服务端bundle和客户端bundle的区别。and别动不动扣阿里的帽子,本人早已不在阿里。

LYnnProspery commented 3 years ago

我只是觉得 不太理解场景的话,不要随便 给别人扣 ”无知“的帽子。

zhangyuang commented 3 years ago

不好意思,我很清楚明白的告诉你,你的理解就是有问题的。你能使用到的任何场景我都接触过。如果你觉得本框架不适合你欢迎出门右转。玻璃心就别提issue了 thanks

zhangyuang commented 3 years ago

and 建议你提问前仔细阅读文档 https://ykfe.surge.sh/guide/deploy.html#%E5%87%86%E5%A4%87 。虽然此文档已经过于旧了,但是完全能解答你的问题。如果你想用更先进的,请阅读 https://github.com/ykfe/ssr

LYnnProspery commented 3 years ago

心情气和的说, 你们的egg-react-ssr和 ssr的 repo 源码我都已经看过了,我自觉应该理解 你所谓的ssr过程 和 你说的一些东西。 这么说吧,如果有一个这种场景:

  1. 已经存在一套内网使用的 灰度策略,这个策略是通过请求返回对应的html文件。
  2. 这个服务存在于ssr的下游,无法知道文件是什么,所以需要从idc请求拉回来
  3. server render是一个 执行renderdomstring的过程,只要能够拿到server.bundle的内容(renderdomstring抽象到这里面),server所需要的这样就是一个 vm.run(server.bundle.js)的过程
  4. 所有的事情都解决了,现在想聚焦的,就是css的这个inject。说实话你的文章我都拜读过,所以对你的思路很认可。组件hoc这种方式实在不太好,所以看到你有一套约定式的inject。
  5. 但是这个约定式的inject,在没有文件内容的情况下,不好获取。

打字说到这,我突然有了思路,我可以把你是说的asset-manifest.json 通过某种方式,加入到nfs中拉取然后读取。感觉可以解决。

zhangyuang commented 3 years ago

你无非要做的不就是把静态资源独立 cdn 部署吗 1、纯客户端渲染应用完全没问题,发版只要更新 客户端 cdn 文件即可 2、ssr 应用不考虑 loadable 不使用asset-manifest.json,此方案也不行,客户端 bundle 更新 对应的服务端 bundle 也需要更新,否则会不匹配 3、文档给的策略是通过 所有bundle全部上 cdn,在服务端动态下载服务端 bundle

zhangyuang commented 3 years ago

构建产物指的是 1、服务端使用 ts 框架,包含 ts-> dist 的构建产物 2、前端webpack构建产物,包括服务端bundle以及客户端bundle

产物1用于部署。产物2若无单独cdn服务,可直接一并部署走静态资源和本地文件的形式分别在前端服务端访问 产物2正常情况下就算上 cdn,也不能做到 server client 独立发版互不影响。除非你按照文档所说的自己写一套服务端bundle的更新逻辑

zhangyuang commented 3 years ago

好的,为我刚才的语气说声抱歉,最近群里基础问题回答的太多了比较暴躁。如果你有进一步的疑问,可扫码加入微信群。同时建议使用新版ssr框架

LYnnProspery commented 3 years ago

感谢提供的读json文件的思路,想了一下,

产物2相关的cdn话策略已经都实现了,每一次构建都绑定一次构建的 json,管理权交给 下游服务,每次拉文件的时候能够配套拿到html, client cdn 地址 & 存放在vpc cos的 server.bundel.js内容。应该能够handle 版本问题。

我现在需要做的,就是把 client build的json映射,同时推到cos并 绑定到一起。这样能够拿到该次对应的css cdn地址,做一个路由约定 + 模糊匹配。然后注入html,唯一的可能是客户端runtime还会 加载一次css, cdn,这个小问题,学习下你们有没有解决的办法。

最后,多谢

zhangyuang commented 3 years ago

css cdn 是在服务端注入的。但是 egg-react-ssr 的注入规则是不完美的。只是根据path来判断用哪个文件。完美的做法是通过 chunk-name来判断,也就是 ssr 框架的做法。 如果你能拿到 asset-manifest.json 那我建议你把webpack构建的产物一并都拿到了。 如果你要做独立部署,你应该先想清楚我说的服务端bundle下载逻辑怎么做

LYnnProspery commented 3 years ago

明白,这块我再思考下

zhangyuang commented 3 years ago

还是那句话,建议用新版的ssr框架做了很多优化。可扫码加群了解

LYnnProspery commented 3 years ago

有一些原因不适合用迁移框架,所以只能自己搞一下,最近很关注 ssr框架,会持续关注 文章和源码。