VuePress2.0 build时遇到 xxx is not defined

419 阅读2分钟

排除问题

首先VuePress默认生成的项目build时就不会有这个问题,VuePress是可以直接在md文件中编写vue代码的,所以我们检查下项目是否安装并引用了其他的三方插件, 因为VuePress打包的时候所有的页面在生成静态 HTML 时都需要通过 Node.js 服务端渲染, Node.js 环境中自然没有 Web浏览器中某些APi,例如documentselfwindow等等 对象,这时候访问浏览器/DOM 中的 API 自然会报错。

来看这个例子,项目安装了 web-loading ,并且直接引入使用,web-loading的绘制方式中使用了window对象。

<div  ref="occRef"></div>
<script setup>
    import { initLoading } from 'web-loading'
    import { ref, onMounted} from 'vue'
    let occRef = ref(null)
    onMounted(()=>{
        let webLoading =  initLoading()
        webLoading.loading(occRef.value)
    })
</script>

我们在dev开发环境下,界面能正常运行,但在打包时会出现"window is not defined"错误。经过这一些排除步骤,我们找到了问题所在。

解决方案

动态组件

<div  ref="occRef"></div>
<script setup>
    import { ref, onMounted} from 'vue'
    let occRef = ref(null)
    onMounted(()=>{
        import('web-loading').then((params) => {
            let  webLoading =  params.initLoading({})
            webLoading.loading(occRef.value)
        })
    })
</script>

在组件挂载后动态加载web-loading模块,并通过occRef引用获取到的DOM元素作为加载的目标元素进行初始化操作。请注意,这里的web-loading同时也是异步加载,所以Node.js 服务端渲染也是以异步代码方式处理。

client 全局注入

该项目使用的是VuePress2.0,之前client.js是叫enhanceApp.js,优化后改名为client.js,该文件会在VuePress构建过程中的最后阶段被调用。

import { defineClientConfig } from '@vuepress/client'
import { provide } from 'vue'
​
export default defineClientConfig({
    enhance({ app, router, siteData }) {},
    setup() {
        import('web-loading').then((res) => {
            // 也可以使用其他方式全局抛出
            provide('count', fullLoading)
        })
    },
    layouts: {},
    rootComponents: []
})

该方法在编译的时候依然会抛出错误 window is not defined,但在VuePress1.0的时我看到有些博主是这样解决的,不知道是不是我操作的问题还是2.0后优化处理了,如果大佬知道可以指点指点,个人还是建议使用动态组件,方便维护。