StreamSaver.js icon indicating copy to clipboard operation
StreamSaver.js copied to clipboard

npm i streamsaver -> how to use in react ?

Open x4080 opened this issue 4 years ago • 19 comments

Hi, I tried it in react using

import streamSaver from 'streamsaver'

And it shows error : window is not defined

How to use it with npm ?

Thanks

x4080 avatar May 18 '20 22:05 x4080

React.js or react native?

jimmywarting avatar May 18 '20 22:05 jimmywarting

Hi @jimmywarting thanks for quick reply, its react js, my current workaround is using

<script src="https://cdn.jsdelivr.net/npm/[email protected]/StreamSaver.min.js"></script>

and put it in root html

x4080 avatar May 18 '20 23:05 x4080

I just remembered maybe its because of ssr, this was in my next js project, when it is importing, no window object available

x4080 avatar May 18 '20 23:05 x4080

@x4080 : you import it with: import * as streamsaver from 'streamsaver' You can see an example here:

dreamofi avatar May 24 '20 10:05 dreamofi

@dreamofi Thanks, I'll try it

x4080 avatar May 24 '20 21:05 x4080

@dreamofi Thanks it works !

x4080 avatar May 24 '20 21:05 x4080

@dreamofi No, I make mistake, it works when the link is in the client, but when rendered from server its not working

x4080 avatar May 24 '20 21:05 x4080

@x4080 can you post your webpack configuration file?

dreamofi avatar May 25 '20 02:05 dreamofi

@dreamofi , I'm using next js and my next.config.js seems not using custom webpack config so it goes like this

const withSass = require('@zeit/next-sass');
const withOffline = require('next-offline')
module.exports = withSass(withOffline());

Thanks for your help

x4080 avatar May 26 '20 00:05 x4080

@x4080 I have yet used nextjs, but what is the error when you render from the server, and can you post the code where you use streamsaver? Do you add ponyfill?

dreamofi avatar May 29 '20 11:05 dreamofi

@dreamofi It's simple actually, 'window is not defined' when it rendered on server

x4080 avatar May 29 '20 21:05 x4080

@dreamofi you should be able to load the dependencies on componentDidMount and set it on the component, since this life cycle is guaranteed to only run on the client.

  componentDidMount() {
    // HACK: streamsaver references window which is undefined on SSR. Ensure library is only loaded on client
    try {
      this.streamSaver = require('streamsaver');
      if (!this.streamSaver.WritableStream) {
        this.streamSaver.WritableStream = require('web-streams-polyfill/ponyfill').WritableStream;
      }
    } catch (e) {
      console.error(e);
    }
  }

  someFunction = () => {
    const fileStream = this.streamSaver.createWriteStream('hi-there.mp4');
    ...
  }

@jimmywarting any chance we can prevent such errors by checking against window (const isSSR = typeof window === "undefined")? Current calls to window will keep crashing SSR builds on Next.js, Gatsby, etc. https://github.com/jimmywarting/StreamSaver.js/blob/1bce493b16fd51cf313570445e2b9f96045393cb/StreamSaver.js#L15

jonsadka avatar Aug 03 '20 07:08 jonsadka

maybe should use globalThis instead?

jimmywarting avatar Aug 03 '20 08:08 jimmywarting

@jimmywarting yeah I think that would work!

jonsadka avatar Aug 03 '20 14:08 jonsadka

any updates on this?

pedro-pedrosa avatar Sep 15 '20 19:09 pedro-pedrosa

if window is not defined then you probably are using streamsaver in a wrong context like some server side render like next or in a web worker.

only include streamsaver on the client side (on the main thread)

jimmywarting avatar Sep 15 '20 21:09 jimmywarting

I'm using dynamic imports on my code for now to work around this. was just asking because there was a suggestion of using globalThis in place of window.

I guess if StreamSaver.js is supposed to be a browser-only module and window is supposed always work, then this issue should be closed to avoid confusion.

pedro-pedrosa avatar Sep 16 '20 09:09 pedro-pedrosa

Webpack 5 might be able to solve this issue with its recently added native Worker support.

eligrey avatar Oct 28 '20 05:10 eligrey