dead-code-elimination: doesn't remove the value of unused const (let/var too?)
- Dominant language
- JavaScript
- Stars
- 4.4k
- Forks
- 217
- PR merge metrics
- No merged PRs in 30d
Description
**Describe the bug**
I'm just experimenting with set of plugins and presets, plus terser to see what is happening.
In one of the `if` branches that I have, I have unused const variable, what dead-code-elimination is doing is that it's removing the `const val =` an the value remains.
**To Reproduce**
Minimal code to reproduce the bug
```js
const foo = (str: string) => {
const pro = /(?\d{4})-(?\d{2})-(?\d{2})/
if (process.env.NODE === '123') {
return 1234
}
if (process.env.WAS === str) {
const someRe = new RegExp(`
# A regular expression for date.
(?\\d{4})- # year part of a date
(?\\d{2})- # month part of a date
(?\\d{2}) # day part of a date
`, 'x');
return pro
}
return process.env.BAR || process.env.QUX === 'sas'
}
console.log(foo('was was'))
```
with config shown below.
And run it with
```
WAS='was was' babel index.ts -d dist -x .ts
```
**Actual Output**
Which outputs
```js
const foo = str => {
const pro = /(\d{4})-(\d{2})-(\d{2})/;
if ("was was" === str) {
/(\d{4})-(\d{2})-(\d{2})/;
return pro;
}
return void 0 || void 0 === 'sas';
};
console.log(foo('was was'));
```
Now, you can see it's clearly not correct - the regex remains and changes the meaning completely. Only the `const someRe =` is removed. It's not some collision of the `modern-regexp` transform. When we remove that transform it still just removes the `const someRe=` instead of the whole regex thing block.
That is a problem, because the above output later can be minified with terser to a thing that means totally different thing:
```js
const foo=o=>{return"was was"===o&&/(\d{4})-(\d{2})-(\d{2})/}
```
Where you can clearly see that it is not correct.
**Expected Output**
If this dead-code-elimination plugin was working right it would remove the const and the whole regex so the terser's output will be something like
```js
const foo=o=>{return /(\d{4})-(\d{2})-(\d{2})/}
```
and the following when not minified
```js
const foo = str => {
const pro = /(\d{4})-(\d{2})-(\d{2})/;
if ("was was" === str) {
return /(\d{4})-(\d{2})-(\d{2});
}
return void 0 || void 0 === 'sas';
};
console.log(foo('was was'));
```
**Stack Trace**
none
**Configuration**
Using pieces of `babel-minify`.
babel.config.js
```js
const modernRegex = false
module.exports = {
presets: [
'@babel/preset-typescript',
'@babel/preset-modules'
],
plugins: [
'babel-plugin-annotate-pure-calls',
'babel-plugin-dev-expression',
'babel-plugin-minify-builtins',
'babel-plugin-transform-inline-environment-variables',
'babel-plugin-transform-modern-regexp',
'babel-plugin-transform-node-env-inline',
'babel-plugin-transform-undefined-to-void',
'babel-plugin-minify-dead-code-elimination',
'babel-plugin-unassert',
].filter(Boolean)
}
```
How are you using babel-minify?
Babel CLI
```json
"dependencies": {
"@babel/cli": "^7.8.0",
"@babel/core": "^7.8.0",
"@babel/preset-modules": "^0.1.2",
"@babel/preset-typescript": "^7.8.0",
"@types/node": "^13.1.6",
"babel-plugin-annotate-pure-calls": "^0.4.0",
"babel-plugin-dev-expression": "^0.2.2",
"babel-plugin-minify-builtins": "^0.5.0",
"babel-plugin-minify-dead-code-elimination": "^0.5.1",
"babel-plugin-transform-inline-environment-variables": "^0.4.3",
"babel-plugin-transform-modern-regexp": "^0.0.6",
"babel-plugin-transform-node-env-inline": "^0.4.3",
"babel-plugin-transform-undefined-to-void": "^6.9.4",
"babel-plugin-unassert": "^3.0.1",
"terser": "^4.6.2"
}
```
**Possible solution**
Don't know.
Contributor guide
Research direction
Start with the minimal TypeScript reproduction and babel.config.js, then run it through the Babel CLI with babel-plugin-minify-dead-code-elimination enabled. Compare the transformed output with the expected output, including the unused RegExp initializer, and verify that the plugin no longer leaves a standalone expression that changes behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- babel, javascript, typescript
- Domain
- build-system, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100