SSR build says "document is not defined" for a Vuejs cli3 SPA app using a Vue cli3 library
Asked Answered
P

1

7

I have a fairly complex SPA Vue.js app created with Vue CLI v3. I want to transform this app to benefit from SSR (although I might end up using only preprendering...)

My app is using custom Vuejs libraries created with the CLI v3 as well. These libs embbed CSS, and I would like to continue to do so.

I've probably read everything that the world has produced on Vue cli, vue-loader, vue-style-loader, vue.config.js, extract css etc, but I keep failing.

Here is the error message of my running app when I load a given route:

ReferenceError: document is not defined
    at addStyle (/Users/onekiloparsec/code/my-app/node_modules/vue-custom-lib/dist/vue-custom-lib.common.js:699:22)
    at addStylesToDom (/Users/onekiloparsec/code/my-app/node_modules/vue-custom-lib/dist/vue-custom-lib.common.js:683:20)
    at addStylesClient (/Users/onekiloparsec/code/my-app/node_modules/vue-custom-lib/dist/vue-custom-lib.common.js:637:3)
    at Object.3351 (/Users/onekiloparsec/code/my-app/node_modules/vue-custom-lib/dist/vue-custom-lib.common.js:500:14)
    at __webpack_require__ (/Users/onekiloparsec/code/my-app/node_modules/vue-custom-lib/dist/vue-custom-lib.common.js:21:30)
    at Object.d12e (/Users/onekiloparsec/code/my-app/node_modules/vue-custom-lib/dist/vue-custom-lib.common.js:3590:380)
    at __webpack_require__ (/Users/onekiloparsec/code/my-app/node_modules/vue-custom-lib/dist/vue-custom-lib.common.js:21:30)
    at Module.fae3 (/Users/onekiloparsec/code/my-app/node_modules/vue-custom-lib/dist/vue-custom-lib.common.js:3859:51)
    at __webpack_require__ (/Users/onekiloparsec/code/my-app/node_modules/vue-custom-lib/dist/vue-custom-lib.common.js:21:30)
    at /Users/onekiloparsec/code/my-app/node_modules/vue-custom-lib/dist/vue-custom-lib.common.js:85:18
    at Object. (/Users/onekiloparsec/code/my-app/node_modules/vue-custom-lib/dist/vue-custom-lib.common.js:88:10)
    at Module._compile (internal/modules/cjs/loader.js:701:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)
    at Module.load (internal/modules/cjs/loader.js:600:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:539:12)
    at Function.Module._load (internal/modules/cjs/loader.js:531:3)

When clicking the first line of the error, I get the following code from the commonjs file of my lib:

function addStyle (obj /* StyleObjectPart */) {
  var update, remove
  var styleElement = document.querySelector('style[' + ssrIdKey + '~="' + obj.id + '"]')
...

I don't know if I need to change things in my lib (I think so) or in my app, or both.

Here is the vue.config.js of my lib:

module.exports = {
  css: {
    extract: false
  }
}

But I also tried extract: true and (a lot) more sophisticated stuff.... I get always the same error.

Is there a way to integrate Vue cli 3 lib with CSS into a SSR Vue app??? Thanks a lot.

Pneumodynamics answered 18/7, 2019 at 20:54 Comment(2)
I was just running in to the same issue.... try updating @vue/cli-service to the latest (at the time of writing, it's at 3.11.0)Donia
Same issue - any luck?Mahler
D
0

You experienced this error because when the application is building process is done on the server-side where no document exists. You can append an element to document styles by finding an element with querySelector:

  var styleElement = document.querySelector('style[' + ssrIdKey + '~="' + obj.id + '"]')

only when JavaScript append to the page is interpreted by the browser (no node js).

You have two options in this case:

  1. Manage styling on the server-side (you can't use `document)
  2. Manage styling on the client-side (you can use document)

In option 1 - server-side you will probably resign from using your vue-custom-lib package or create a fork that checks if the environment is browser or node js. Eg.:

if(process) { you are in node js }
if(window) { you are in the browser - you can use the document.querySelector } 

In option 2 I recommend you check Nuxt.

You can add a package with document in head.script property in nuxt.config.js

export default {
  head: {
    script: [
      { src: '...' }
    ]
  },

you should also read about detecting server and client-side in the Nuxt context

https://nuxtjs.org/api/context/

Configuration build that has also the property isServer:

https://nuxtjs.org/api/configuration-build

Appending your custom library can be done also in renderAndGetWindow function

https://nuxtjs.org/api/nuxt-render-and-get-window

Distorted answered 3/10, 2020 at 11:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.