zdog icon indicating copy to clipboard operation
zdog copied to clipboard

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

Open desandro opened this issue 5 years ago • 14 comments

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 avatar Jun 05 '19 13:06 desandro

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?

aarongoin avatar Jun 05 '19 13:06 aarongoin

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.

remimi avatar Jun 05 '19 14:06 remimi

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

marcelinollano avatar Jun 05 '19 15:06 marcelinollano

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

partynikko avatar Jun 05 '19 22:06 partynikko

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.

https://github.com/mango-chutney/zdog/commit/ece47f116215357850745e0a134686eef575126e

yofrancisco avatar Jun 07 '19 06:06 yofrancisco

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.

desandro avatar Jun 07 '19 13:06 desandro

I think this might be caused when dragger.js is being loaded as a commonjs module. https://github.com/metafizzy/zdog/blob/125bda077e142ed066fba1f59bec5d4ef9713d94/js/dragger.js#L14 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.

statikowsky avatar Jun 08 '19 08:06 statikowsky

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

kylios avatar Jun 09 '19 19:06 kylios

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

maxackerman avatar Jun 18 '19 20:06 maxackerman

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.

vuchl avatar Jun 26 '19 12:06 vuchl

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()

talentlessguy avatar Jun 29 '19 13:06 talentlessguy

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.

vickylance avatar Aug 18 '19 11:08 vickylance

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.

luchoster avatar Oct 17 '19 00:10 luchoster

In SHA: 3566dcb30275a5999037cb2b4804d1df017b12b3, 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.

desandro avatar Oct 23 '19 13:10 desandro