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

Different result from evaluation of in operator in build time vs runtime #15765

Closed
JoSuzuki opened this issue May 3, 2022 · 3 comments
Closed

Comments

@JoSuzuki
Copy link

JoSuzuki commented May 3, 2022

Bug report

What is the current behavior?

Starting from version 5.71.0, when evaluating the operation const hasPortalSupport = 'createPortal' in ReactDOM. It generates a bundle with const hasPortalSupport = false. Probably connected with PR #15455.

I've created a stackblitz repo, with the relevant files

index.js

import ReactDOM from 'react-dom';

const hasPortalSupport = 'createPortal' in ReactDOM;

const getReactDOM = () => ReactDOM;

const hasPortalSupportRuntime = 'createPortal' in getReactDOM();

console.log('hasPortalSupport', hasPortalSupport); // false

console.log('hasPortalSupportRuntime', hasPortalSupportRuntime); // true

webpack.config.js

const path = require('path');

module.exports = {
  mode: 'production',
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist'),
  },
};

package.json

{
  "name": "getting-started-using-a-configuration",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack",
    "start": "serve dist"
  },
  "keywords": [],
  "author": "",
  "license": "MIT",
  "dependencies": {
    "react": "17.0.2",
    "react-dom": "17.0.2"
  },
  "devDependencies": {
    "serve": "^12.0.0",
    "webpack": "^5.72.0",
    "webpack-cli": "^4.9.2"
  }
}

What is the expected behavior?

The expected behavior is that the build time eval equals the runtime eval. The expression const hasPortalSupport = 'createPortal' in ReactDOM; should be evalued as const hasPortalSupport = true;

Other relevant information:
webpack version: 5.72.0 (the bug starts to happen in version 5.71.0)
Node.js version: v16.14.2
Operating System: Ubuntu 20.04.4 LTS

@vankop
Copy link
Member

vankop commented May 4, 2022

@JoSuzuki in operator could be evaluated only with import specifiers. So in your case we can't evaluate. you can change your code to

import * as ReactDOM from 'react-dom';

const hasPortalSupportRuntime = 'createPortal' in ReactDOM;

to make build time evaluation work

@vankop vankop closed this as completed May 4, 2022
@JoSuzuki
Copy link
Author

JoSuzuki commented May 4, 2022

@vankop I see, I will update the code accordingly, pardon my ignorance, I have a hard time understanding the way modules are exported/imported, but just to see if I understood more or less of what is happening:

with import ReactDOM from 'react-dom' in build time, webpack tries to import the default export from react-dom which doesn't exist, therefore it is evaluated as false, but it exists in runtime because of something webpack (or depending on the tools babel, or tsconfig) does to normalize the way the imports are made.

by importing with import * as ReactDOM from 'react-dom' we are importing everything that is exported (and not just the default) with the name of ReactDOM which can then be evaluated correctly.

one last question: in build time can't know we that the syntax import ReactDOM from 'react-dom' would be "wrong", so that we are able to bail out from the evaluation and keep the original value?

@vankop
Copy link
Member

vankop commented May 4, 2022

ok.. I see what you mean this was fixed in master #15660 not published yet

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

No branches or pull requests

3 participants