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

Node/Puppeteer/ChromeDevTools疑难:变量属性明明已定义,Shell却提示未定义?原因解析

Fixing the "Cannot read property 'length' of undefined" Error in Your Puppeteer Coverage Script

Hey there, I see exactly where things are going wrong here—let's walk through the issues and get your script working properly.

The Root Cause: Misusing for...in Loops

The error you're hitting comes down to using for...in to iterate over arrays. for...in is designed to loop through object keys, not array elements. When you use it on an array, you're getting the string indices (like "0", "1") instead of the actual coverage entry objects. That's why entry.text is undefined—you're trying to access a property on a string, not the coverage object!

On top of that, there are a few other small bugs in your script that we'll fix along the way:

  • You're only iterating over the first entry in your coverage arrays instead of all entries
  • A typo in the JS section: you named your collected JS variable js_css but tried to write covered_js to file
  • Same for...in mistake when looping through the ranges array of each entry

Corrected Script

Here's the fixed version with comments pointing out the key changes:

const puppeteer = require('puppeteer');
const fs = require('fs');
const iPhone = puppeteer.devices['iPhone 6'];

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.emulate(iPhone);

  // Start coverage collection
  await Promise.all([
    page.coverage.startCSSCoverage(),
    page.coverage.startJSCoverage()
  ]);

  await page.goto('http://127.0.0.1:5500/index.html');

  // Stop coverage collection
  const [cssCoverage, jsCoverage] = await Promise.all([
    page.coverage.stopCSSCoverage(),
    page.coverage.stopJSCoverage()
  ]);

  // Process CSS Coverage
  let cssUsedBytes = 0;
  let cssTotalBytes = 0;
  let coveredCss = "";

  // Use for...of to iterate over coverage entries (arrays, not objects)
  for (const entry of cssCoverage) {
    cssTotalBytes += entry.text.length;
    console.log(`Total Bytes for ${entry.url}: ${entry.text.length}`);
    
    // Same fix for ranges array
    for (const range of entry.ranges) {
      cssUsedBytes += range.end - range.start;
      coveredCss += entry.text.slice(range.start, range.end) + "\n";
    }
  }

  // Process JS Coverage
  let jsUsedBytes = 0;
  let jsTotalBytes = 0;
  let coveredJs = ""; // Fixed variable name from js_css to coveredJs

  // Again, for...of for array iteration
  for (const entry of jsCoverage) {
    jsTotalBytes += entry.text.length;
    console.log(`Total Bytes for ${entry.url}: ${entry.text.length}`);
    
    for (const range of entry.ranges) {
      jsUsedBytes += range.end - range.start;
      coveredJs += entry.text.slice(range.start, range.end) + "\n";
    }
  }

  // Log stats
  console.log(`Total Bytes of CSS: ${cssTotalBytes}`);
  console.log(`Used Bytes of CSS: ${cssUsedBytes}`);
  console.log(`Total Bytes of JS: ${jsTotalBytes}`);
  console.log(`Used Bytes of JS: ${jsUsedBytes}`);

  // Save CSS file
  fs.writeFile("./exported_css.css", coveredCss, function(err) {
    if(err) {
      return console.log(err);
    }
    console.log("The CSS file was saved!");
  });

  // Save JS file (now using the correct variable name)
  fs.writeFile("./exported_js.js", coveredJs, function(err) {
    if(err) {
      return console.log(err);
    }
    console.log("The JS file was saved!");
  });

  await browser.close();
})();

Key Changes Explained

  • Swapped all for...in loops to for...of when iterating over arrays (cssCoverage, jsCoverage, and each entry's ranges array)
  • Removed unnecessary array spreading (you can use the original coverage arrays directly)
  • Fixed the variable name typo in the JS section (js_css → coveredJs)
  • Adjusted the byte calculation to range.end - range.start (your original -1 was likely a mistake, since slice is end-exclusive)

This should resolve the "Cannot read property 'length' of undefined" error and correctly extract the used CSS/JS into separate files.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 12:03:13