排除问题
首先
VuePress默认生成的项目build时就不会有这个问题,VuePress是可以直接在md文件中编写vue代码的,所以我们检查下项目是否安装并引用了其他的三方插件, 因为VuePress打包的时候所有的页面在生成静态 HTML 时都需要通过Node.js服务端渲染,Node.js环境中自然没有 Web浏览器中某些APi,例如document、self、window等等 对象,这时候访问浏览器/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后优化处理了,如果大佬知道可以指点指点,个人还是建议使用动态组件,方便维护。