ChatGPT解决这个技术问题 Extra ChatGPT

Chrome Devtools Coverage:如何保存或捕获代码使用的代码?

Coverage 工具擅长查找已使用和未使用的代码。但是,似乎没有办法只保存或导出使用过的代码。即使隐藏未使用的代码也会有所帮助。

我正在尝试减少应用程序中 Bootstrap CSS 的数量;该文件超过7000行。获取使用过的代码的唯一方法是仔细滚动文件,寻找绿色部分,然后将该代码复制到一个新文件中。这是耗时且不可靠的。

有不同的方法吗? Chrome 60 似乎没有添加这个功能。

关于有没有更好的选择。此 mdn page on css coverage警告 This feature is experimental and is not yet available in Firefox. 在 Firefox ESR 45.8.0 中,可以通过按 SHIFT F2 打开 GCLI Graphical Command Line Interpreter Christian Heilmann 上传 video CSSCoverage tool in Firefox Devtools
我打赌你可以写一个 chrome 扩展来导出数据
好问题,同样的问题
不幸的是,@surfmuggle 提到的功能现在已经消失了——support.mozilla.org/en-US/questions/1248832

C
Chuck Le Butt

你可以用 puppeteer 做到这一点

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

  //Start sending raw DevTools Protocol commands are sent using `client.send()`
  //First off enable the necessary "Domains" for the DevTools commands we care about
  const client = await page.target().createCDPSession()
  await client.send('Page.enable')
  await client.send('DOM.enable')
  await client.send('CSS.enable')

  const inlineStylesheetIndex = new Set();
  client.on('CSS.styleSheetAdded', stylesheet => {
    const { header } = stylesheet
    if (header.isInline || header.sourceURL === '' || header.sourceURL.startsWith('blob:')) {
      inlineStylesheetIndex.add(header.styleSheetId);
    }
  });

  //Start tracking CSS coverage
  await client.send('CSS.startRuleUsageTracking')

  await page.goto(`http://localhost`)
  // const content = await page.content();
  // console.log(content);

  const rules = await client.send('CSS.takeCoverageDelta')
  const usedRules = rules.coverage.filter(rule => {
    return rule.used
  })

  const slices = [];
  for (const usedRule of usedRules) {
    // console.log(usedRule.styleSheetId)
    if (inlineStylesheetIndex.has(usedRule.styleSheetId)) {
      continue;
    }

    const stylesheet = await client.send('CSS.getStyleSheetText', {
      styleSheetId: usedRule.styleSheetId
    });

    slices.push(stylesheet.text.slice(usedRule.startOffset, usedRule.endOffset));
  }

  console.log(slices.join(''));

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

您使用哪个版本的 node 来运行您的解决方案?
@dryleaf nodejs 8.6
谢谢。看到 puppeteer 文档后,我能够在 8.0.0 上运行。这是一个不错的 CSS hack。 +1 给出了很好的答案。我将如何进行 JS hack?
我想我们也可以 filter 并获取未使用的规则,将它们分开并将未使用的规则加载为延迟样式。也许它们被用于其他内部页面。
如果我只想专注于 bootstrap.css 并让所有其他人保持原样怎么办?我需要如何更改上面的编码?
C
Chuck Le Butt

您可以使用 Headless Chrome 和 puppeteer 执行此操作:

在一个新文件夹中使用 npm 安装 puppeteer(这将包括 Headless Chrome):

npm i puppeteer --save

将以下内容放入名为 csscoverage.js 的文件中,并将 localhost 更改为指向您的网站。

const puppeteer = require('puppeteer');
const util = require('util');
const fs    = require("fs");

(async () => {
 const browser = await puppeteer.launch();
 const page = await browser.newPage();
 await page.coverage.startCSSCoverage();
 await page.goto('https://localhost'); // Change this
 const css_coverage = await page.coverage.stopCSSCoverage();
 console.log(util.inspect(css_coverage, { showHidden: false, depth: null }));
 await browser.close();

let final_css_bytes = '';
let total_bytes = 0;
let used_bytes = 0;

for (const entry of css_coverage) {
  final_css_bytes = "";

  total_bytes += entry.text.length;
  for (const range of entry.ranges) {
    used_bytes += range.end - range.start - 1;
    final_css_bytes += entry.text.slice(range.start, range.end) + '\n';
  }

  filename = entry.url.split('/').pop();

  fs.writeFile('./'+filename, final_css_bytes, error => {
    if (error) {
      console.log('Error creating file:', error);
    } else {
      console.log('File saved');
    }
  });
}
})();

使用节点 csscoverage.js 运行它

这会将您正在使用的所有 CSS 输出到它们出现的单独文件中(阻止您将外部库合并到您自己的代码中,就像其他答案一样)。


添加 await page.setDefaultNavigationTimeout(0);避免在运行重负载或加载较难的页面时超时
这只是提取移动 css。不知何故,更大的屏幕 css 没有被提取。知道如何解决这个问题吗?
K
Kayce Basques

我与拥有此功能的工程师进行了交谈。从 Chrome 64 开始,仍然无法导出覆盖率分析的结果。

issue #717195 以帮助团队优先考虑此功能请求。


t
tmighty

我喜欢这个简单的解决方案。它可以与 Chrome 中的 Coverage 工具一起使用,无需任何进一步的安装。您可以简单地使用 Coverage 工具允许您导出的 json 文件:

https://nachovz.github.io/devtools-coverage-css-generator/

但请注意我的答案下方的评论!!!他是对的,这是有风险的。我仍然希望/等待更新。


它不需要像 @media (min-width: 768px) 这样的 css 行,所以风险很大
r
reza jafari

