vue-cookie-law
vue-cookie-law copied to clipboard
Version 1.13.0 broke SSR
nuxt 2.12.2 vue 2.6.11 vue-cookie-law 1.13.2
Prior to version 1.13.0 I was using this plugin with Nuxt, and it was working perfectly. Nuxt render pages server-side, so I had to put the <vue-cookie-law> component in a <client-only> tag, like this:
<client-only>
<cookie-law
button-class="btn btn-primary"
></cookie-law>
</client-only>
With this new version, it is not working anymore, as I'm getting this error:
ReferenceError window is not defined node_modules/vue-cookie-law/dist/vue-cookie-law.js@15:4
Here a repro link with the version 1.13.2 installed: https://codesandbox.io/s/old-water-s4p24
Hm that is weird. I have it running in an older nuxt project with the <no-ssr> component which should be now the client-only component. And it was working fine.
But I will look into this.
Precision, just the import trigger the error. Don't even need to add the component.
Just add this in a .vue page : import CookieLaw from 'vue-cookie-law' and the error appears.
Might be related to the new webpack 4 build setup.
Comparing v.1.12
(function webpackUniversalModuleDefinition(root, factory) {
--
7 | if(typeof exports === 'object' && typeof module === 'object')
8 | module.exports = factory();
9 | else if(typeof define === 'function' && define.amd)
10 | define("CookieLaw", [], factory);
11 | else if(typeof exports === 'object')
12 | exports["CookieLaw"] = factory();
13 | else
14 | root["CookieLaw"] = factory();
15 | })(this, function() {
and v.1.13
(function webpackUniversalModuleDefinition(root, factory) {
--
7 | if(typeof exports === 'object' && typeof module === 'object')
8 | module.exports = factory();
9 | else if(typeof define === 'function' && define.amd)
10 | define("CookieLaw", [], factory);
11 | else if(typeof exports === 'object')
12 | exports["CookieLaw"] = factory();
13 | else
14 | root["CookieLaw"] = factory();
15 | })(window, function() {
It looks like this got replaced with window.
Further issues with 1.13.3 SSR build:
/node_modules/vue-cookie-law/dist/vue-cookie-law.js:972 var styleElement = document.querySelector('style[' + ssrIdKey + '~="' + obj.id + '"]') ^ ReferenceError: document is not defined at addStyle
Same here
Please use the old version for now. It is still a webpack build issue. Need to investigate further.
Already have it locked to 1.12.0 in my project, for the time being. Thanks for looking into this.
Not sure it's the best solution, but a workaround :
let CookieLaw;
if (process.client) {
CookieLaw = require("vue-cookie-law").default;
}
I can confirm that this is a huge problem. Nuxt and Vue users can't use this plugin, anymore. Please fix it soon :))
/node_modules/vue-cookie-law/dist/vue-cookie-law.js:972 var styleElement = document.querySelector('style[' + ssrIdKey + '~="' + obj.id + '"]') ^ ReferenceError: document is not defined at addStyle
Another, failing solution
So, I tried to load it dynamically, but still get an error:
<client-only>
<CookieLaw theme="aatheme" buttonText="Vielen Dank »">
<div slot="message">
We use cookies.
</div>
</CookieLaw>
</client-only>
export default {
components: {
TheHeader,
TheFooter,
'CookieLaw': () => import('vue-cookie-law')
},
}
Error message
ERROR [Vue warn]: Failed to resolve async component: () => Promise.resolve(/*! import() */).then(__webpack_require__.t.bind(null, /*! vue-cookie-law */ "vue-cookie-law", 7))
Reason: ReferenceError: document is not defined
@apertureless
Looks like this option should be set to default 'window'
https://github.com/apertureless/vue-cookie-law/blob/eb35aa33ccc138d551ff9bc28765a978f2de1f41/build/webpack.release.js#L33
@lxzxl
Sadly nope. I had to set this to this to fix the first error in this issue (window is not defined)
And the webpack config also confirms this:
https://webpack.js.org/configuration/output/#outputglobalobject
When targeting a library, especially when libraryTarget is 'umd', this option indicates what global object will be used to mount the library. To make UMD build available on both browsers and Node.js, set output.globalObject option to 'this'.
The current error has something to do with the styles that get injected. But I need to investigate further.
I'll try to debug it.
Thanks that would be great. I am currently very low on time.
The issue in general is, that the dynamic style loading of webpack breaks. An easy'ish workaround would be to extract the CSS so people have to import it, themself.
However this would be a breaking change. Thats why I was looking for other solutions to this. However, it there are not other solutions I would go with the extracting of css.
Thanks for looking into this.
I assumed that having a separate css file is how it should be anyways (like the majority of 3rd party components I use in my project). Due to it being a breaking change, couldn't it simply be released as a new major version?
On Mon, 11 May 2020 at 05:45, Jakub [email protected] wrote:
Thanks that would be great. I am currently very low on time.
The issue in general is, that the dynamic style loading of webpack breaks. An easy'ish workaround would be to extract the CSS so people have to import it, themself.
However this would be a breaking change. Thats why I was looking for other solutions to this. However, it there are not other solutions I would go with the extracting of css.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/apertureless/vue-cookie-law/issues/67#issuecomment-626625593, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAWU3VT3RLO25JMXCIMJV3RQ7JLJANCNFSM4LZW36IA .
This works for me:
// plugins/cookie-law.ts
import Vue from 'vue'
import CookieLaw from 'vue-cookie-law'
export default () => {
Vue.component('cookie-law', CookieLaw)
}
// nuxt.config.ts
plugins: [
...
{src: '@/plugins/cookie-law', mode: 'client'}
]
// file.vue
<client-only>
<cookie-law theme="base" />
</client-only>
@tre-dev This works indeed. Small precision, ssr: false is deprecated and mode: 'client' is now the preferred syntax.
@tre-dev I use Gridsome (so my Vue knowledge is probably less than that of Nuxt.js users), but I should be able to translate that.
you can try dynamic import:
components: {
CookieLaw: () => {
if (process.client) {
return import(/* webpackChunkName: 'vue-cookie-law' */ 'vue-cookie-law')
}
},
},
By the way, for people using basic Vue SSR without Nuxt.js, you must put the following (the declaration) into the entry-client.js file:
Vue.component('cookie-law', CookieLaw);
And in your component template (PUG style):
client-only
cookie-law
works also with nuxt
components: { CookieLaw: () => (process.client ? import('vue-cookie-law') : null), },