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

DefinePlugin breaks references to imports #18573

Open
rtsao opened this issue Jul 12, 2024 · 1 comment
Open

DefinePlugin breaks references to imports #18573

rtsao opened this issue Jul 12, 2024 · 1 comment
Labels

Comments

@rtsao
Copy link
Contributor

rtsao commented Jul 12, 2024

Bug report

What is the current behavior?

When an imported identifier shadows a nested DefinePlugin definition, references to the import are broken when they are in a more complex expression (e.g. assignment to a new variable). This results in a ReferenceError being introduced.

import foo from './foo.js';

function works() {
  return foo.bar;
}

function broken() {
  const bar = foo.bar;
  return bar;
}

works(); // does not throw
broken(); // throws ReferenceError
DefinePlugin({"foo.bar.baz": "baz"});

If the current behavior is a bug, please provide the steps to reproduce.

Added failing minimal test here: #18572

What is the expected behavior?

import foo from './foo.js';

function works() {
  return foo.bar;
}

function broken() {
  const bar = foo.bar;
  return bar;
}

works(); // does not throw
broken(); // should NOT throw ReferenceError
DefinePlugin({"foo.bar.baz": "baz"});

Other relevant information:
webpack version: 5.93.0
Node.js version: 20
Operating System: MacOS
Additional tools:


Note that this does not appear to be a recent regression, this has been broken for a long time.

I originally found this bug in this scenario:

import process from 'global/process';

const foo = process?.env?.SOME_VAR;

Babel transforms this optional chaining into:

var _process$env;
import process from 'global/process';
const foo = process === null || process === void 0 || (_process$env = process.env) === null || _process$env === void 0 ? void 0 : _process$env.SOME_VAR;
console.log(foo);

This bug is triggered by this code: webpack breaks the reference to the imported process.env within the chained logical expression, resulting in a ReferenceError in browsers because process.env is obviously undefined.

Notably, this code breaks with default webpack configuration, as DefinePlugin is automatically applied:

if (options.optimization.nodeEnv) {
const DefinePlugin = require("./DefinePlugin");
new DefinePlugin({
"process.env.NODE_ENV": JSON.stringify(options.optimization.nodeEnv)
}).apply(compiler);
}

@alexander-akait
Copy link
Member

PR welcome, we need to skip replacing when it used as reference, thank you for a report

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Priority - Medium
Development

No branches or pull requests

2 participants