在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
相关产品推荐
相关产品推荐

