tsdx: breaks are transpiled to return inside then
Current Behavior
While working on my code I noticed a bug that led to my transpiled files and I saw that tsdx was incorrectly transforming my break inside switch cases to return.
I thoughts that was rather odd so I created a sample project with the following code to pinpoint the issue:
function wait() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, 1000);
});
}
export const test = async () => {
await wait();
switch ('' as any) {
case 'a':
break;
case 'b':
break;
default:
break;
}
const foo = { bar: true };
console.log('foo :', foo);
};
When running tsdx build, this is what I get:
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
function wait() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve();
}, 1000);
});
}
var test = function test() {
try {
return Promise.resolve(wait()).then(function () {
switch ('') {
case 'a':
return;
case 'b':
return;
default:
return;
}
var foo = {
bar: true
};
console.log('foo :', foo);
});
} catch (e) {
return Promise.reject(e);
}
};
exports.test = test;
//# sourceMappingURL=switch-test.cjs.development.js.map
As you can see, inside test, breaks inside then are transformed to returns, which is NOT correct. The console.log line would never be reached.
Expected behavior
breaks inside then should stay breaks.
Suggested solution(s)
No idea. The problem may come from babel or rollrup or one of their plugins. Any idea what may cause the problem?
Your environment
| Software | Version(s) |
|---|---|
| TSDX | 0.12.3 |
| TypeScript | ^3.7.5 |
| Browser | |
| npm/Yarn | yarn 1.19.1 |
| Node | 10.16.3 |
| Operating System | Linux, but same behavior on windows |
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 3
- Comments: 16 (1 by maintainers)
Another comment on that issue revealing more broken code: https://github.com/rpetrich/babel-plugin-transform-async-to-promises/issues/49#issuecomment-656050437. And still no response / maintenance.
At this point, I think it would be optimal to switch to regenerator because at least the code it produces is actually correct and not broken in subtle, hard-to-detect ways. I’m also not sure really how much difference in weight it adds as a polyfill because
babel-plugin-transform-async-to-promisesalso adds helpers, it’s not just a polyfill vs. no polyfill comparison.async-to-promiseshas been replaced withbabel-plugin-polyfill-regeneratorin #795 and will be released in v0.14.0 soon. It will only pure polyfill generators fortargetsthat need a polyfill according to yourbrowserslistrcorpreset-envtargetsNot to just add unnecessary noise, but this drove me crazy! I discovered even more broken examples where the emitted code would literally use things like
_break4or_break2in a different scope than they were declared, code that was not just incorrect but could be statically determined to be incorrect! Compiling to non-regenerator-runtime code is a noble goal, but ultimately I can’t justify using tsdx when it’s in this state. It does bother me to have to essentially “eject” because of such a glaring issue when otherwise the project is so useful.One of the main reasons I’m writing this comment is so people who search something like
_break4or_break2can find this and see the problem!Thank you @agilgur5 and @hb-seb for trying to resolve this! I hope it can be resolved soon.
Ah gotcha, that makes sense. Yea I can see why some workarounds can be annoying for people with multiple packages, though you might not need this everywhere.
The other option is to create a shareable
tsdx.config.js, like:Though if something like this is officially adopted (I’m planning on making an RFC soon), it would probably look more like a plugin than a shareable config:
You can of course do either (or both) unofficially though. The RFC will be to establish a spec for compatibility and to ideally eventually bring some common use cases in as “core” plugins (esp. since they can be brittle). But we’ll see how that goes.
Yea, unfortunately since it’s upstream and hasn’t been responded to in ~3 months it might take a while 😞 . In the meantime, your fork is likely to become out-of-sync, so it becomes a maintenance burden for you to update 😕
@schickling I did say in the above comment I was looking to switch to regenerator. That’s the only other option as far as I know. TSDX also already bundles in regenerator if one uses generators (the
async/awaitpart is turned off)Looks like there was another incorrect transpilation brought up from this plugin: #423 / https://github.com/rpetrich/babel-plugin-transform-async-to-promises/issues/53 .
EDIT: Also seems like #190 is related. But that doesn’t seem to error if it’s used standalone
Would probably be good to consider replacing this, especially since it hasn’t been maintained the past few months (although regenerator maybe the only good alternative) 😕
Yes, that’s what I initially wanted to do, but then I realized I’d have to perform the same process for each new project. That’d defeat the process of using a initializer like TSDX. I wanted something that just works out of the box without me copy-pasting stuff from previous projects. I’ll jump back to
tsdxonce it is fixed and doesn’t need any extra step 😃.