nvms / vue-atlas

A Vue.js 2 UI component library.
MIT License
180 stars 22 forks source link

nuxt js ReferenceError window is not defined #161

Open canersevince opened 4 years ago

canersevince commented 4 years ago

vue-atlas.js

import Vue from 'vue' import vueAtlas from 'vue-atlas' import 'vue-atlas/dist/vue-atlas.css'

Vue.use(vueAtlas, 'en')


nuxt-config.js

plugins: [ '@/plugins/vue-atlas', ]

image

canersevince commented 4 years ago

can anyone help me ?

santiagodls commented 4 years ago

Same problem over here. This occurs when you try to import the entire library, because AnimQueue and Collapse modules depends on velocity-animate, which only works on browsers. Partial solution is simple: import only the components you need, and if you need to use AnimQueue or Collapse components just wrap them into nuxt's <client-only> component, so ssr will ignore them:

// plugins/vue-atlas.ts
import Vue from 'vue'
import { VaButton } from 'vue-atlas/src/Button'
import 'vue-atlas/dist/vue-atlas.css'

Vue.use(VaButton)

Also transpilation configurations is needed:

// nuxt.config.ts
export default {
  ...
  build: {
    transpile: [
      'vue-atlas/src/Button'
    ]
  },
  ...
}

And you should enable sass if you hadn't yet:

npm i -D node-sass sass-loader

In order to be able to use Collapse component on nuxt ssr, velocity-animate should be loaded conditionally as nuxt's docs says

hendrikgaffo commented 4 years ago

I had this issue too and did some digging. It seems like velocity-animate does not check if window is available or undefined. The exact issue is line 13 of the velocity-animate library.

I can highly recomment patch-package for that matter. It lets you create patches for dependencies.

So that's what I did. I will give you the copy & paste solution, since I already have it in place. But you could totally write the patch yourself, in case you want to understand better what is going on.

1. Install patch-package

yarn add patch-package

2. Create a folder called patches in the root of your nuxt project.

3. Inside of patches, create a file called velocity-animate+1.5.2.patch with the following content:

diff --git a/node_modules/velocity-animate/velocity.js b/node_modules/velocity-animate/velocity.js
index 3881bf9..0bb4416 100644
--- a/node_modules/velocity-animate/velocity.js
+++ b/node_modules/velocity-animate/velocity.js
@@ -10,7 +10,8 @@
 /* These shimmed functions are only used if jQuery isn't present. If both this shim and jQuery are loaded, Velocity defaults to jQuery proper. */
 /* Browser support: Using this shim instead of jQuery proper removes support for IE8. */

-(function(window) {
+if(typeof window !== "undefined"){
+   (function(window) {
    "use strict";
    /***************
     Setup
@@ -4771,3 +4772,5 @@
 /* The CSS spec mandates that the translateX/Y/Z transforms are %-relative to the element itself -- not its parent.
  Velocity, however, doesn't make this distinction. Thus, converting to or from the % unit with these subproperties
  will produce an inaccurate conversion value. The same issue exists with the cx/cy attributes of SVG circles and ellipses. */
+
+}
\ No newline at end of file

4. In your package.json, create a new entry inside of the scripts section:

"scripts": {
  // your other scripts like 'build', 'dev', etc
  "postinstall": "patch-package"
}

5. Reinstall your dependencies. The patch will be applied automatically:

yarn

This also works like a charm when deploying your app, because the postinstall hook gets executed.

ddcodepl commented 3 years ago

Hey @canersevince should be used only on client side as it's reffering to the window you shouldn't execute it on server side.

So there are two solutions to do that.

  1. Change your plugin name with appending .client.js so it will be vue-atlas.client.js - This tells to the the project it shouldn't be used on the server side

  2. You can apply mode in nuxt.config.js so it will be -

plugins: [
    {src: '@/plugins/vue-atlas.js', mode: 'client'}
]

https://nuxtjs.org/docs/2.x/directory-structure/plugins