-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature Request] Add "preserveConstEnums" option to transform-typescript #6476
Comments
Hey @ForbesLindesay! We really appreciate you taking the time to report an issue. The collaborators If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack |
I'm not sure if this would be a good thing to support... in my opinion, |
I've always been confused by that flag. Why not just remove |
The reason is that const enums are a useful optimisation in production, and I can handle them by just using the full typescript compiler for the prod build. In development. I want to make the build as fast as possible by using babel for everything and compiling each module independently. |
I use const enum in declaration files(not exporting it), it is useful for distinguishing custom obj type. |
The
For us, loosing the |
const string enums are even more fantastic, because then you're essentially just dealing with strings. |
@andy-ms EDIT: We went with unique symbols for our use-case. |
@nojvek Is there any advantage to a string const enum type over a union of string literal types? type COUNTRIES = "austria" | "germany" | "greece" | "brazil"; |
@nicoburns Autocomplete / usability by the developers? |
here's an example where it'd be useful:
in my own app, I use |
@mattkrick Can't you also do |
As @mattkrick says, sometimes the values are not as clear as "germany" and const string enums can be very clarifying, while still compiling to the raw string, avoiding any overhead. But partly, it's an expectations thing. const string enums are part of typescript, they're useful and not having them is surprising to developers (even if the reason for their current absence is reasonable). It also means, for example, babel-node can't be a drop-in replacement for ts-node, which is a shame. |
I came across an issue related to this today. Imagine if you are in a monorepo project that has Using normal const types_1 = require("@MyApp/types");
// ...
types_1.SIZE.BIG and But now, we get an issue in |
Prior art (Sucrase): alangpierce/sucrase#423 (comment)
|
Is it possible to write a babel plugin to run before |
I went through the babel-handbook. It's pretty simple. The
Just traverse the whole AST and set them all to Here is what I have so far (you guys can run it in node). I still need to read the part on how to create a plugin. $ npm install @babel/parser @babel/traverse @babel/types @babel/generator // const-enum.js
const parser = require('@babel/parser');
const { default: traverse } = require('@babel/traverse');
const types = require('@babel/types');
const { default: generate } = require('@babel/generator');
const code = `
const enum Enum {
A = 1,
B = A * 2
}
`.trim();
console.log(`Before:
${code}
`);
const ast = parser.parse(code, {
sourceType: 'module',
plugins: ['typescript']
});
traverse(ast, {
enter(path) {
if (types.isTSEnumDeclaration(path.node, { const: true })) {
path.node.const = false;
}
}
});
console.log(`
After:
${generate(ast).code}
`.trim()); $ node const-enum.js |
You can experiment here: https://astexplorer.net/ |
@nicolo-ribaudo I saw that site, but I don't see TypeScript support, only JavaScript. The plugin has to be a TypeScript to TypeScript transpiler. So then you can feed that into |
You can click on the gear next to the parser (in the header), and enable TypeScript support for Babylon 7. (which is the old name of @babel/parser) |
@nicolo-ribaudo, using JavaScript + babylon7, I get
I tried on the babel site and noticed that enabling The only combinations that work on AST explorer are JavaScript + one of the following:
The only transformer that works is I wonder why I don't have any problems in node, without having to enable |
Did you click on the gear next to "babylon7" and enable it's TypeScript plugin? |
Oh, my mistake. I misunderstood the UI and what you said earlier. I thought parser dropdown and the gear was the same thing. Didn't notice the gear was separate settings for the parser. Thanks! Hmm, now I have the parser working, but not the transformer: Seems like their list of plugins for their babelv7 transformer doesn't have |
Actually, I figured out a workaround. I just cloned their repo to run locally with modified code. I changed |
Yay! I finished my plugin, babel-plugin-const-enum. Add to your {
"plugins": [
"const-enum"
]
} The default is to remove the The README has more information. You can test at the online repl by adding the plugin on bottom left. Feel free to file issues or send in PRs at the GitHub Repo. This is my first time writing a plugin so there are things that can be improved. |
Really awesome @dosentmatter ! @ForbesLindesay, considering there are some tradeoffs / footguns with the approach in your original description, is this plugin enough to close this issue? Maybe along with some documentation about const enums and this plugin in some FAQ or something in the Babel TypeScript docs? |
Yes, we should definitely link it in our docs. |
Docs are updated in master now |
Why is |
@qm3ster, the reason I chose |
What's the status on this? Would really like to use |
@vegerot, I saw you commented #8741 (comment) and you got a reply on that issue to use If you need the plugin to only run on TS files, you can use the |
Thank you. I'll look into it |
When using the typescript compiler, there is an option to "preserve const enums", which essentially just treats const enums exactly the same as non-const enums. It would be really useful to have the same feature in the babel transform.
Input Code
Babel Configuration (.babelrc, package.json, cli command)
Expected Behavior
Current Behavior
Throws: 'const' enums are not supported
Possible Solution
Add an option that makes const enums behave exactly the same as regular enums.
Context
I want to be able to use babel to transform my typescript in development, as this will be much faster than doing a babel pass and a typescript pass, and babel is needed for other plugins. In production, I can use the slower typescript transform, which handles const enums properly.
The text was updated successfully, but these errors were encountered: