Skip to content

Instantly share code, notes, and snippets.

@renoirb
Last active April 30, 2021 21:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save renoirb/86464e3816df6eb13db0fedec0afdbfd to your computer and use it in GitHub Desktop.
Save renoirb/86464e3816df6eb13db0fedec0afdbfd to your computer and use it in GitHub Desktop.
WeakMap and Class private fields transpiled for different runtimes
node_modules/
dist/
package-lock.json

ECMAScript class #private properties and WeakMap

#something is ECMAScript's way of making a property private natively. It's supported since TypeScript 3.8. TypeScript normally add in its releases what's been Stage 3

See more published in 2019-07 by Axel Raushmayer's blog private class fields and in Impatient JS, section 29.3Private data for classes

Example

Compiled into ECMAScript 2015

This Gist shows different build outputs of the following.

export interface LivingBeing {
  age: number
}

/**
 * The purpose of this example
 */
export class Person implements LivingBeing {
    #age = 0;
    constructor(public name: string) {}
    get age(): number {
        return this.#age;
    }
}

In modern runtime, this would be compiled into ECMAScript 2015 as

function __classPrivateFieldGet(receiver, state, kind, f) {
  // ...
}

var _age;

/**
 * The purpose of this example
 */
class Person {
  constructor(name) {
    this.name = name;

    _age.set(this, 0);
  }

  get age() {
    return __classPrivateFieldGet(this, _age);
  }

}
_age = new WeakMap();

In an older runtime, this would become about 2000 lines of code though.

import useBili from '@renoirb/conventions-use-bili'
/**
* The bundling utility, it's a wrapper around
* Rollup and egoist/bili
*/
export default useBili(
{
input: 'main.ts',
bundleNodeModules: true /* So it's possible to inline dependencies */,
externals: [],
output: {
minify: false,
},
},
{
firstYear: 2003,
},
{
withCore: true,
},
)
export interface LivingBeing {
age: number
}
/**
* The purpose of this example
*/
export class Person implements LivingBeing {
#age = 0;
constructor(public name: string) {}
get age(): number {
return this.#age;
}
}
{
"name": "gist-example-private-fields",
"version": "0.1.0",
"description": "An illustration of how hash prefixed attributes gets transpiled",
"keywords": [],
"license": "UNLICENSED",
"author": {
"name": "Renoir Boulanger",
"email": "contribs@renoirboulanger.com"
},
"exports": {
"browser": "./dist/index-browser.js",
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
},
"main": "dist/index.cjs",
"browser": {
"./dist/ie6to8.js": "./dist/ie6to8.umd.js",
"./dist/index.js": "./dist/index-browser.js"
},
"typings": "dist/index.d.ts",
"files": [
"dist"
],
"scripts": {
"build": "use-run-all clean build:*",
"build:browser": "use-cross-env use-bili --config bili.config.ts --target browser --format iife --module-name Person --file-name index-browser.js",
"build:ie6to8": "use-cross-env BROWSERSLIST='ie 6-8' use-bili --config bili.config.ts --target browser --format umd --module-name latency --file-name ie6to8.umd.js",
"build:ie6to8cjs": "use-cross-env BROWSERSLIST='ie 6-8' use-bili --target browser --format cjs --module-name latency --file-name ie6to8.cjs",
"build:main": "use-cross-env BROWSERSLIST='> 0.5%' use-bili --target browser --format cjs --file-name index.cjs",
"build:modern": "use-cross-env BROWSERSLIST='maintained node versions' use-bili --target node --format esm --file-name index.mjs",
"clean": "use-rimraf .rpt2_cache dist *.*.log"
},
"devDependencies": {
"@babel/core": "^7.14.0",
"@babel/plugin-transform-runtime": "^7.13.0",
"@babel/preset-env": "^7.14.0",
"@babel/preset-typescript": "^7.13.0",
"@babel/runtime-corejs3": "^7.14.0",
"@renoirb/conventions-use-bili": "^1.3.0",
"@renoirb/conventions-use-eslint": "^1.2.0",
"@renoirb/conventions-use-typescript-3": "^1.2.0",
"@renoirb/tools-bundling-helpers": "^1.2.0",
"@types/node": "^14.0.0",
"core-js": "^3.11.0",
"tslib": "^2.0.0",
"typescript": "4.2.4"
}
}
{
"extends": "./node_modules/@renoirb/conventions-use-typescript-3/includes/tsconfig.json",
"compilerOptions": {
"baseUrl": ".",
"importHelpers": true,
"lib": ["dom", "es2015"],
"target": "es2015"
},
"include": ["src"],
"exclude": ["src/__tests__"]
}
@renoirb
Copy link
Author

renoirb commented Apr 30, 2021

Screen Shot 2021-04-30 at 17 08 51
Screen Shot 2021-04-30 at 17 09 23
Screen Shot 2021-04-30 at 17 10 21
Screen Shot 2021-04-30 at 17 11 24

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment