-
-
Notifications
You must be signed in to change notification settings - Fork 178
Bug report: Minification causes runtime error for a special variable name #311
Description
Bug report
Setup
Package versions
webpack: 4.8.3
uglify-es: 3.3.9
uglifyjs-webpack-plugin: 1.2.5
babel: 6.23.0
Babel setup
{
"presets": [
"react",
["env", {
"modules": false,
"useBuiltIns": true,
"targets": {
"browsers": [
"last 2 Chrome versions", "not Chrome < 60",
"last 2 Safari versions", "not Safari < 10.1",
"last 2 iOS versions", "not iOS < 10.3",
"last 2 Firefox versions", "not Firefox < 54",
"last 2 Edge versions", "not Edge < 15"
]
}
}]
],
"plugins": [
["transform-object-rest-spread", {
"useBuiltins": true
}],
"transform-class-properties"
]
}
Webpack setup
{
entry: '...',
output: '...',
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: babel
}]
},
optimization: {
minimizer: [
new UglifyJsPlugin({
sourceMap: true,
uglifyOptions: {
ecma: 6
}
})
]
}
};
Code samples
Working example
Source code:
const TYPES = {
type: {
subtype: ['field']
}
}
const FIELDS = {
field: ['property']
}
function getHashTable(type, subtype) {
return TYPES[type][subtype].map(field => {
return FIELDS[field].includes('property');
})
}
function doStuff(data, table) {
// some heavy operation not necessary for showcase
return data || table;
}
const minificationError = props => data => {
const { type, x } = props;
console.log(type, x);
const temp = getHashTable(type, x);
return doStuff(data, temp);
}
console.log(minificationError({
type: 'type',
x: 'subtype'
})())
Minified code:
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.r=function(e){Object.defineProperty(e,"__esModule",{value:!0})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=1)}([function(e,t){const n={type:{subtype:["field"]}},r={field:["property"]};var o;console.log((e=>t=>{const u=e.type,c=e.x;console.log(u,c);const p=(o=c,n[u][o].map(e=>r[e].includes("property")));return t||p})({type:"type",x:"subtype"})())},function(e,t,n){e.exports=n(0)}]);
It first logs type subtype
then [true]
.
Non-working example
Source code:
const TYPES = {
type: {
subtype: ['field']
}
}
const FIELDS = {
field: ['property']
}
function getHashTable(type, subtype) {
return TYPES[type][subtype].map(field => {
return FIELDS[field].includes('property');
})
}
function doStuff(data, table) {
// some heavy operation not necessary for showcase
return data || table;
}
const minificationError = props => data => {
const { type, subtype } = props;
console.log(type, subtype);
const temp = getHashTable(type, subtype);
return doStuff(data, temp);
}
console.log(minificationError({
type: 'type',
subtype: 'subtype'
})())
Minified code:
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.r=function(e){Object.defineProperty(e,"__esModule",{value:!0})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=1)}([function(e,t){const n={type:{subtype:["field"]}},r={field:["property"]};var o;console.log((e=>t=>{const o=e.type,u=e.subtype;console.log(o,u);const p=(u=u,n[o][u].map(e=>r[e].includes("property")));return t||p})({type:"type",subtype:"subtype"})())},function(e,t,n){e.exports=n(0)}]);
This throws Uncaught TypeError: Assignment to constant variable
.
Description of the problem
Hello everyone, we're trying to switch from using webpack + babel to transpiling source code to es5 to only transpiling to es6 and using <script type="module"> because we don't need support for old browsers.
We found out there is an issue with how our webpack + babel + uglify-es handles one of our files. Above is the source code reduced down as much as possible. What happens is that there is a destructuring assignment and then two funnction calls that handle data. When upon minification, the result of first function gets directly inserted into the second function:
const a = fn1();
return fn2(a);
becomes
return fn2(fn1(a))
but there is an issue with function arguments.
When the argument is called subtype
minification somehow screws up with variables and tries to assing to a const
. Different name of variable, such as x
does not cause a problem (see source code above).
The problem occurs even with the default minimizer, which is why we've tried to override it with ecma option.
In my opinion, variable name should not cause such a difference, which is why I've decided to submit this bug report.
Thank you!