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
Optional chain is incorrectly removed when used on import #12960
Comments
I am also facing the same issue. Thank you. |
I'm also seeing this problem. |
Other example #13792 |
@vankop @sokra It looks like you two were the original authors on #11221 so I hope you can help — I spent some time understanding the root cause and looking at potential fixes, but I got stuck. It looks like this issue has been present since the initial PR and is not a regression. The root cause is that a parser code path of webpack/lib/javascript/JavascriptParser.js Line 106 in 911ec1a
The reason it only happens for imports is that the code path only applies when webpack/lib/javascript/JavascriptParser.js Lines 3478 to 3486 in 911ec1a
One approach to solve this is changing Another approach I tried is changing It seems like a larger refactor might be needed, unless you can recommend another solution that someone like me (with no prior experience contributing to webpack) would be able to do. |
@alexander-akait @sokra Any suggested workarounds for this issue? |
A simple workaround we've found is referencing the imported module as another variable. For example: import x from './x.js';
const xRef = x;
console.log(`optional value is: ${xRef?.value}`); Not ideal, but it works until this can be fixed. |
Yeah i've resorted to doing something similar, it's just a large codebase and i'm not certain i've got em all |
I also ran into this issue. To avoid this issue cropping back up before a fix is implemented, I ended up forcing optional chaining to be transformed by babel before webpack has a chance to remove it. Obviously this removes the actual optional chaining operators in the bundled code, but at least it's functionally equivalent. babel.config.js: module.exports = {
presets: [
[
'@babel/preset-env',
{
// force optional chaining transform
include: ['proposal-optional-chaining'],
// omitting the rest of my preset-env config for brevity
}
],
]
}; |
Snowpack users are likely to run into this issue, and we came up with a similar solution to this one to configure Snowpack's Webpack plugin.
I didn't realise the |
I'm not sure if this is the same issue but maybe it is so I will not open another issue. Although I'm using no babel but only ts-loader I get the same behaviour. const id = this.props.id || store.data[0]?._id || '' Is transpiled to const e = this.props.id || n.data[0]._id || ""; Loosing the optional chaining will generate some run-time error if the array is empty. I created a minimal reproduction here. A fix of the issue would be of great help! Thanks Jochen |
this is not fixed yet |
Well I understand this has been merged into the main branch just an hour ago and will be available with the next release 5.64.5. Did you use this in your test? In fact nothing changed in 5.64.4 but in my opinion this is as expected. |
thats not a fix, only part of it |
No, this issue about supporting export * as c from './c.js' index.js import * as a from './a.js'
a.c?.b // or
a?.c?.b
// right now will produce
a.c.b
a.c.b to produce optional chain in output we need |
With 5.65.0 and output: { ..., environment: { optionalChaining: true } }, const id = this.props.id || store.data[0]?._id || '' Is still transpiled to const e = this.props.id || n.data[0]._id || ""; when targeting ES2020. |
@JMS-1 I think your problem is not related to webpack, do you use babel? |
If webpack encountered |
No the problem ist that the ?. is removed bevore it event gets to the ts-loader. const path = require('path')
module.exports = {
entry: { index: path.join(__dirname, './src/index.ts') },
mode: 'production',
module: { rules: [{ test: /\.(ts|tsx)$/, use: 'ts-loader' }] },
output: { filename: '[name].js', path: path.join(__dirname, 'build'), environment: { optionalChaining: true } },
resolve: { extensions: [".js", '.ts'] },
} |
Sorry, possible silly question: how do I define |
It is not yet implemented, work before is just stage to prepare fix |
Just in case someone (like me) thought this was fixed on 5.65.0. It is still not fixed. |
solved in |
5.71.0 now works even without |
yes, this is solved in 5.71 |
Bump dependencies to their latest version to bring important bug-fixes like webpack/webpack#12960
**User-Facing Changes** None **Description** Upgrades webpack and removes the workaround for webpack/webpack#12960 introduced in #1638. The bug was fixed upstream in webpack 5.71.0.
Bug report
What is the current behavior?
Webpack incorrectly compiles
x?.value
to(something).value
whenx
is something that's been imported.If the current behavior is a bug, please provide the steps to reproduce.
webpack.config.js:
index.js:
x.js:
Produces dist/main.js:
which leads to
TypeError: Cannot read property 'value' of undefined
at runtime.What is the expected behavior?
The
?
should be retained or converted to a ternary operator.When
import x from './x.js';
is removed and replaced withconst x = (() => void console)();
(something complicated enough that webpack doesn't completely constant-fold it), the output is:which is as expected (the
?
is retained).Other relevant information:
webpack version: latest, 5.27.2
Node.js version: v15.9.0
Operating System: macOS 11.2.2
The text was updated successfully, but these errors were encountered: