Rollup 构建后报 Cannot convert a Symbol value to a string
Rollup 4.64.0/4.64.1 会误剪 core-js-pure 的 Symbol 探测,强制进入不适合原生 Symbol 的路径。采用含正式修正的版本,核对锁文件与真实运行产物。
Rollup 更新到 4.64.0 或 4.64.1 后,构建顺利完成,应用一启动却报 TypeError: Cannot convert a Symbol value to a string。如果堆栈经过 core-js-pure 的 toPropertyKey、defineProperty,检查打包结果中的原生 Symbol 功能探测,不要先把业务里的 Symbol 键全改成字符串。
这两个版本存在一条 tree-shaking 回归:core-js 的探测辅助函数被错误地静态推断,原本按环境决定是否启用的 Symbol polyfill 变成了强制分支。即使当前引擎支持原生 Symbol,内部属性键转换也可能走到错误实现。
打包前的代码不一定有非法字符串转换
下面是用于保留相关依赖路径的入口示例,项目需已有 core-js-pure;这里没有让业务代码执行 Symbol() + '':
import SymbolPolyfill from 'core-js-pure/stable/symbol'
import defineProperty from 'core-js-pure/stable/object/define-property'
const key = Symbol('check')
const target = {}
defineProperty(target, key, { value: 1 })
console.log(typeof SymbolPolyfill, target[key])
当构建包含 @rollup/plugin-commonjs 和 node-resolve 时,先核对实际解析的 Rollup、插件及 core-js-pure 版本。4.64.0/4.64.1 与 core-js-pure 3.50.0、3.49.0 的相关组合有具体故障条件;不能把任何 Symbol 转换异常都归到这里。
比较产物时,关注 Symbol 功能探测是否还参与分支选择,是否出现了不符合运行环境的 forced: true、sham: true,以及 toPropertyKey 是否错误地尝试把原生 Symbol 拼接为字符串。压缩可能改掉变量名,不能只靠搜索某个源码函数名判断。
4.64.2 已有正式修正
Rollup 4.64.2 的正式发行记录已包含 core-js 辅助函数误剪修复。它重新处理了“所有返回路径都返回同一个、但又会被赋值的变量”的返回值分析,避免把初始化值当作唯一结果;当前 4.65.0 也保留相关实现。
在上层构建工具允许的范围内选择包含修正的正式版本,更新锁文件并从真实构建环境确认解析结果。若由 Vite 等工具间接带入 Rollup,按那套工具链支持的方式调整,不要只在根目录额外安装一份新 Rollup,就假定原构建已换版本。
暂时无法使用修复版时,可以评估将受影响的 Rollup 路径回退到此前已验证的 4.63.6。回退也会撤掉其他修改,应保留原锁文件与产物,并确认平台包和插件仍兼容;它是有条件的过渡选择,不是要求所有项目长期固定旧版。
不要通过全局关闭 tree-shaking、删掉 core-js 或把所有属性键转成字符串来代替修正。前两种改动会改变体积与兼容行为,最后一种则直接改变业务数据的键语义。
用部署产物检查 Symbol 键访问
重新构建后,在实际支持的运行环境中检查原来触发异常的入口。上面的示例应能完成属性定义,并通过同一个 Symbol 键读到值。
还要核对原应用的异步启动、依赖 polyfill 的组件和正常属性读写。构建成功本来就是故障的一部分,不能再把它当作恢复证明。部署与回退都应使用相容的整套依赖和产物,避免旧 bundle 仍被缓存或重新上线。


