Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]结合 styled components 使用时 dynamicHeadAppend 存在缺陷 #617

Closed
xxn520 opened this issue May 29, 2020 · 14 comments
Closed

[Bug]结合 styled components 使用时 dynamicHeadAppend 存在缺陷 #617

xxn520 opened this issue May 29, 2020 · 14 comments

Comments

@xxn520
Copy link

xxn520 commented May 29, 2020

What happens?

qiankun 和 styled components 一起使用时,当 styled components 插入动态样式时,样式量多时会为一个应用插入多个 style 节点,第一个 style 节点以后的 style 节点不是往 head 中插入的,因此 qiankun 的 dynamicHeadAppend 拦截不到。这导致在应用切换的时候,未拦截到的动态的 style 节点将会丢失,导致 styled components 报错。

相关环境信息

  • qiankun 版本:2.0.12-0
    -styled components:4.4.0
  • 浏览器版本:Chrome 81.0.4044.138
  • 操作系统:MacOS Mojave 10.14.4
@kuitos
Copy link
Member

kuitos commented May 29, 2020

styled components:0.4.4 ?
这个版本是不是太老了?

提供一个可复现仓库吧

@xxn520
Copy link
Author

xxn520 commented May 29, 2020

4.4.0,5 以上也能复现。

@xxn520
Copy link
Author

xxn520 commented May 29, 2020

仓库弄一个比较麻烦,晚点提供

@xxn520
Copy link
Author

xxn520 commented May 29, 2020

其实就是目前 qiankun 拦截了动态往 head 里插的 style 节点,但是 styled components 第一个以后的动态 style 节点不是往 head 里插的,是往前面插入的最后一个 style 节点后面插的,因此拦截不到。

@xxn520 xxn520 closed this as completed Jun 2, 2020
@chenqiangmingyu
Copy link

其实就是目前 qiankun 拦截了动态往 head 里插的 style 节点,但是 styled components 第一个以后的动态 style 节点不是往 head 里插的,是往前面插入的最后一个 style 节点后面插的,因此拦截不到。

@xxn520 问题解决了吗,能请教下解决方案么?也遇到相同问题,styled-components再rebuild的时候某些样式丢失了。

@xxn520
Copy link
Author

xxn520 commented Jun 5, 2020

@chenqiangmingyu 升 5 目前能解决多个 style 节点带来的问题,但是升 5 后,在应用切换的时候,StyleSheet 里面的 Tag 里面的 sheet 对象持有的还是老的引用,会导致新的样式插不进去(这应该也就是你提到的某些样式丢失的原因),目前的解法是在应用卸载的时候调用一下 StyleSheet.clearTag 方法清空 Tag,那么在应用切回来的时候 Tag 会重新创建,sheet 对象也会更新。但是进一步会有新的问题,我们无法比较好的控制 clearTag 的时机,如果用了 styled components 的 global styles,这个东西卸载的时机如果在 clearTag 之后又会报新的错。总得来说这两个东西有点水土不服,可能会 fork 其中一个来改了。

@kuitos
Copy link
Member

kuitos commented Jun 5, 2020

能提供一个可复现的仓库吗 @chenqiangmingyu @xxn520

@xxn520
Copy link
Author

xxn520 commented Jun 5, 2020

@kuitos https://github.com/xxn520/qiankun/tree/master/examples 实际情况比这个复杂,但 dynamicHeadAppend 的问题这个例子也能够复现

@chenqiangmingyu
Copy link

chenqiangmingyu commented Jun 5, 2020

能提供一个可复现的仓库吗 @chenqiangmingyu @xxn520

@kuitos @xxn520 我这边问题点已经fixed了,主要是子应用的容器是父应用动态生成的,父应用技术栈是React,因为父应用渲染由自身router控制,不受qiankun生命周期约束,导致location切换时把子应用的宿主容器给直接销毁,子应用unmount钩子执行与DOM容器清理并没有按照预期的顺序执行。容器清理后,待缓存的style节点也一并被粗暴的从DOM清理了,此后unmount读到的style可能由于gc之类机制出现了残缺(style.sheet === null),重建的样式也就异常了。

解决方案:这边把子应用容器作为一个常驻容器扔到父应用组件,不再销毁。
重建时产生另外一个问题就是cssRules和bootstrap的顺序正好相反造成的样式异常已经另开issue.

@fantasyroot
Copy link

@kuitos https://github.com/xxn520/qiankun/tree/master/examples 实际情况比这个复杂,但 dynamicHeadAppend 的问题这个例子也能够复现

+1,楼主这个是可复现仓库,请 @kuitos 能尽快解决,感谢

@baicaisong
Copy link