首先,您需要下载并安装“Google Chrome Dev”。在 Google chrome Dev 上转到 Inspect element > Sources > Ctrl+shift+p 输入“coverage”并选择“Start Instrumenting coverage and reload Page” 然后使用 Export 图标,这将为您提供一个 json 文件。

您还可以访问:Chrome DevTools: Export your raw Code Coverage Data


如果您只需要从 json 中获取文件的覆盖文本,则可以使用以下 js 代码:var file = json[N]; var coverage_file = ""; file.ranges.forEach(range => coverage_file += file.text.substring(range.start, range.end));。其中 N 是 json 中的文件数
“下载并安装”Google Chrome Dev“是什么意思?F12 还不够?
谷歌浏览器开发!=谷歌浏览器。我认为下载覆盖文本仅在 Google Chrome Dev 上可用。 Google chrome Dev 是为开发人员构建的 chrome 版本。
不确定何时添加,但当我输入此选项时,此选项位于 Chrome 的最新(mac)版本中 - 版本 89.0.4389.90(官方构建)(x86_64)
a
atoms

我下载了最新版本的金丝雀,并且出现了导出按钮。

然后我使用这个 PHP 脚本来解析返回的 json 文件。 (其中数组中的键 '6' 是要解析的资源)。我希望它可以帮助某人!

$a = json_decode(file_get_contents('coverage3.json'));
$sText = $a[6]->text;
$sOut = "";
foreach ($a[6]->ranges as $iPos => $oR) {
    $sOut .= substr($sText, $oR->start, ($oR->end-$oR->start))." \n";
}
echo '<style rel="stylesheet" type="text/css">' . $sOut . '</style>';

非常感谢这个!但是你有一个小错误(或者可能当时生成的coverage.json不同),substr的第三个参数应该是长度,但是在coverage.json中出现了结束字符,所以它应该是:$ sOut .= substr($sText, $oR->start, ($oR->end-$oR->start));
此外,您可能希望使用 mb_substr() 而不是 substr() 来解释多字节字符(有时用于 CSS 中的图标)。
8
8oh8

Chrome canary 73 可以做到。您将需要 Windows 或 Mac OS。记录和清除按钮旁边有一个导出功能(向下箭头图标)。您将获得一个 json 文件,然后您可以使用它以编程方式删除未使用的行。


任何从json中提取的脚本?
P
Phil W.

这是一个保留媒体查询的版本,基于 Christopher Schiefer 的:

$jsont = <<<'EOD'
{ "url":"test"} 
EOD;

$a = json_decode($jsont);
$sText = $a->text;
preg_match_all('(@media(?>[^{]|(?0))*?{)', $sText, $mediaStartsTmp, PREG_OFFSET_CAPTURE);
preg_match_all("/\}(\s|\\n|\\t)*\}/", $sText, $mediaEndsTmp, PREG_OFFSET_CAPTURE);
$mediaStarts = empty($mediaStartsTmp) ? array() : $mediaStartsTmp[0];
$mediaEnds = empty($mediaEndsTmp) ? array() : $mediaEndsTmp[0];
$sOut = "";
$needMediaClose = false;
foreach ($a->ranges as $iPos => $oR) {
    if ($needMediaClose) { //you are in a media query
        //add closing bracket if you were in a media query and are past it
        if ($oR->start > $mediaEnds[0][1]) {
            $sOut .= "}\n";
            array_splice($mediaEnds, 0, 1);
            $needMediaClose = false;
        }
    }
    if (!$needMediaClose) {
        //remove any skipped media queries
        while (!empty($mediaEnds) && $oR->start > $mediaEnds[0][1]) {
            array_splice($mediaStarts, 0, 1);
            array_splice($mediaEnds, 0, 1);
        }
    }
    if (!empty($mediaStarts) && $oR->start > $mediaStarts[0][1]) {
       $sOut .= "\n" . $mediaStarts[0][0] . "\n";
       array_splice($mediaStarts, 0, 1);
       $needMediaClose = true;
    }
    $sOut .= mb_substr($sText, $oR->start, ($oR->end-$oR->start))." \n";
}
if ($needMediaClose) { $sOut .= '}'; }
echo '<style rel="stylesheet" type="text/css">' . $sOut . '</style>';

N
Nathan B

这是我提取代码的python代码:

import json

code_coverage_filename = 'Coverage-20210613T173016.json'
specific_file_url = 'https://localhost:3000/b.css'

with open(code_coverage_filename) as f:
  data = json.load(f)
  
for entry in data:
    pass # print entry['url']
    if entry['url'] == specific_file_url:
        text = ""
        for range in entry['ranges']:
            range_start = range['start']
            range_end = range['end']
            text += entry['text'][int(range_start):int(range_end)]+"\n"
                
        print text

但是,有一个问题。 Chrome 调试器不会标记这些行

@media (min-width: 768px) {

所以使用这种技术有点问题


我可能是错的,但至少在 Chrome 102 看来,它现在确实包含 @media 查询。
C
Christopher Schiefer

基于 Atoms 的更实用的版本。

改进为无需任何文件即可工作。

PHP 沙盒 http://sandbox.onlinephpfunctions.com/

要转换为 1 行 https://www.freeformatter.com/json-formatter.html#ad-output 的 JSON 格式化程序

取消它https://unminify.com/

$jsont = <<<'EOD'
{ "url":"test"} 
EOD;

$a = json_decode($jsont);
$sText = $a->text;
$sOut = "";
foreach ($a->ranges as $iPos => $oR) {
    $sOut .= substr($sText, $oR->start, ($oR->end-$oR->start))." \n";
}
echo '<style rel="stylesheet" type="text/css">' . $sOut . '</style>';

D
Dmitry Drehval

我使用这个 DisCoverage chrome 扩展,它从覆盖工具解析 json 文件