我想将带有私有类字段的 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
}
}
出现警告...,输出预期结果。
// 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.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
]
}
})
]
}