[Vue警告]:客户端渲染的虚拟DOM树与服务器渲染的内容不匹配(Nuxt / Vue / lerna monorepo)

时间:2020-01-30 20:27:58

标签: vue.js webpack nuxt.js vue-cli lerna

我正在尝试运行一个基本的Nuxt应用程序,该应用程序具有使用lerna monorepo内部的vue-cli构建的外部Vue组件。

页面简要显示组件内容(服务器渲染),然后消失,并抛出以下错误。

"export 'default' (imported as 'Header') was not found in 'a2b-header'

之后

Mismatching childNodes vs. VNodes: NodeList(7) [svg, text, div#app, text, h2.subtitle, text, div.links] (7) [VNode, VNode, VNode, VNode, VNode, VNode, VNode]

最后是红色的Vue警告

[Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content. This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>, or missing <tbody>. Bailing hydration and performing full client-side render.

我用于外部组件的设置是 package.json

{
  "name": "a2b-header",
  "version": "0.1.0",
  "private": true,
  "main": "./dist/a2b-header.umd.js",
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build --target lib --name a2b-header src/main.js",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "core-js": "^3.4.3",
    "vue": "^2.6.10"
  },
  ...
}

我的 main.js 如下所示:

import Header from './Header.vue'

export default Header

和组件文件本身 Header.vue 是:

<template>
  <div id="app">
    <h1>Welcome to Your Vue.js App</h1>
  </div>
</template>

<script>
export default {
  name: 'Header'
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

所有内容都将通过简单的方式导入到Nuxt项目 index.vue 中:

import Header from 'a2b-header'

和..它不起作用。我认为SSR与客户端的不匹配是由于不正确的导出所致,可能是通过某些webpack配置可以解决的,但是在尝试了许多不同的方法之后,我在这里苦苦挣扎。

我希望它能够工作的原因是,在monorepo中,我们计划拥有各种Vue应用程序(SPA和Nuxt),并且将通用代码封装在可跨不同项目重用的组件中的能力至关重要。 >

3 个答案:

答案 0 :(得分:1)

很多次敲打后确定,解决方法如下。在nuxt.config.js中,在extend函数内部的构建块中,我们需要添加:

    extend (config, ctx) {
      config.resolve.symlinks = false
    }

此设置最终正确构建了一个符号链接到Nuxt项目node_modules中的共享软件包。导出默认错误消失了,因此所有不匹配的SSR与Vnode警告均会消失。

答案 1 :(得分:1)

<ClientOnly> <YourComponent> </ClientOnly>

包裹你的组件

转到官方 nuxt 文档了解更多信息:

https://nuxtjs.org/docs/2.x/features/nuxt-components#the-client-only-component

答案 2 :(得分:0)

您可以尝试使用来包装组件,或将所有dom操作移至已安装的生命周期挂钩。

https://github.com/nuxt/nuxt.js/issues/1700#issuecomment-331099596

answer可能会为您