@chenqiangmingyu 升 5 目前能解决多个 style 节点带来的问题,但是升 5 后,在应用切换的时候,StyleSheet 里面的 Tag 里面的 sheet 对象持有的还是老的引用,会导致新的样式插不进去(这应该也就是你提到的某些样式丢失的原因),目前的解法是在应用卸载的时候调用一下 StyleSheet.clearTag 方法清空 Tag,那么在应用切回来的时候 Tag 会重新创建,sheet 对象也会更新。但是进一步会有新的问题,我们无法比较好的控制 clearTag 的时机,如果用了 styled components 的 global styles,这个东西卸载的时机如果在 clearTag 之后又会报新的错。总得来说这两个东西有点水土不服,可能会 fork 其中一个来改了。

@xxn520 请问StyleSheet.clearTag指的是子应用 unmount 的时候,把所有 <style> remove 吗?

https://stackoverflow.com/questions/53486470/react-styled-components-stripped-out-from-production-build

通过将 SC_DISABLE_SPEEDY=true ,可以使 <style> 里的内容在生产环境下也展示出来。可以避开 qiankun 在rebuildCSSRules 时对 styled components 的特殊处理。重新加载子应用时 styled components 也可以正确找到文件插入样式。可以解决我样式丢失的问题

@li9269391
Copy link

@chenqiangmingyu 升 5 目前能解决多个 style 节点带来的问题,但是升 5 后,在应用切换的时候,StyleSheet 里面的 Tag 里面的 sheet 对象持有的还是老的引用,会导致新的样式插不进去(这应该也就是你提到的某些样式丢失的原因),目前的解法是在应用卸载的时候调用一下 StyleSheet.clearTag 方法清空 Tag,那么在应用切回来的时候 Tag 会重新创建,sheet 对象也会更新。但是进一步会有新的问题,我们无法比较好的控制 clearTag 的时机,如果用了 styled components 的 global styles,这个东西卸载的时机如果在 clearTag 之后又会报新的错。总得来说这两个东西有点水土不服,可能会 fork 其中一个来改了。

@xxn520 请问StyleSheet.clearTag指的是子应用 unmount 的时候,把所有 <style> remove 吗?

https://stackoverflow.com/questions/53486470/react-styled-components-stripped-out-from-production-build

通过将 SC_DISABLE_SPEEDY=true ,可以使 <style> 里的内容在生产环境下也展示出来。可以避开 qiankun 在rebuildCSSRules 时对 styled components 的特殊处理。重新加载子应用时 styled components 也可以正确找到文件插入样式。可以解决我样式丢失的问题

我也遇到了同样的问题。但项目里面用的是 css module ,SC_DISABLE_SPEEDY=true 是在哪里设置呢,是放在 umi 项目的根目录 .env 文件吗?我还尝试过加 REACT_APP_SC_DISABLE_SPEEDY=true 都不生效

@jasonChen1234
Copy link

在umi-plugin-qiankun中,设置 sandbox:false 发现可以解决这个问题

@li9269391
Copy link

@chenqiangmingyu 升 5 目前能解决多个 style 节点带来的问题,但是升 5 后,在应用切换的时候,StyleSheet 里面的 Tag 里面的 sheet 对象持有的还是老的引用,会导致新的样式插不进去(这应该也就是你提到的某些样式丢失的原因),目前的解法是在应用卸载的时候调用一下 StyleSheet.clearTag 方法清空 Tag,那么在应用切回来的时候 Tag 会重新创建,sheet 对象也会更新。但是进一步会有新的问题,我们无法比较好的控制 clearTag 的时机,如果用了 styled components 的 global styles,这个东西卸载的时机如果在 clearTag 之后又会报新的错。总得来说这两个东西有点水土不服,可能会 fork 其中一个来改了。

@xxn520 请问StyleSheet.clearTag指的是子应用 unmount 的时候,把所有 <style> remove 吗?
https://stackoverflow.com/questions/53486470/react-styled-components-stripped-out-from-production-build
通过将 SC_DISABLE_SPEEDY=true ,可以使 <style> 里的内容在生产环境下也展示出来。可以避开 qiankun 在rebuildCSSRules 时对 styled components 的特殊处理。重新加载子应用时 styled components 也可以正确找到文件插入样式。可以解决我样式丢失的问题

我也遇到了同样的问题。但项目里面用的是 css module ,SC_DISABLE_SPEEDY=true 是在哪里设置呢,是放在 umi 项目的根目录 .env 文件吗?我还尝试过加 REACT_APP_SC_DISABLE_SPEEDY=true 都不生效

最后发现是 qiankun v2.7.2 更新导致,回退到v2.7.0正常

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants