Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

server-side rendering - window.addEventListener is not a function #49

Open
desandro opened this issue Jun 5, 2019 · 14 comments
Open

server-side rendering - window.addEventListener is not a function #49

desandro opened this issue Jun 5, 2019 · 14 comments
Labels
bug Something isn't working

Comments

@desandro
Copy link
Member

desandro commented Jun 5, 2019

If you try to load Zdog in outside an browser-less environment like on server-side, you will likely run into an error

dragger.js:84 Uncaught TypeError: window.addEventListener is not a function
    at Item.Dragger.dragStart (dragger.js:84)
    at Item.Illustration.dragStart (illustration.js:232)
    at Item.Dragger.onmousedown.Dragger.onpointerdown (dragger.js:73)
    at Item.Dragger.handleEvent (dragger.js:67)

Zdog currently expects browser environment for things like window and document. My basic recommendation is to add a conditional to disable loading Zdog on the server, and enable it for the browser. I'm not a server-side rendering expert, so any guidance here on how to manage would be appreciated.


Add a 👍 reaction to this issue if you've ran into this issue so I know how prevalent this is.

@desandro desandro added the bug Something isn't working label Jun 5, 2019
@aarongoin
Copy link

aarongoin commented Jun 5, 2019

I'm seeing this client-side when using parcel to bundle my app. I haven't done the steps to ensure this isn't just a parcel issue yet though. Anyone with a webpack/rollup build seeing this as well?

@remimi
Copy link

remimi commented Jun 5, 2019

I have the same issue as @aarongoin using classic vue app. I'm currently trying to do a little wrapper to make Zdog work in Vue environnement (someone is already doing the react one 😌 )

It's just a try for now.

@marcelinollano
Copy link

@aarongoin interesting, I am also using parcel and having the same issue.

@partynikko
Copy link

partynikko commented Jun 5, 2019

I'm having the same issue using parcel.
Seems like an empty window object is being used hence why addEventListener is not available.

@yofrancisco
Copy link

Hey i had the same issue, i solved it by making the listener the canvas instead of the window. I'm not 100% sure yet if this has any unintended side effects.

mango-chutney@ece47f1

@desandro
Copy link
Member Author

desandro commented Jun 7, 2019

i solved it by making the listener the canvas instead of the window. I'm not 100% sure yet if this has any unintended side effects.

Yes this change has side effects with dragging, preventing movement and drag end event triggering unless the pointer is within the rendering element.

@statikowsky
Copy link

I think this might be caused when dragger.js is being loaded as a commonjs module.

}( this, function factory( window ) {
expects this to be window, but for commonjs modules this will not be true.

If you are using webpack you can remedy this by using imports-loader.
The following webpack config worked for me:

 module: {
    rules: [
      {
        test: require.resolve('./node_modules/zdog/js/dragger.js'),
        use: 'imports-loader?this=>window'
      },
      ...
    ]
  }

Here are the webpack docs: https://webpack.js.org/guides/shimming/#granular-shimming
A similar configuration should be possible for other bundlers.

@kylios
Copy link

kylios commented Jun 9, 2019

I am having the same issue client-side, using webpack-dev-server. @statikowsky 's workaround seemed to fix the issue for me.

@maxackerman
Copy link

Similar issue happening for me, I'm using import and babel in my build process. Zdog is rendering but, I'm getting this error when trying to drag:

TypeError: window.addEventListener is not a function

@vuchl
Copy link

vuchl commented Jun 26, 2019

I used the solution of @statikowsky with a vue ui set up project.

I needed to add a vue.config.js to the project root with this content

// vue.config.js
module.exports = {
  configureWebpack: {
    module: {
      rules: [
        {
          test: require.resolve('./node_modules/zdog/js/dragger.js'),
          use: 'imports-loader?this=>window'
        },
      ]
    }
  }
}

I also use this library via vue-zdog wrapper and needed to install some more packages (and for some reason zdog too) via npm install --save import-loader vue-runtime-helpers zdog it started to work.

@talentlessguy
Copy link

Same issue with Parcel 😢

Code:

import { Illustration, Shape } from 'zdog'

let illo = new Illustration({
  element: '#app',
  dragRotate: true,
})

new Shape({
  addTo: illo,
  path: [
    { x: -60, y: -60 },   // start
    { bezier: [
      { x:  20, y: -60 }, // start control point
      { x:  20, y:  60 }, // end control point
      { x:  60, y:  60 }, // end point
    ]},
  ],
  closed: false,
  stroke: 20,
  color: '#636'
});

function animate() {
  illo.updateRenderGraph()
  requestAnimationFrame(animate)
}

animate()

@vickylance
Copy link

vickylance commented Aug 18, 2019

Is this not still fixed? :( I am facing the same issue.
I am using parcel to bundle. Eventually I want to use it on my Gatsby website. If it doesn't work with parcel I doubt it will work with Gatsby.

@luchoster
Copy link

luchoster commented Oct 17, 2019

Is this not still fixed? :( I am facing the same issue.
I am using parcel to bundle. Eventually I want to use it on my Gatsby website. If it doesn't work with parcel I doubt it will work with Gatsby.

This works fine with Gatsby. Just install imports-loader and then add this to your gatsby-node.js

exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => {
  if (stage === 'build-html') {
    actions.setWebpackConfig({
      module: {
        rules: [
          {
            test: require.resolve('./node_modules/zdog/js/dragger.js'),
            use: loaders.null(),
          },
        ],
      },
    })
  } else {
    actions.setWebpackConfig({
      module: {
        rules: [
          {
            test: require.resolve('./node_modules/zdog/js/dragger.js'),
            use: 'imports-loader?this=>window',
          },
        ],
      },
    })
  }
}
  • commenting for future reference and help with Gatsby.

desandro added a commit that referenced this issue Oct 23, 2019
Addresses `this = window` mismatch with Webpack, Parcel, Gatsby.
@desandro
Copy link
Member Author

In SHA: 3566dcb, I removed setting window to this and instead rely on global window value, plus added some internal checks in case window is undefined. This fix is released in v1.1.1.

Please update and let me know of any lingering issues. Thanks all for your insights here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Development

No branches or pull requests