VuePress在build打包時(shí)window?document?is?not?defined問題解決
前言
近期在造一個(gè) vue 的組件庫(這也有不少故事可以講...),造完輪子后需要編寫組件文檔,選了 vuepress,在文檔中需要代碼演示,自然就需要引入組件庫,引入組件庫后編寫文檔正常使用沒有問題,但是在 build 的時(shí)候就出麻煩了...
問題
問題一
ReferenceError: document is not defined
出現(xiàn)這個(gè)問題的原因是我在編寫 vue 組件的時(shí)候,在.vue文件中引入了樣式文件,就是下面這個(gè)樣子:
<style lang="less"> @import '../style/content.less'; </style>
這個(gè)大家應(yīng)該很熟悉了,正常的引入樣式,但是問題是組件庫代碼編譯過后,會(huì)用到 document.querySelectory() 來進(jìn)行樣式處理,而 vuepress 所有的頁面在生成靜態(tài) HTML 時(shí)都需要通過 Node.js 服務(wù)端渲染, Node.js 環(huán)境中自然沒有 document 對象,這時(shí)候訪問瀏覽器/DOM 中的 API 自然會(huì)報(bào)錯(cuò)。
本地開發(fā)沒有問題,但是 build 就會(huì)出錯(cuò)
問題二
window is not defined
出現(xiàn)這個(gè)問題同樣是因?yàn)樵诰帉懡M件時(shí)用到了 window 對象,而 Node.js 中沒有 window 對象。
解決
第一回合
利用 vue 的動(dòng)態(tài)組件
vuepress 官方給出解決辦法,就是利用 vue 的動(dòng)態(tài)組件,
<template> <component v-if="dynamicComponent" :is="dynamicComponent"></component> </template> <script> export default { data() { return { dynamicComponent: null } }, mounted () { import('./lib-that-access-window-on-import').then(module => { this.dynamicComponent = module.default }) } } </script>
具體查看瀏覽器的 API 訪問限制
這種方式固然能解決問題,但是很麻煩,想想我要編寫十幾個(gè)組件文檔,寫 demo 的時(shí)候每次都要這樣處理,要是遇到復(fù)雜的示例,一個(gè) demo 里面用到了好幾個(gè)組件,那豈不是麻煩得很,不夠優(yōu)雅,不夠優(yōu)雅。
而且編寫文檔的時(shí)候,組件庫完全可以在enhanceApp.js
中一次性完整引入,不需要按需引入,比如:
import Element from 'element-ui' export default ({ Vue, options, router, siteData }) => { Vue.use(Element); };
第二回合
beforeMount 或 mounted 再去訪問訪問瀏覽器 / DOM 的 AP
其實(shí)上面第一種解決辦法已經(jīng)給我們提供了思路,在 beforeMount
或 mounted
再去訪問訪問瀏覽器 / DOM 的 API。
但是按照我們的需求,這時(shí)候不能再去 demo 組件中的 mounted
單獨(dú)處理這個(gè)問題了,那我們目光又回到 enhanceApp.js
,組件庫的引入可以放到這里,在這里使用 mixin 來處理。
因?yàn)槭?Node.js 服務(wù)端渲染,第一想到了用 require:
import Element from 'element-ui' export default ({ Vue, options, router, siteData }) => { Vue.use(Element); Vue.mixin({ mounted() { var WisdomUI = require('wisdom-ui') Vue.use(WisdomUI) }, }) };
build 通過
本地運(yùn)行,組件加載失敗
頭大,應(yīng)該用 ES module:
import Element from 'element-ui' export default ({ Vue, options, router, siteData }) => { Vue.use(Element); Vue.mixin({ mounted() { import('wisdom-ui').then(function (m) { Vue.use(m.default) }) }, }) };
- 本地運(yùn)行沒有問題
- build 正常
問題解決。
以上就是VuePress在build打包時(shí)window document is not defined問題解決的詳細(xì)內(nèi)容,更多關(guān)于VuePress build打包問題解決的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue3中reactive數(shù)據(jù)被重新賦值后無法雙向綁定的解決
這篇文章主要介紹了vue3中reactive數(shù)據(jù)被重新賦值后無法雙向綁定的解決,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05vue實(shí)現(xiàn)高德地圖添加多個(gè)點(diǎn)標(biāo)記
地圖多點(diǎn)標(biāo)注其實(shí)是個(gè)非常簡單的問題,這篇文章主要給大家介紹了關(guān)于vue實(shí)現(xiàn)高德地圖添加多個(gè)點(diǎn)標(biāo)記的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06ElementUI之表格toggleRowSelection選中踩坑記錄
這篇文章主要介紹了ElementUI之表格toggleRowSelection選中踩坑記錄,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03手把手教你如何使用Vite構(gòu)建vue項(xiàng)目
這篇文章主要介紹了如何使用Vite構(gòu)建vue項(xiàng)目的相關(guān)資料,本文主要介紹了Vite構(gòu)建Vue項(xiàng)目的詳細(xì)步驟,包括檢查node.js和pnpm的安裝,構(gòu)建Vite+Vue項(xiàng)目,利用HBuilderX導(dǎo)入項(xiàng)目,需要的朋友可以參考下2024-10-10詳解基于 Nuxt 的 Vue.js 服務(wù)端渲染實(shí)踐
這篇文章主要介紹了詳解基于 Nuxt 的 Vue.js 服務(wù)端渲染實(shí)踐,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10如何在vue項(xiàng)目中嵌入jsp頁面的方法(2種)
這篇文章主要介紹了如何在vue項(xiàng)目中嵌入jsp頁面的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02Vue中v-show添加表達(dá)式的問題(判斷是否顯示)
這篇文章主要介紹了關(guān)于Vue中v-show中添加表達(dá)式用于判斷是否顯示的問題,很多朋友經(jīng)常會(huì)遇到這樣的需求,有數(shù)據(jù)來源和標(biāo)簽類型兩行選項(xiàng),需要實(shí)現(xiàn)點(diǎn)擊上面的某個(gè)數(shù)據(jù)來源時(shí),標(biāo)簽類型自動(dòng)切換功能,感興趣的朋友一起看看吧2018-03-03Vue中this.$nextTick()方法的使用及代碼示例
$nextTick()是Vue.js框架中的一個(gè)方法,它主要用于DOM操作,當(dāng)我們修改Vue組件中的數(shù)據(jù)時(shí),Vue.js會(huì)在下次事件循環(huán)前自動(dòng)更新視圖,并異步執(zhí)行$nextTick()中的回調(diào)函數(shù),本文主要介紹了Vue中this.$nextTick()方法的使用及代碼示例,需要的朋友可以參考下2023-05-05