vite 打包后私有变量无法赋值?

版本

  • vite ^5.2.8
  • vue ^3.4.21

源码:

export default class MessageChain {
  #debug = false;
  constructor(options = {}) {
    this.#debug = options.debug; // 出错代码
  }
}

编译后

var ye;
class MessageChain {
    constructor(r={}) {
        ge(this, ye, r.debug) // 出错代码
    }
}

var ce = (a,r,t)=>Le(a, typeof r != "symbol" ? r + "" : r, t)
  , Ce = (a,r,t)=>r.has(a) || De("Cannot " + t);
var ie = (a,r,t)=>(Ce(a, r, "read from private field"),

错误

index-DJLqw9J7.js:264 TypeError: Cannot write to private field
    at De (index-Wsimtzzt.js:1:47)
    at Ce (index-Wsimtzzt.js:1:223)
    at ge (index-Wsimtzzt.js:1:445)
    at new MessageChain (index-Wsimtzzt.js:212:7585)
    at index-Wsimtzzt.js:212:9006

问题

  1. 在开发环境可以正常赋值
  2. 如何正确赋值
  3. 如何让vite编译时保留class的源码
阅读 816
avatarAI BotBETA

问题解答

1. 在开发环境可以正常赋值

在开发环境中,由于Vite通常使用ES模块(ESM)和源代码转换(如Babel插件或Vite内置支持),私有字段(#debug)的访问和修改通常能够正常工作。这是因为开发环境通常不会进行深度代码转换,或者转换时保留了足够的上下文来正确处理私有字段。

2. 如何正确赋值

在你的代码中,你试图在构造函数中通过 this.#debug = options.debug; 来赋值私有字段。这个语法在ES2020及更高版本的JavaScript中是有效的,但在编译后的代码中,如果编译器没有正确处理私有字段,就可能导致问题。

由于你看到的编译后的代码使用了不同的函数(如ge)来尝试访问和修改私有字段,这可能是导致问题的原因。这通常发生在编译器试图优化或转换代码时,但没有正确处理私有字段的特殊情况。

解决方案

  • 确保你的Vite配置和所有相关的插件(如Babel)都支持ES2020及更高版本的JavaScript特性,特别是私有字段。
  • 检查是否有任何Vite插件或Babel插件可能干扰了私有字段的处理。
  • 尝试更新Vite和所有相关依赖到最新版本。

3. 如何让vite编译时保留class的源码

要让Vite在编译时尽可能保留类的源码,你可以考虑以下几个选项:

  • 使用@babel/plugin-transform-classesloose选项:虽然这通常用于旧版JavaScript环境,但你可以检查这个选项是否影响私有字段的处理。不过,通常不建议在需要私有字段的场景下使用loose模式。
  • 关闭不必要的代码转换:检查Vite配置,确保没有不必要的插件或配置选项在编译过程中修改你的类定义。
  • 使用targetmodules选项:在Vite配置中,你可以设置build.targetbuild.lib.esModule等选项来指定输出代码的格式和目标环境。确保这些设置与你的需求相匹配。
  • 查看Vite的issue和文档:查看Vite的GitHub issues和官方文档,看看是否有其他人报告了类似的问题,或者是否有推荐的解决方案。

注意:由于Vite和Babel等工具的版本不断更新,具体的解决方案可能会随着新版本的发布而变化。因此,始终建议查阅最新的文档和社区讨论。

1 个回答

你是说编译后的代码在构建函数里也不能给私有变量赋值?那不对呀,那是 bug 了。

不然的话,贴一下你修改私有变量的代码吧。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