Chrome扩展Manifest V3下不使用new Function渲染模板字面量的轻量化方案
解决Manifest V3禁用unsafe-eval后的模板渲染最小改动方案
针对Manifest V3升级后无法使用new Function渲染模板的问题,这里提供一个几乎不需要改动现有模板和调用逻辑的替代方案——通过正则匹配并替换模板中的${data.xxx}占位符,完全规避unsafe-eval限制。
替换后的renderTemplate实现
function renderTemplate(expression, data) { // 匹配所有 ${data.xxx.yyy} 格式的占位符 return expression.replace(/\$\{data\.([\w.]+)\}/g, (match, propPath) => { // 将属性路径拆分为数组,比如 "user.name" → ["user", "name"] const props = propPath.split('.'); // 从data对象中逐层获取属性值 let value = data; for (const prop of props) { value = value?.[prop]; // 如果某个属性不存在,返回空字符串或自定义默认值 if (value === undefined) return ''; } return value; }); } // 原有的JSON模板和调用代码完全不需要改动 const json = { "test":"Hi I'm ${data.name}. It's ${data.time} and I'm almost ${data.age} years old." }; const renderedTemplate = renderTemplate(json.test, { name: "Patrick", age: 30, time: "3pm" }); console.log(renderedTemplate); // Hi I'm Patrick. It's 3pm and I'm almost 30 years old.
方案说明
- 零模板改动:你的JSON模板完全保持原有
${data.xxx}格式,无需调整。 - 调用逻辑不变:
renderTemplate函数的入参和调用方式和之前完全一致,原有业务代码无需修改。 - 支持嵌套属性:如果模板中有
${data.user.address.city}这类嵌套属性,该方案也能正确解析。 - 安全合规:完全不依赖
eval/new Function,符合Manifest V3的内容安全策略。
注意事项
如果模板中包含复杂表达式(比如${data.age + 1}、${data.isAdult ? 'yes' : 'no'}),上述基础版本无法处理。这种情况下,可以扩展正则替换逻辑支持简单运算,或者封装沙箱页面的同步调用层,但如果大部分模板都是纯属性访问,基础版本已经足够满足需求。
内容的提问来源于stack exchange,提问作者Patrick Matte
相关产品推荐
相关产品推荐

