Advertisement
Guest User

Untitled

a guest
Aug 21st, 2019
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.24 KB | None | 0 0
  1. const postcss = require("postcss");
  2.  
  3. // 行番号・列番号をソースコード上の位置(0 〜 ソースコード.length - 1)に変換
  4. const lineColumnToIndex = (coverage, line, column) => {
  5. // 各行の改行文字を含む文字数
  6. const countPerLine = coverage.text.split("\n").map((lineStr, index, lines) =>
  7. // 最終行以外は改行文字分の+1をする
  8. index === lines.length - 1 ? lineStr.length : lineStr.length + 1
  9. );
  10. // 配列の要素を全て足す関数
  11. const sum = arr => arr.reduce((acc, val) => acc + val, 0);
  12.  
  13. // 1~${line - 1}行まで文字数 + column = ソースコード上の位置
  14. return sum(countPerLine.slice(0, line)) + column - 1;
  15. };
  16.  
  17. // ノードが削除対象か判定
  18. const isNodeUnneeded = (node, coverage) => {
  19. // Root, Comment, Declarationは削除しない
  20. if (["root", "comment", "decl"].includes(node.type)) {
  21. return false;
  22. }
  23.  
  24. // @font-faceは削除しない
  25. if (node.type === "atrule" && node.name === "font-face") {
  26. return false;
  27. }
  28.  
  29. // その他:カバレッジが無ければ削除
  30.  
  31. // ノードのソース上での開始・終了位置(行列番号)
  32. const { start, end } = node.source;
  33. // 行列番号を文字列位置(0 ~ ソースコード文字列.length - 1)に変換
  34. const startIndex = lineColumnToIndex(coverage, start.line, start.column);
  35. const endIndex = lineColumnToIndex(coverage, end.line, end.column);
  36.  
  37. // ノードのソースコード上の範囲を含むカバレッジを探す
  38. const covered = coverage.ranges.find(
  39. range => !(startIndex => range.end || endIndex < range.start)
  40. );
  41.  
  42. // カバレッジが見つかれなければ、trueを返す
  43. return typeof covered === "undefined";
  44. };
  45.  
  46. /**
  47. * PuppeteerのCSSカバレッジから不要なスタイルを削除したCSSを生成
  48. *
  49. * @param {Object} coverage - stopCSSCoverageが返す配列の要素
  50. */
  51. const removeUnusedCSS = coverage => {
  52. // CSSからASTを生成
  53. const root = postcss.parse(coverage.text);
  54.  
  55. // ASTの探索
  56. root.walk(node => {
  57. // 削除対象か?
  58. if (isNodeUnneeded(node, coverage)) {
  59. // 削除対象ならASTから削除する
  60. node.remove();
  61. }
  62. });
  63.  
  64. // ASTからCSSを生成
  65. return root.toString();
  66. };
  67.  
  68. module.exports = removeUnusedCSS;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement