在用nuxt開發服務端渲染項目並引入第三方庫的時候,常常會遇到window或document未定義的狀況,緣由是這個第三方庫裏面用到了window或者document,而後在服務端打包的時候,node環境並無window或者document,因此就報了window或document未定義的錯誤。css
並且,咱們在引入第三方庫的時候,並不但願把第三方庫打包進app.js,而是但願這個第三方庫只在須要的頁面才加載。html
下面以tinymce這個第三方庫爲例,記錄我在nuxt.js框架中的實現方法,供之後開發時參考,相信對其餘人也有用。vue
咱們不能把tinymce放到plugin裏面去引入,由於這樣會引入到全局js裏面去。node
nuxt官網介紹了一種方法:Window 或 Document 對象未定義?,可是寫的很簡略,我這裏詳細說明一下。webpack
首先咱們在要引入的blog.vue文件中,經過判斷是不是客戶端來選擇性的加載tinymce這個庫:web
let tinymce; if (process.client) { tinymce = require('tinymce/tinymce'); // A theme is also required require('tinymce/themes/silver/theme'); // Any plugins you want to use has to be imported require('tinymce/plugins/advlist'); require('tinymce/plugins/wordcount'); require('tinymce/plugins/autolink'); require('tinymce/plugins/autosave'); require('tinymce/plugins/charmap'); require('tinymce/plugins/codesample'); require('tinymce/plugins/contextmenu'); require('tinymce/plugins/emoticons'); require('tinymce/plugins/fullscreen'); require('tinymce/plugins/hr'); require('tinymce/plugins/imagetools'); require('tinymce/plugins/insertdatetime'); require('tinymce/plugins/link'); require('tinymce/plugins/media'); require('tinymce/plugins/noneditable'); require('tinymce/plugins/paste'); require('tinymce/plugins/print'); require('tinymce/plugins/searchreplace'); require('tinymce/plugins/tabfocus'); require('tinymce/plugins/template'); require('tinymce/plugins/textpattern'); require('tinymce/plugins/visualblocks'); require('tinymce/plugins/anchor'); require('tinymce/plugins/autoresize'); require('tinymce/plugins/bbcode'); require('tinymce/plugins/code'); require('tinymce/plugins/colorpicker'); require('tinymce/plugins/directionality'); require('tinymce/plugins/fullpage'); require('tinymce/plugins/help'); require('tinymce/plugins/image'); require('tinymce/plugins/importcss'); require('tinymce/plugins/legacyoutput'); require('tinymce/plugins/lists'); require('tinymce/plugins/nonbreaking'); require('tinymce/plugins/pagebreak'); require('tinymce/plugins/preview'); require('tinymce/plugins/save'); require('tinymce/plugins/spellchecker'); require('tinymce/plugins/table'); require('tinymce/plugins/textcolor'); require('tinymce/plugins/toc'); require('tinymce/plugins/visualchars'); require('tinymce/skins/lightgray/skin.min.css'; }
這樣,在服務端就不會引入這些庫,只會在客戶端引入。可是服務端沒有引入的話,相關js在執行的時候會報不存在的錯誤,這裏就須要再用process.client判斷一下環境再執行。示例以下:app
if (process.client) { tinymce.init({ ...options, ...this.otherOptions, language: this.language, }); )
有時候咱們但願用引入tinymce.js的方法來引入,而不用webpack打包的方式。這個時候咱們須要在blog.vue裏面加上以下代碼便可:框架
export default { name: 'Blog', layout: 'blank', head: { script: [ { src: '/tinymce.5.0.4/tinymce.min.js' }, ], }, }
其中上面src的路徑是static文件夾的絕對路徑。ui
按照上述的方法會有一個問題,就是執行下面的代碼的時候,即便用了process.client,但仍是會報tinymce不存在的錯誤:this
if (process.client) { tinymce.init({ ...options, ...this.otherOptions, language: this.language, }); )
緣由是,客戶端打包的時候,tinymce確實是沒有定義的。因此這裏改爲以下形式便可:
if (process.client) { window.tinymce.init({ ...options, ...this.otherOptions, language: this.language, }); )
nuxt有一個組件是no-ssr組件,因此上面的html最好用no-ssr包起來,否則會報tinymce組件沒有定義的錯誤:
<no-ssr placeholder="Loading..."> <tinymce id="myTinymce" v-model="content" :height="600" /> </no-ssr>