alexplumb/material-ui-phone-number

Reference error when used in server side rendering app

Opened this issue ยท 15 comments

When this library is used in SSR react app, window is not defined error comes up.

+1

Can you verify that this isn't working in material-ui-phone-number@2.2.4?

@alexplumb it is not working (also tried with NoSsr from material).
It works using dynamic import from nextjs but it flicks and loads later them all other components outside NoSsr

I don't have a NextJS or other SSR project that I can use to test this - do you have a reproducible code repo that you can share, or a codesandbox link?

The same error with window. I'm using Nextjs

> Build error occurred
ReferenceError: window is not defined
    at r (....../node_modules/material-ui-phone-number/dist/index.js:1:82978)
    at i (....../node_modules/material-ui-phone-number/dist/index.js:1:83066)
    at n.exports (....../node_modules/material-ui-phone-number/dist/index.js:1:86103)
    at Object.<anonymous> (....../node_modules/material-ui-phone-number/dist/index.js:1:69470)
    at t (....../node_modules/material-ui-phone-number/dist/index.js:1:186)
    at Module.<anonymous> (....../node_modules/material-ui-phone-number/dist/index.js:1:91153)
    at t (....../node_modules/material-ui-phone-number/dist/index.js:1:186)
    at ....../node_modules/material-ui-phone-number/dist/index.js:1:985
    at Object.<anonymous> (....../node_modules/material-ui-phone-number/dist/index.js:1:996)
    at Module._compile (internal/modules/cjs/loader.js:701:30)
error Command failed with exit code 1.

I think problem in /scheduler/ module, somewhere here

// Capture local references to native APIs, in case a polyfill overrides them.
  var performance = window.performance;
  var _Date = window.Date;
  var _setTimeout = window.setTimeout;
  var _clearTimeout = window.clearTimeout;

FYI: A workaround that works for me is to use next/dynamic:

export const MuiPhoneNumber = dynamic(
  () => import("material-ui-phone-number"),
  {
    ssr: false
  }
);

Another workaround is to use react-loadable and material-ui/nossr since react-loadable only supports CSR.

import Loadable from 'react-loadable';
import NoSsr from '@material-ui/core/NoSsr';
import CircularProgress from '@material-ui/core/CircularProgress';

const MuiPhoneNumber = Loadable({
  loader: () => import('material-ui-phone-number'),
  loading: CircularProgress
});

...
<NoSsr>
  <MuiPhoneNumber />
</NoSsr>

Background

@neallred and I ran into this issue as well and dug into it a bit more because we were unable to utilize material-ui/nossr. It looks like this issue has the same root cause as issues #49 and #15, but luckily it can be pretty easily fixed (see proposed solution below).

Issue Details

The SSR build-time error is occurring because of the style-loader dependency, specifically the style injection supporting IE<=9 here: https://github.com/webpack-contrib/style-loader.

Minimal Reproduction (using Gatsby)

Repo: https://github.com/braxtonex/minimal-reproduction
Steps to reproduce:

  1. Clone repo
  2. Install dependencies (npm install)
  3. Optional: View functioning development server (gatsby develop)
  4. Attempt build to see error (gatsby build)
  5. View error:
WebpackError: ReferenceError: window is not defined

  - index.js:1 r
    node_modules/material-ui-phone-number/dist/index.js:1:82916
  - index.js:1 i
    node_modules/material-ui-phone-number/dist/index.js:1:82980
  - index.js:1 n.exports
    node_modules/material-ui-phone-number/dist/index.js:1:85983
  - index.js:1 Object../node_modules/material-ui-phone-number/dist/index.js
    node_modules/material-ui-phone-number/dist/index.js:1:69402
  - index.js:1 t
    node_modules/material-ui-phone-number/dist/index.js:1:112
  - index.js:1 Module.<anonymous>
    node_modules/material-ui-phone-number/dist/index.js:1:91091
  - index.js:1 t
    node_modules/material-ui-phone-number/dist/index.js:1:112
  - index.js:1 ./node_modules/material-ui-phone-number/dist/index.js
    node_modules/material-ui-phone-number/dist/index.js:1:915
  - index.js:1 Object../node_modules/material-ui-phone-number/dist/index.js
    node_modules/material-ui-phone-number/dist/index.js:1:934
  - index.js:1 Module../src/pages/index.js
    src/pages/index.js:1:1

Proposed Solution

Because material-ui-phone-number already has a CSS in JS styling solution using withStyles() we could convert all Less styling to JSS and remove less & style-loader, along with other associated loaders (css-loader & less-loader).

Here's a link to a PR that implements this proposed solution: #54

Changes:

  • Converts the flag styles from Less to JSS
  • Removes the now unneeded dependencies and associated webpack rules
  • Adds classes necessary to pass JSS styling to components

It appears to work well and would not be a breaking change.

I'd love to hear any feedback you have @alexplumb !

@alexplumb Thoughts on the above solution? This PR should solve this issue.

@alexplumb Thoughts on the above solution? This PR should solve this issue.

Just FYI - I tried @braxex 's PR on a Gatsby site and it seems to have fixed the SSR problem for me. Thanks @braxex !

@alexplumb Thoughts on the above solution? This PR should solve this issue.

Just FYI - I tried @braxex 's PR on a Gatsby site and it seems to have fixed the SSR problem for me. Thanks @braxex !

Glad to hear it was useful for you - always happy to help a fellow Twin Cities dev! I also deployed an NPM package with the PR for use in the meantime if that helps.

Hi there, can we have this pr merged?