0

I wont to do

I want to transpile TypeScript code with Private Class Fields to ES5 like when using TypeScript's private identifier.

(I give up one or the other, it will be resolved soon. But I don't want to give up.)

I did

I tried to replace code before transpiling TypeScript code using Rollup.

// ./src/index.mts
export class Foo {
  #foo = 0
  #bar = 'a'
  get foo() {
    return this.#foo
  }
  set foo(value) {
    this.#foo = value
  }
  get bar() {
    return this.#bar
  }
  set bar(value) {
    this.#bar = value
  }
}
// rollup.config.mjs
import replace from '@rollup/plugin-replace'
import typescript from '@rollup/plugin-typescript'
export default {
  input: './src/index.mts',
  output: {
    file: './dist/index.js',
    format: 'iife'
  },
  plugins: [
    replace({ // Assumption that ' #' and '.#' are not used in strings, regular expressions, etc.
      ' #': ' private _',
      '.#': '._',
      delimiters: ['', '']
    }),
    typescript({compilerOptions: {target: 'es5'}})
  ]
}

result

JavaScript code using WeakMap is output. Not appear to be replaced.

Changing from ' private _' to ' _', same result.

How can I solve what I want?

note

In JavaScript file, expected result is output.

So I see nothing wrong with Rollup replace plugin part.

// rollup.config.mjs
import replace from '@rollup/plugin-replace'
export default {
  input: './src/index.mjs',
  output: {
    file: './dist/index.js',
    format: 'iife'
  },
  plugins: [
    replace({ // Assumption that ' #' and '.#' are not used in strings, regular expressions, etc.
      ' #': ' _',
      '.#': '._',
      delimiters: ['', '']
    })
  ]
}
// ./src/index.mjs (same as ./src/index.mts)
export class Foo {
  #foo = 0
  #bar = 'a'
  get foo() {
    return this.#foo
  }
  set foo(value) {
    this.#foo = value
  }
  get bar() {
    return this.#bar
  }
  set bar(value) {
    this.#bar = value
  }
}

1 Answer 1

0

I did it!?

Warnings occurred..., expected results were output.

transformer

// transformer.mjs

import * as ts from 'typescript'

const updatePrivatePropertyDeclaration = (factory, node) => factory.updatePropertyDeclaration(
  node,
  (node.modifiers || []).concat(factory.createToken(ts.SyntaxKind.PrivateKeyword)),
  factory.createIdentifier(node.name.getFullText().replace(/^#/, '_')),
  undefined,
  undefined,
  undefined
)

const updatePrivatePropertyAccessExpression = (factory, node) => factory.updatePropertyAccessExpression(
  node,
  node.expression,
  factory.createIdentifier(node.name.getFullText().replace(/^#/, '_'))
)

const isPropertyDeclaration = node => node.kind === ts.SyntaxKind.PropertyDeclaration

const isPropertyAccessExpression = node=> node.kind === ts.SyntaxKind.PropertyAccessExpression

export const transform = context => sourceFile => {
  const visitor = node => (
    isPropertyDeclaration(node) && node.name.kind === ts.SyntaxKind.PrivateIdentifier ?
    updatePrivatePropertyDeclaration(context.factory, node) :
    isPropertyAccessExpression(node) && node.name.kind === ts.SyntaxKind.PrivateIdentifier ?
    updatePrivatePropertyAccessExpression(context.factory, node) :
    ts.visitEachChild(node, visitor, context)
  )
  return ts.visitNode(sourceFile, visitor)
}

export default program => transform

rollup.config

// rollup.config.mjs

import typescript from '@rollup/plugin-typescript'

import transformer from './transformer.mjs'

export default {
  input: './src/index.mts',
  output: {
    file: './dist/index.js',
    format: 'iife'
  },
  plugins: [
    typescript({
      compilerOptions: {target: 'es5'},
      transformers: {
        before: [
          {
            type: 'program',
            factory: transformer
          }
        ]
      }
    })
  ]
}

or

// rollup.config.mjs

import typescript from '@rollup/plugin-typescript'

import {transform} from './transformer.mjs'

export default {
  input: './src/index.mts',
  output: {
    file: './dist/index.js',
    format: 'iife'
  },
  plugins: [
    typescript({
      compilerOptions: {target: 'es5'},
      transformers: {
        before: [
          transform
        ]
      }
    })
  ]
}

References

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.