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

在JSX文件中使用Benchmark.js抛出‘关键依赖:依赖请求为表达式’错误

React中使用Benchmark.js的依赖警告及基准测试展示解决方案

需求

我想获取不同循环的基准测试结果并在页面展示,当前代码如下:

import Benchmark from 'benchmark';
import React, { useState } from 'react';
import Navigation from '../Navigation/Navigation';

const Array = () => {
  const suite = new Benchmark.Suite();
  const values = [];

  var sum = 0;
  const initialElement = '';
  const [inputArrayElement, setInputArrayElement] = useState([]);
  const [enteredElement, setEnteredElement] = useState(initialElement);
  const handleSubmit = (e) => {
    e.preventDefault();
    setInputArrayElement((prev) => [...prev, enteredElement]);
    setEnteredElement(initialElement);
  };

  const findElement = (inputArrayElement, n) => {
    ...logic...
  };

  suite
    .add('Array.prototype.some', () => {
      const processed = values.some((value) => value > 0);
    })
    .on('cycle', (event) => {
      console.log(event.target.toString());
      console.log(event.target.name);
      console.log(event.target.stats.rme);
      console.log(event.target.stats.sample.length);
      console.log(event.target.count); // The number of times a test was executed.
      console.log(event.target.cycles); // The number of cycles performed while benchmarking.
      console.log(event.target.hz);
    })
    .run();
  return (
    <div>
      <Navigation />
        <div className="row">
          <div className="col-sm border rounded  my-3 py-4 shadow p-3 mb-3 bg-light rounded">
            BenchMark
            {...function call...}
          </div>
        </div>
  );
};

export default Array;

错误信息

WARNING in ./node_modules/benchmark/benchmark.js 649:36-51
Critical dependency: the request of a dependency is an expression

问题分析与解决方案

1. 解决Webpack依赖警告

Benchmark.js内部存在动态require语句,Webpack无法静态解析,因此抛出警告。可以通过以下两种方式解决:

方式一:定义浏览器环境变量

在webpack.config.js中添加DefinePlugin,告知Benchmark当前运行在浏览器环境,避免加载不必要的依赖:

const webpack = require('webpack');

module.exports = {
  // 其他配置项
  plugins: [
    new webpack.DefinePlugin({
      'process.env.BROWSER': JSON.stringify(true)
    })
  ]
};

方式二:忽略Benchmark的解析

如果上述方法无效,让Webpack跳过解析Benchmark.js文件:

module.exports = {
  // 其他配置项
  module: {
    noParse: /benchmark\.js$/
  }
};

2. 修复React组件逻辑问题

原代码存在几个影响功能的问题,以下是优化后的完整代码:

import Benchmark from 'benchmark';
import React, { useState, useEffect, useRef } from 'react';
import Navigation from '../Navigation/Navigation';

// 避免使用Array作为组件名,与原生构造函数冲突
const ArrayBenchmark = () => {
  const [inputArrayElement, setInputArrayElement] = useState([]);
  const [enteredElement, setEnteredElement] = useState('');
  // 存储基准测试结果用于页面展示
  const [benchmarkResults, setBenchmarkResults] = useState([]);
  const suiteRef = useRef(null); // 保存测试套件实例,避免重复创建

  const handleSubmit = (e) => {
    e.preventDefault();
    setInputArrayElement(prev => [...prev, enteredElement]);
    setEnteredElement('');
  };

  const findElement = (inputArrayElement, n) => {
    // 你的元素查找逻辑
  };

  // 仅在组件挂载或输入数组变化时运行基准测试
  useEffect(() => {
    const suite = new Benchmark.Suite();
    suiteRef.current = suite;

    // 使用用户输入的数组或默认示例数据
    const testValues = inputArrayElement.length > 0 
      ? inputArrayElement.map(Number) // 转换为数字类型(根据需求调整)
      : [1, -2, 3, -4, 5];

    // 添加测试项,可扩展更多循环类型
    suite
      .add('Array.prototype.some', () => {
        testValues.some(value => value > 0);
      })
      .add('普通for循环', () => {
        let hasPositive = false;
        for (let i = 0; i < testValues.length; i++) {
          if (testValues[i] > 0) {
            hasPositive = true;
            break;
          }
        }
      })
      .add('forEach循环', () => {
        let hasPositive = false;
        testValues.forEach(value => {
          if (value > 0) hasPositive = true;
        });
      })
      // 捕获每个测试项的结果
      .on('cycle', (event) => {
        const result = {
          name: event.target.name,
          hz: event.target.hz,
          rme: event.target.stats.rme,
          count: event.target.count,
          cycles: event.target.cycles
        };
        setBenchmarkResults(prev => [...prev, result]);
      })
      .on('complete', () => {
        console.log('所有基准测试完成');
      })
      // 异步运行测试,避免阻塞UI
      .run({ async: true });

    // 组件卸载时停止测试
    return () => {
      if (suiteRef.current) {
        suiteRef.current.abort();
      }
    };
  }, [inputArrayElement]);

  return (
    <div>
      <Navigation />
      <div className="row">
        <div className="col-sm border rounded my-3 py-4 shadow p-3 mb-3 bg-light rounded">
          <h3>循环性能基准测试</h3>
          {/* 数组元素输入表单 */}
          <form onSubmit={handleSubmit} className="mb-4">
            <input
              type="text"
              value={enteredElement}
              onChange={(e) => setEnteredElement(e.target.value)}
              placeholder="输入数字元素"
              className="mr-2"
            />
            <button type="submit" className="btn btn-primary">添加元素</button>
          </form>
          {/* 展示测试结果 */}
          <div className="benchmark-results">
            {benchmarkResults.length > 0 ? (
              benchmarkResults.map((result, index) => (
                <div key={index} className="result-item mb-3 p-2 border rounded">
                  <h4>{result.name}</h4>
                  <p>每秒操作数: <strong>{result.hz.toFixed(2)} ops/sec</strong></p>
                  <p>相对误差: ±{result.rme.toFixed(2)}%</p>
                  <p>测试执行次数: {result.count}</p>
                  <p>循环次数: {result.cycles}</p>
                </div>
              ))
            ) : (
              <p>正在运行基准测试...</p>
            )}
          </div>
        </div>
      </div>
    </div>
  );
};

export default ArrayBenchmark;

优化点说明

  • 组件名改为ArrayBenchmark,避免与原生Array冲突
  • 使用useEffect控制基准测试的执行时机,仅在必要时运行
  • 添加benchmarkResults状态存储测试结果,实现页面展示
  • 使用useRef保存测试套件实例,方便组件卸载时清理
  • 异步运行测试,避免阻塞UI线程
  • 支持用户输入数组元素,动态更新测试数据

内容的提问来源于stack exchange,提问作者Bhavesh Kumar Sharma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 15:50:22