Vite JS / Vue 3 / SSR:ReferenceError window 未定义
Vite JS / Vue 3 / SSR: ReferenceError window is not defined
我将 Vite JS 与 Vue 3 一起用于具有服务器端渲染的单页应用程序。
我知道只能在客户端执行的JS必须在水合上完成,但是可以用包来完成吗?
我的情况是我希望能够使用 Headless UI(对于 Tailwind UI)并且只要该应用程序作为单页应用程序启动它就可以正常工作。用SSR启动时出现这个错误:
[Vue warn]: Unhandled error during execution of setup function
at <Dialog as="div" static="" class="fixed z-10 inset-0 overflow-y-auto" ... >
ReferenceError: window is not defined
at useWindowEvent (C:\test\node_modules\.pnpm\@headlessui+vue@1.2.0_vue@3.0.11\node_modules\@headlessui\vue\dist\headlessui.cjs.development.js:408:3)
at useFocusTrap (C:\test\node_modules\.pnpm\@headlessui+vue@1.2.0_vue@3.0.11\node_modules\@headlessui\vue\dist\headlessui.cjs.development.js:486:3)
at setup (C:\test\node_modules\.pnpm\@headlessui+vue@1.2.0_vue@3.0.11\node_modules\@headlessui\vue\dist\headlessui.cjs.development.js:1052:5)
at callWithErrorHandling (C:\test\node_modules\.pnpm\@vue+runtime-core@3.0.11\node_modules\@vue\runtime-core\dist\runtime-core.cjs.js:156:22)
at setupStatefulComponent (C:\test\node_modules\.pnpm\@vue+runtime-core@3.0.11\node_modules\@vue\runtime-core\dist\runtime-core.cjs.js:6488:29)
at setupComponent (C:\test\node_modules\.pnpm\@vue+runtime-core@3.0.11\node_modules\@vue\runtime-core\dist\runtime-core.cjs.js:6449:11)
at renderComponentVNode (C:\test\node_modules\.pnpm\@vue+server-renderer@3.0.11_vue@3.0.11\node_modules\@vue\server-renderer\dist\server-renderer.cjs.js:160:17)
at renderVNode (C:\test\node_modules\.pnpm\@vue+server-renderer@3.0.11_vue@3.0.11\node_modules\@vue\server-renderer\dist\server-renderer.cjs.js:263:22)
at renderComponentSubTree (C:\test\node_modules\.pnpm\@vue+server-renderer@3.0.11_vue@3.0.11\node_modules\@vue\server-renderer\dist\server-renderer.cjs.js:228:13)
at renderComponentVNode (C:\test\node_modules\.pnpm\@vue+server-renderer@3.0.11_vue@3.0.11\node_modules\@vue\server-renderer\dist\server-renderer.cjs.js:173:16)
我知道这个错误是因为 window 属性 无法在服务器端访问,但这是由包本身设置的。
有没有告诉 Vite JS SSR 不要在那个包上执行 JS,除非它在客户端?
这是导致错误的vue组件的内容(仅在SSR执行时,Dialog来自Headless UI):
<template>
<TransitionRoot as="template" :show="open">
<Dialog as="div" static class="fixed z-10 inset-0 overflow-y-auto" @close="open = false" :open="open">
<div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
TEST
</div>
</Dialog>
</TransitionRoot>
</template>
<script>
import { ref } from 'vue'
import { Dialog, TransitionRoot } from '@headlessui/vue'
export default {
components: {
Dialog,
TransitionRoot
},
setup() {
const open = ref(true)
return {
open,
}
},
}
</script>
PS:如果您需要参考配置,我使用了这个样板项目:https://github.com/frandiox/vitesse-ssr-template
您应该导入并使用该包仅在客户端。
对于仅在客户端导入,您可以使用 require 而不是像这样导入:
let headlessui
if (process.browser) headlessui= require('@headlessui/vue')
然后在您的模板中,您可以将所有客户端组件放入 <client-only></client-only>
标记中:
<client-only>
<TransitionRoot as="template" :show="open">
<Dialog as="div" static class="fixed z-10 inset-0 overflow-y-auto" @close="open = false" :open="open">
<div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text- center sm:block sm:p-0">
TEST
</div>
</Dialog>
</TransitionRoot>
<client-only>
我在 Vue2 中遇到了类似的问题
我实际上是在尝试使用 apexchart,在构建之后,我得到 Reference error window is not defined
我所做的是安装 vue-client-only
然后在我的条目文件中添加了
if (typeof window !== 'undefined') {
const VueApexCharts = require('vue-apexcharts')
Vue.component('ApexChart', VueApexCharts)
}
我用组件包装了它
<template>
<client-only>
<div id="chart">
<apex-chart type="radar" height="350" :options="chartOptions" :series="series"></apex-chart>
</div>
</client-only>
</template>
<script>
import ClientOnly from 'vue-apexcharts'
export default {
components: {
ClientOnly
}}
</script>
我将 Vite JS 与 Vue 3 一起用于具有服务器端渲染的单页应用程序。
我知道只能在客户端执行的JS必须在水合上完成,但是可以用包来完成吗?
我的情况是我希望能够使用 Headless UI(对于 Tailwind UI)并且只要该应用程序作为单页应用程序启动它就可以正常工作。用SSR启动时出现这个错误:
[Vue warn]: Unhandled error during execution of setup function
at <Dialog as="div" static="" class="fixed z-10 inset-0 overflow-y-auto" ... >
ReferenceError: window is not defined
at useWindowEvent (C:\test\node_modules\.pnpm\@headlessui+vue@1.2.0_vue@3.0.11\node_modules\@headlessui\vue\dist\headlessui.cjs.development.js:408:3)
at useFocusTrap (C:\test\node_modules\.pnpm\@headlessui+vue@1.2.0_vue@3.0.11\node_modules\@headlessui\vue\dist\headlessui.cjs.development.js:486:3)
at setup (C:\test\node_modules\.pnpm\@headlessui+vue@1.2.0_vue@3.0.11\node_modules\@headlessui\vue\dist\headlessui.cjs.development.js:1052:5)
at callWithErrorHandling (C:\test\node_modules\.pnpm\@vue+runtime-core@3.0.11\node_modules\@vue\runtime-core\dist\runtime-core.cjs.js:156:22)
at setupStatefulComponent (C:\test\node_modules\.pnpm\@vue+runtime-core@3.0.11\node_modules\@vue\runtime-core\dist\runtime-core.cjs.js:6488:29)
at setupComponent (C:\test\node_modules\.pnpm\@vue+runtime-core@3.0.11\node_modules\@vue\runtime-core\dist\runtime-core.cjs.js:6449:11)
at renderComponentVNode (C:\test\node_modules\.pnpm\@vue+server-renderer@3.0.11_vue@3.0.11\node_modules\@vue\server-renderer\dist\server-renderer.cjs.js:160:17)
at renderVNode (C:\test\node_modules\.pnpm\@vue+server-renderer@3.0.11_vue@3.0.11\node_modules\@vue\server-renderer\dist\server-renderer.cjs.js:263:22)
at renderComponentSubTree (C:\test\node_modules\.pnpm\@vue+server-renderer@3.0.11_vue@3.0.11\node_modules\@vue\server-renderer\dist\server-renderer.cjs.js:228:13)
at renderComponentVNode (C:\test\node_modules\.pnpm\@vue+server-renderer@3.0.11_vue@3.0.11\node_modules\@vue\server-renderer\dist\server-renderer.cjs.js:173:16)
我知道这个错误是因为 window 属性 无法在服务器端访问,但这是由包本身设置的。
有没有告诉 Vite JS SSR 不要在那个包上执行 JS,除非它在客户端?
这是导致错误的vue组件的内容(仅在SSR执行时,Dialog来自Headless UI):
<template>
<TransitionRoot as="template" :show="open">
<Dialog as="div" static class="fixed z-10 inset-0 overflow-y-auto" @close="open = false" :open="open">
<div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
TEST
</div>
</Dialog>
</TransitionRoot>
</template>
<script>
import { ref } from 'vue'
import { Dialog, TransitionRoot } from '@headlessui/vue'
export default {
components: {
Dialog,
TransitionRoot
},
setup() {
const open = ref(true)
return {
open,
}
},
}
</script>
PS:如果您需要参考配置,我使用了这个样板项目:https://github.com/frandiox/vitesse-ssr-template
您应该导入并使用该包仅在客户端。
对于仅在客户端导入,您可以使用 require 而不是像这样导入:
let headlessui
if (process.browser) headlessui= require('@headlessui/vue')
然后在您的模板中,您可以将所有客户端组件放入 <client-only></client-only>
标记中:
<client-only>
<TransitionRoot as="template" :show="open">
<Dialog as="div" static class="fixed z-10 inset-0 overflow-y-auto" @close="open = false" :open="open">
<div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text- center sm:block sm:p-0">
TEST
</div>
</Dialog>
</TransitionRoot>
<client-only>
我在 Vue2 中遇到了类似的问题
我实际上是在尝试使用 apexchart,在构建之后,我得到 Reference error window is not defined
我所做的是安装 vue-client-only
然后在我的条目文件中添加了
if (typeof window !== 'undefined') {
const VueApexCharts = require('vue-apexcharts')
Vue.component('ApexChart', VueApexCharts)
}
我用组件包装了它
<template>
<client-only>
<div id="chart">
<apex-chart type="radar" height="350" :options="chartOptions" :series="series"></apex-chart>
</div>
</client-only>
</template>
<script>
import ClientOnly from 'vue-apexcharts'
export default {
components: {
ClientOnly
}}
</script>