如何在使用 Rollup 转译 TypeScript 代码之前替换代码。 (如何将带有私有类字段的 TypeScript 代码转译为 ES5。)

问题描述 投票:0回答:1

我不会做

我想将带有私有类字段的 TypeScript 代码转换为 ES5,就像使用 TypeScript 的私有标识符一样。

(我放弃一个或另一个,很快就会解决。但我不想放弃。)

我做到了

我尝试在使用 Rollup 转译 TypeScript 代码之前替换代码。

// ./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'}})
  ]
}

结果

使用

WeakMap
的 JavaScript 代码被输出。好像没有被替换。

' private _'
更改为
' _'
,结果相同。

如何解决我想要的问题?

注意

在JavaScript文件中,输出预期的结果。

所以我认为 Rollup 替换插件部分没有任何问题。

// 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
  }
}
javascript typescript ecmascript-5 rollupjs
1个回答
0
投票

我做到了!?

出现警告...,输出预期结果。

变压器

// 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
          }
        ]
      }
    })
  ]
}

// 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
        ]
      }
    })
  ]
}

参考文献

© www.soinside.com 2019 - 2024. All rights reserved.