parcel
parcel copied to clipboard
parcel build produces wrong minified js
🐛 bug report
I used https://github.com/TimTCrouch/WordList-JS in my app (which basically involves including https://github.com/TimTCrouch/WordList-JS/blob/master/src/wordList.js and https://github.com/TimTCrouch/WordList-JS/blob/master/src/wordBank.js in my index.html) and used "parcel build" to produce a bundle for browsers.
"parcel build" produced a wrong minified js for wordList.js with 2 issues:
- the global variable Word_List https://github.com/TimTCrouch/WordList-JS/blob/master/src/wordList.js#L10 was stripped
- the return statement https://github.com/TimTCrouch/WordList-JS/blob/master/src/wordList.js#L71 was stripped
After the 2 mentioned issues were manually fixed, my bundle worked. I reproduced the same error using the original https://github.com/TimTCrouch/WordList-JS/blob/master/testing.html instead of my index.html
🎛 Configuration (.babelrc, package.json, cli command)
The test setup I cloned https://github.com/TimTCrouch/WordList-JS to add my setup for using parcel here: https://github.com/minnie80/test-build-wordlistjs/blob/test-build-with-parcel/package.json
cli commands Build: npm run build Test: npm run prod
The test app http://localhost:3000/testing.html
🤔 Expected Behavior
The minified js in the bundle produced by "parcel build" should be correct. The corrected script:
var Word_List = (function () {
var t = {},
o = [];
(t.isInList = function (t) {
return o[(t = t.toLowerCase()).charAt(0)].indexOf(t) > -1;
}),
(t.getRandomWord = function (t) {
0 == (t = t || 0) && (t = Math.floor(7 * Math.random()) + 4),
t < 4 && (t = 4),
t > 10 && (t = 10);
var r,
n,
a = String.fromCharCode(Math.floor(26 * Math.random()) + 97);
do (r = Math.floor(Math.random() * o[a].length)), (n = o[a][r]);
while (n.length != t);
return n;
}),
(t.loadBank = function (t) {
var r = t[12].charAt(0);
if (!r)
throw "Not able to get first letter from word to determine word bank.";
o[r] = t;
});
return t;
})();
😯 Current Behavior
The incorrect script produced by "parcle build" (re-formatted by prettier.io):
!(function () {
var t = {},
o = [];
(t.isInList = function (t) {
return o[(t = t.toLowerCase()).charAt(0)].indexOf(t) > -1;
}),
(t.getRandomWord = function (t) {
0 == (t = t || 0) && (t = Math.floor(7 * Math.random()) + 4),
t < 4 && (t = 4),
t > 10 && (t = 10);
var r,
n,
a = String.fromCharCode(Math.floor(26 * Math.random()) + 97);
do (r = Math.floor(Math.random() * o[a].length)), (n = o[a][r]);
while (n.length != t);
return n;
}),
(t.loadBank = function (t) {
var r = t[12].charAt(0);
if (!r)
throw "Not able to get first letter from word to determine word bank.";
o[r] = t;
});
})();
💁 Possible Solution
🔦 Context
💻 Code Sample
🌍 Your Environment
Software | Version(s) |
---|---|
Parcel | v2.9.3 |
Node | v18.16.1 |
npm/Yarn | npm v9.5.1 |
Operating System | Windows 10 |
I think I may be experiencing something similar with our project. The local dev server will run/build the code properly, but the minified build output is missing a symbol for react-router which breaks the entire app. This is a problem for us in 2.9.2 and 2.9.3 but not in 2.8.1. Out of curiosity, does your example work in 2.8.1?
Does it work with the --no-optimize
CLI flag?
@devongovett yes, it works with --no-optimize
flag.
I think I may be experiencing something similar with our project. The local dev server will run/build the code properly, but the minified build output is missing a symbol for react-router which breaks the entire app. This is a problem for us in 2.9.2 and 2.9.3 but not in 2.8.1. Out of curiosity, does your example work in 2.8.1?
Yes, it works with 2.8.1. The minified for https://github.com/minnie80/test-build-wordlistjs/blob/test-build-with-parcel/src/wordList.js formatted by prettier.io
var Word_List = (function () {
var r = {},
t = new Array();
return (
(r.isInList = function (r) {
var o = (r = r.toLowerCase()).charAt(0);
return t[o].indexOf(r) > -1;
}),
(r.getRandomWord = function (r) {
0 == (r = r || 0) && (r = Math.floor(7 * Math.random()) + 4),
r < 4 && (r = 4),
r > 10 && (r = 10);
var o,
a,
n = Math.floor(26 * Math.random()),
e = String.fromCharCode(n + 97);
do {
(o = Math.floor(Math.random() * t[e].length)), (a = t[e][o]);
} while (a.length != r);
return a;
}),
(r.loadBank = function (r) {
var o = r[12].charAt(0);
if (!o)
throw "Not able to get first letter from word to determine word bank.";
t[o] = r;
}),
r
);
})();
//# sourceMappingURL=testing.8ef956dc.js.map
I don't mean to hijack this thread, but I feel like I have a similar issue. It's hard to create a reproducible repo, as it seems to be a combination of many factors (and after a full day of debugging, I'm still unsure what).
I'm building a React app, with Orval, TanStack, React Query, Axios, and the dev build works fine. The production build however produces a an error within Axios because of a missing import (link to the specific line that fails in the production build, validator.assertOptions
is undefined, thus crashing). In watch mode, or when running with --no-optimize
this problem does not occur.
The next question is whether this is a bug in Parcel itself or in the new SWC minifier that we switched to in v2.9. Could you all try building your project with @parcel/optimizer-terser
instead and see if that fixes the issue? To do that, install @parcel/optimizer-terser
with npm and add this to your .parcelrc
:
{
"extends": "@parcel/config-default",
"optimizers": {
"*.js": ["@parcel/optimizer-terser"]
}
}
Thanks @devongovett, appreciate it! For me that yields a perfectly valid bundle that passes all tests 👌 Hope that helps in your investigation.
{ "extends": "@parcel/config-default", "optimizers": { "*.js": ["@parcel/optimizer-terser"] } }
yes, that fixed my issue with [email protected]. Thanks!
As I mentioned in #9119, using the terser optimiser also resolved the problem for me. Does that indicates a problem in the swc minifier?
Same problem and resolution here:
- ✅ dev build works fine
- ❌ production build with
@parcel/optimizer-swc
has missing symbols - ✅ production build with
@parcel/optimizer-terser
works fine
Are you all using <script>
elements in your HTML without type="module"
? I noticed this in the original reproduction, and SWC appears to generate different output depending on the module flag. Is that a common thread here?
I am using a <script>
tag with type="module"
.
Are you all using
<script>
elements in your HTML withouttype="module"
? I noticed this in the original reproduction, and SWC appears to generate different output depending on the module flag. Is that a common thread here?
We're using type="module" as well
Likewise, I'm using type="module"
:
<script type="module" src="app.ts"></script>
That being said, I have noticed that I get two output JS files:
ui/dist/ui.0a6c46e3.js 415 KB 1.63s
ui/dist/ui.6eb97b68.js 415.06 KB 1.65s
Which appears to be differential bundling:
<script type="module" src="/assets/ui.6eb97b68.js"></script>
<script src="/assets/ui.0a6c46e3.js" nomodule defer></script>
I'm surprised that this is happening as I attempted to only target very recent browsers:
"targets": {
"default": {
"distDir": "ui/dist",
"publicUrl": "/assets",
"engines": {
"browsers": "since 2023"
}
}
},
I was testing with Chrome Canary when I noticed the problem, so I'd expect that it was using the type="module"
version.
Same error for me, and I fixed it using "@parcel/optimizer-terser"
Following this advice (see also https://github.com/parcel-bundler/parcel/issues/9179), I changed to using the terser optimiser. Is there an update of the swc minifier? Should I now revert to using the swc minifier?
I am still using the terser optimiser. Should I revert to the swc minifer now?
I removed my usage of @parcel/optimizer-terser
and don't appear to have any minification issues. However, that's not a ringing endorsement because I recall that the error was hard to trigger and I have multiple projects using Parcel and some needed this workaround and others didn't. At least at this point, it appears to work for me. 🤷
I've also now removed the optimizer-terser call and it seems to be working for me.