Repository navigation
breaks are transpiled to return inside then #509
Copy link
Copy link
Closed
Labels
kind: bugSomething isn't workingSomething isn't workingscope: upstreamIssue in upstream dependencyIssue in upstream dependencytopic: async-to-promisesRelated to bugs with babel-plugin-async-to-promisesRelated to bugs with babel-plugin-async-to-promises
Description
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.mapAs 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 |
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
kind: bugSomething isn't workingSomething isn't workingscope: upstreamIssue in upstream dependencyIssue in upstream dependencytopic: async-to-promisesRelated to bugs with babel-plugin-async-to-promisesRelated to bugs with babel-plugin-async-to-promises
Activity
CyriacBr commentedon Feb 12, 2020
So, seems like this is due to rpetrich/babel-plugin-transform-async-to-promises#49.
Can
tsdxmove away frombabel-plugin-transform-async-to-promises?agilgur5 commentedon Feb 13, 2020
Thanks for tracking down the root cause @CyriacBr ! That certainly seems problematic 🙁 As far as I know, TSDX uses it because it is a syntax transform instead of a runtime polyfill, therefore no need to use
regenerator-runtime.There are some alternatives, like
fast-async, but that seems less used and less maintained 🙁I'm not 100% sure if there's a way to disable it with a custom
babelrc(it is merged with TSDX's normally, would have to look into that). You might be able to make some small modifications to your code in the meantime to workaround that bug, but idkCyriacBr commentedon Feb 13, 2020
For now I'm going to override the rollup config and only use
@rollup/typescriptfor compilation and transpilation.agilgur5 commentedon Feb 13, 2020
Ok sure, overriding
rollup-plugin-typescript2'stargetis an option as well. TS does use a generator polyfill however -- see microsoft/TypeScript#31621 about transpiling to promises instead.Can also override
rollup-plugin-babelto stay closer to TSDX. Can see the plugins used internally here.I'm looking to add a Babel preset to help make customizing these types of things easier, #383 has some progress on that.
Removing an option is a the difficult part here though; there's this old issue about Babel not allowing you to disable a plugin within a preset (different from how ESLint works), but maybe that's no longer true with
overrides. Haven't faced this issue before (first time reading aboutoverridesetc), sorry I can't be more helpful on that front.CyriacBr commentedon Feb 14, 2020
Alright. For the time being I ended up forking TSDX and removed anything babel related. If anyone passing by and encountered the same issue, you can thing my fork here, and it's published. I'm fine with TS's runtime polyfill.
TSDX has been my go-to initializer for many months now, thanks a lot for setting up that.
agilgur5 commentedon Feb 16, 2020
Ok, I don't normally recommend forking and the other maintainers recommend using
patch-packagefor internal changes.I'm also pretty sure this can be worked around with just a
tsdx.config.jslike I said above (that's what I thought you were going to do too), either overridingrollup-plugin-babel's config (that way you can remove plugins) or overridingrollup-plugin-typescript2's config to changetargetto something lower.CyriacBr commentedon Feb 16, 2020
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 :).agilgur5 commentedon Feb 16, 2020
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 😕
agilgur5 commentedon Mar 6, 2020
Looks like there was another incorrect transpilation brought up from this plugin: #423 / rpetrich/babel-plugin-transform-async-to-promises#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) 😕
agilgur5 commentedon Jul 19, 2020
Another comment on that issue revealing more broken code: rpetrich/babel-plugin-transform-async-to-promises#49 (comment). 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.schickling commentedon Jul 31, 2020
agilgur5 commentedon Jul 31, 2020
rivertam commentedon Aug 19, 2020
Not 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.
agilgur5 commentedon Sep 20, 2020
@allcontributors please add @CyriacBr for bug
allcontributors commentedon Sep 20, 2020
@agilgur5
I've put up a pull request to add @CyriacBr! 🎉
agilgur5 commentedon Sep 20, 2020
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-envtargets