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

Moving hook call to another module and importing result breaks RHL #1280

Closed
rfgamaral opened this issue Jul 2, 2019 · 6 comments
Closed

Comments

@rfgamaral
Copy link

Description

I'm using Material-UI and the makeStyles hook to style my application. Everything is working fine when the makeStyles call is in the same file I'll be using it's output. When I place this call in a different file and import the result, RHL breaks.

For instance, take this Application.tsx file:

import React from 'react';

import { hot } from 'react-hot-loader';

import Container from '@material-ui/core/Container';
import CssBaseline from '@material-ui/core/CssBaseline';
import Paper from '@material-ui/core/Paper';
import Typography from '@material-ui/core/Typography';

import { makeStyles } from '@material-ui/core/styles';

interface Props {
    name: string;
}

const useStyles = makeStyles(theme => ({
    container: {
        marginTop: theme.spacing(8)
    },
    paper: {
        padding: theme.spacing(3, 2)
    }
}));

function Application(props: Props): JSX.Element {
    const classes = useStyles();
    const { name } = props;

    return (
      <React.Fragment>
        <CssBaseline />
        <Container className={classes.container} maxWidth="md">
          <Paper className={classes.paper}>
            <Typography variant="h5" component="p" align="center">
              {'Hello there '}
              <span role="img" aria-label="Waving Hand">
                            👋
              </span>
              {`, ${name}`}
            </Typography>
          </Paper>
        </Container>
      </React.Fragment>
    );
}

export default hot(module)(Application);

Note: As you can see I'm using TypeScript with React.

The example above works just fine with RHL, no issues whatsoever.

But now I've changed Application.tsx to this:

import React from 'react';

import { hot } from 'react-hot-loader';

import Container from '@material-ui/core/Container';
import CssBaseline from '@material-ui/core/CssBaseline';
import Paper from '@material-ui/core/Paper';
import Typography from '@material-ui/core/Typography';

import { useStyles } from './Application.styles';

interface Props {
    name: string;
}

function Application(props: Props): JSX.Element {
    const classes = useStyles();
    const { name } = props;

    return (
      <React.Fragment>
        <CssBaseline />
        <Container className={classes.container} maxWidth="md">
          <Paper className={classes.paper}>
            <Typography variant="h5" component="p" align="center">
              {'Hello there '}
              <span role="img" aria-label="Waving Hand">
                            👋
              </span>
              {`, ${name}`}
            </Typography>
          </Paper>
        </Container>
      </React.Fragment>
    );
}

export default hot(module)(Application);

And Application.styles.ts:

import { makeStyles } from '@material-ui/core/styles';

export const useStyles = makeStyles(theme => ({
    container: {
        marginTop: theme.spacing(8),
    },
    paper: {
        padding: theme.spacing(3, 2),
    },
}));

Expected behavior

What you think should happen:

When saving Application.tsx file, RHL should work as expected and without any errors.

Actual behavior

What actually happens:

When saving Application.tsx file, RHL shows this error:

image

Environment

React Hot Loader version: v4.12.0

Run these commands in the project folder and fill in their results:

  1. node -v: v10.15.0
  2. yarn -v: v1.16.0

Then, specify:

  1. Operating system: Windows 10 (WSL)
  2. Browser and version: Firefox Quantum 68.0b14 (64-bit)

Reproducible Demo

I apologize in advanced for not having a demo project yet. If one is really necessary, please let me know and I'll get it pushed as soon as I'm able to.

@theKashey
Copy link
Collaborator

theKashey commented Jul 2, 2019

I recon this is a babel plugin :)

Could you please:

  • open /node_modules/react-hot-loader/dist/babel.development.js
  • find getHookCallsSignature around 200 line
  • change
.map(function (call) {
        return call.callee;
      })
/// to
.map(function (call) {
        return t.cloneDeep(call.callee);
      })

If that would fix the problem - that would be great!

I've tried to reproduce your case, but with no luck. You may also just copy here transpiled version of your component, problem should be there.

PS: This was "fixed" at #1268 just a few days ago, but, look like, not in full.

@rfgamaral
Copy link
Author

If that would fix the problem - that would be great!

FYI, Before this change, every 2 file saves (no exception) showed that error above. With the fix above, I re-ran Parcel (the bundler I'm using) and I got the error once and never again. I quit Parcel server, re-ran again and never got the error again.

So I guess that actually fixed the problem? 😃

@theKashey
Copy link
Collaborator

Sounds like a cache.
Could you run parcel with --no-cache and verify that it's working yet again.
And I could you share you babel config - we knew that the problem might exists, but still don't know how to reproduce it.

@rfgamaral
Copy link
Author

Yeah, it was a cache issue :)

.babelrc:

{
  "plugins": [
    "react-hot-loader/babel"
  ],
  "presets": [
    [
      "@babel/preset-env",
      {
        "modules": false
      }
    ],
    "@babel/preset-react"
  ]
}

package.json:

"alias": {
    "react-dom": "@hot-loader/react-dom"
  },
  "dependencies": {
    "@hot-loader/react-dom": "16.8.6",
    "@material-ui/core": "4.1.3",
    "@material-ui/icons": "4.2.1",
    "react": "16.8.6",
    "react-dom": "16.8.6",
    "react-hot-loader": "4.12.0"
  },

tsconfig.json:

{
  "compilerOptions": {
    "allowJs": true,
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "jsx": "react",
    "lib": [
      "dom",
      "es2017"
    ],
    "module": "es6",
    "moduleResolution": "node",
    "noEmitOnError": true,
    "noImplicitAny": true,
    "noImplicitReturns": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "outDir": "./dist/",
    "removeComments": true,
    "sourceMap": true,
    "strict": true,
    "suppressImplicitAnyIndexErrors": true,
    "target": "es5"
  },
  "exclude": [
    ".cache",
    "dist",
    "node_modules",
    "temp"
  ],
  "include": [
    "./src/**/*"
  ]
}

@theKashey
Copy link
Collaborator

And just to double-double check - you already had ‘t.clone’ there, and just made it more “deep”?
Just trying to understand how it possible, and how to create a test.

@rfgamaral
Copy link
Author

No, I had return call.callee;.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants