meteorlxy / vssue

:mailbox: A Vue-powered Issue-based Comment Plugin
https://vssue.js.org
MIT License
770 stars 106 forks source link

[Bug Report] Vuepress中使用控制台报错DOMException: Failed to execute 'appendChild' on 'Node': This node type does not support this method. #47

Closed zhhlwd closed 5 years ago

zhhlwd commented 5 years ago

在Vssue0.7.1之后,在我的vuepress主题使用,在文章页刷新或者第一次就访问的是文章页,控制台会报错,从而导致页面功能完全错乱。 DOMException: Failed to execute 'appendChild' on 'Node': This node type does not support this method. 这似乎是一个ssr常见的错误,我在开发vuepress主题时经常遇到,我的经验是让报错的地方尽可能被预渲染到html中,在nuxt.js中也常有出现 issue,我测试到在0.7.1的版本不报错,之后的版本会出现这个问题。

这里有一个例子,部署在github page的是0.7.1版本,部署在gitee page下的是0.9.1版本,直接点击链接,或者点击进去后刷新一下,gitee的会在控制台报错,页面功能也会出现各种错乱,而github的则不会。

我的主题Vssue配置,正常使用的版本号 "@vssue/api-github-v3": "0.7.3", "vssue": "0.7.1"

meteorlxy commented 5 years ago

有没有使用我们提供的vuepress-plugin-vssue

zhhlwd commented 5 years ago

没有

meteorlxy commented 5 years ago

用一下呀老铁,文档里写了,用插件可以避免很多vuepress的问题

meteorlxy commented 5 years ago

可以参考相关内容:https://vssue.js.org/zh/guide/vuepress.html

meteorlxy commented 5 years ago

如果你改了自己的样式文件的话,干脆放到ClientOnly里面比较省事

zhhlwd commented 5 years ago

没有使用插件,因为要改动太多,我用了<ClientOnly>,在最新版本不会报错了

zhhlwd commented 5 years ago

那您有打算找找出错的原因吗?没有我就把issue关了,有我就让您自己关。

meteorlxy commented 5 years ago

已经把 Vssue 的初始化过程扔在 mounted 里面了,但是还是会出这种问题,有点奇怪。有可能在预渲染 loading 状态的时候出现了 SSR mismatch 类似的问题。

之前我简单看过但是没有定位到具体问题,这两天我抽时间再试试看,老铁要是有兴趣的话也可以帮忙找找问题 😉

meteorlxy commented 5 years ago

Related Issue https://github.com/nuxt/nuxt.js/issues/1552

meteorlxy commented 5 years ago

This v-if could be the reason of this problem:

https://github.com/meteorlxy/vssue/blob/ec1e6995b1eb72d9263932c9873c644bc12e0f27/packages/vssue/src/components/VssueHeader.vue#L20

zhhlwd commented 5 years ago

This beforeMount () could be the reason of this problem

meteorlxy commented 5 years ago

beforeMount / mounted will be triggered only in the client. (the mounted in my previous comment was a typo 😅 )

I have confirmed that the v-if cause this error. A possible solution is to add an empty <span v-else /> after that.

zhhlwd commented 5 years ago

在0.7.2之前,我观察到主题编译预渲染的HTML中已经被渲染到了‘Powered by GitHub & Vssue’这句,说明v-if中的内容已经被预渲染到了,就是因为beforeMount / mounted不会在服务端触发,所以没有init预渲染到,在客户端就可能报错Failed to execute 'appendChild' on 'Node'.

我在开发主题时经常遇到,例如刚开始标签页的标签数据是在客户端jsonp请求得到后渲染的,但是在客户端刷新就会报错Failed to execute 'appendChild' on 'Node',我试过v-if一个空白的,也依然报错,后来直接import数据,让vuepress预渲染到所有标签,就不会报错了,这种错误在首页,归档页,自我介绍页,文章页都出现过,直到我把数据全部本地import进来,并且让所有页面都尽可能的被预渲染到,这种错误就没有发生了,所以开头我说的对于这种错误我的经验是让报错的地方尽可能被预渲染到html中。

meteorlxy commented 5 years ago

这个东西应该是因为 v-if="false" 导致预渲染出来一个空白的注释 <!----> 导致的。

我刚才做了一个最小复现仓库:https://github.com/meteorlxy/vuepress-appendchild-error

meteorlxy commented 5 years ago

在0.7.2之前,我观察到主题编译预渲染的HTML中已经被渲染到了‘Powered by GitHub & Vssue’这句,说明v-if中的内容已经被预渲染到了,就是因为beforeMount / mounted不会在服务端触发,所以没有init预渲染到,在客户端就可能报错Failed to execute 'appendChild' on 'Node'.

我在开发主题时经常遇到,例如刚开始标签页的标签数据是在客户端jsonp请求得到后渲染的,但是在客户端刷新就会报错Failed to execute 'appendChild' on 'Node',我试过v-if一个空白的,也依然报错,后来直接import数据,让vuepress预渲染到所有标签,就不会报错了,这种错误在首页,归档页,自我介绍页,文章页都出现过,直到我把数据全部本地import进来,并且让所有页面都尽可能的被预渲染到,这种错误就没有发生了,所以开头我说的对于这种错误我的经验是让报错的地方尽可能被预渲染到html中。

嗯对,差不多就是这个原因,v-if 预渲染出了 <!----> 这个东西,在客户端不能直接用。所以如果预渲染的时候避免掉空的 v-if 也就不会这样了

meteorlxy commented 5 years ago

我感觉是客户端的 Vue 接管预渲染的 HTML 的时候,对 <!----> 这个东西的处理和 VNode Tree 之间出现了冲突导致的。

zhhlwd commented 5 years ago

这是两个相同文章在没有用<ClientOnly>的情况下vuepress预渲染结果对比,vssue0.7.1版本vssue0.7.2版本

它们大致一样,但在这里0.7.10.7.2不太一样(0.7.1刷新不报错,0.7.2会报错)。

meteorlxy commented 5 years ago

@zhhlwd 1.0.1 修复了,有时间的话可以帮忙确认一下 😉

不过我还是觉得直接用 ClientOnly 比较好,因为目前版本 Vssue 的图标是放在一个 Vue 组件里的,预渲染会把图标 svg 也渲染出来,有点占地方。

zhhlwd commented 5 years ago

测试中没有报错了