简体   繁体   中英

Typescript const enum alternative

More and more modern Typescript transpilers have moved toward a strategy of per-module transpilation, which significantly increases build speed, but eliminates the possibility for cross-module const enum usage, since transpilation of them requires type information.

I have a significant amount of const enums that when used without the inlining that const provides:

  1. End up being hundreds of KBs even after minification due to long property names
  2. Leak internal, backend property names that I don't want public

Right now I have these const enum definitions auto generated from backend native code. As a contrived example, you can imagine I work at Apple and have a great big const enum of every hardware device.

const enum HardwareType {
    Apple1 = 0,
    // ...
    iPhoneX = 412,
    // ...
    iPhoneUltraXD = 499, // Some theoretical unannounced iPhone
}

If I just change const enum HardwareType to enum HardwareType , in addition to bumping up my bundle size, I've now leaked the new "iPhone Ultra XD" to the public.

I see that something like Terser supports the --mangle-props option , but even that seems to be warned against in the official docs and also would mean creating a regex that covers every single HardwareType ? Not to mention that's just my contrived example and I have dozens of these enums in reality with hundreds of values.

I'd really like to use the latest tech for application bundling, but is there really not a better option out there for compile time inlining of constant values?

const enum is not very secure in hiding original names. As you can see in that playground typescript compiler adds original names in comments:

// Input:
const enum Fruites {
    Apple = 1,
    Banana = 2
}

const x = Fruites.Apple
const y = Fruites.Banana

// Output:
"use strict";
const x = 1 /* Apple */;
const y = 2 /* Banana */;

If your a really wondering to use the latest tech for application bundling and want to hide some secret names from output files, try to use esbuild-loader or esbuild itself. It support define option that allows you to replace some secret naming with meaningless values in compilation time like that

define: {
  "secrets.hardwareType.iPhoneUltraXD": "499"
}

and safely use the defined value in source code

// Source code: 
if (deviceId === secrets.hardwareType.iPhoneUltraXD) {
// Bundled code:
if(deviceId===499){

define option could be initiated in webpack or esbuild config file with any computed values (even with required json files) so you have no limit in count of compile-time definitions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM