You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

webpack压缩后使用eval执行动态数学公式报错问题咨询

问题根因
  • webpack打包默认开启严格模式,严格模式下eval内部的var声明仅在eval自身的执行上下文内有效,不会提升到外层函数作用域,所以你在eval里声明的A、B等变量,外层代码无法访问。
  • webpack压缩混淆时会把模块内导入的局部变量名(比如你引入的angle/intersect等工具函数)替换为短字符名,但eval里的公式字符串是静态内容,不会跟着同步替换,导致执行时找不到对应函数。
最优解决方案

不要直接使用eval,改为通过new Function构造动态计算函数,显式传入所有公式依赖的上下文,完全避开压缩和作用域问题,实现代码如下:

import {intersect, distance, angle, dist} from './utils'

// 配置公式用到的所有工具函数映射,键名必须和公式内写的函数名完全一致
const formulaMethods = {
  intersect,
  distance,
  angle,
  dist
}

function analysis() {
  const data = require('./config/analyses.json')

  const instance = {
    available_analyses: function() {
      return Object.keys(data);
    },

    run_analysis: function(name, points) {
      const analysis = data[name]
      const equations = analysis['equations']
      const results = []

      // 拼接执行上下文的键和值
      const execKeys = [...Object.keys(formulaMethods), ...Object.keys(points)]
      const execValues = [...Object.values(formulaMethods), ...Object.values(points)]

      for (const equation of equations) {
        const formula = equation.formula
        // 构造动态计算函数,参数名和公式内的变量/函数名完全匹配
        const calcFn = new Function(...execKeys, `return ${formula}`)
        results.push({
          name: formula,
          value: calcFn(...execValues)
        })
      }
      return results;
    }
  }
  return instance;
}

该方案的优势:

  • 不受webpack压缩混淆、严格模式的影响
  • 不会污染全局作用域
  • 执行上下文可控,安全性比直接eval更高
备选兼容方案(不推荐)

如果一定要沿用eval的写法,可以把所有依赖的函数和变量挂载到全局对象上,示例:

// 初始化时把工具函数挂载到全局window
import {intersect, distance, angle, dist} from './utils'
window.intersect = intersect
window.distance = distance
window.angle = angle
window.dist = dist

// run_analysis内生成点变量时也挂载到全局
for (const [key, value] of Object.entries(points)) {
  eval(`window.${key} = [${value}];`);
}

该方案的缺陷是会污染全局变量,可能和页面其他脚本产生命名冲突。


内容的提问来源于stack exchange,提问作者jtomasrl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 18:30:04