Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
PuppeteerでいらないCSSを消す
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Hiroyuki ANAI
June 19, 2019
Programming
29k
23
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
PuppeteerでいらないCSSを消す
@pirosikick の発表資料です。
https://mentaico-js.connpass.com/event/132416/
Hiroyuki ANAI
June 19, 2019
More Decks by Hiroyuki ANAI
See All by Hiroyuki ANAI
書き換えて学ぶTemporal #fukts
pirosikick
2
400
fukuoka.ts #3 社内でESLintの共通設定を配りたい2025年春版
pirosikick
3
470
compilerOptions、全部読んだ
pirosikick
1
290
Step Functionsの設計時に知っておいたほうがいいかもしれないこと
pirosikick
0
520
Go言語による並行処理「4.4 orチャネル」の図
pirosikick
0
470
サイボウズWebフロントエンド脱レガシーの今までとこれから
pirosikick
6
17k
@cybozu/eslint-configから学ぶ、全社共通ESLint configの運用
pirosikick
4
1.9k
Web Share Target API #w3fukuoka
pirosikick
0
730
Google I/O '19のWebをまとめる会
pirosikick
2
890
Other Decks in Programming
See All in Programming
AIとRubyの静的型付け
ukin0k0
0
560
エージェンティックRAGにAWSで入門しよう!
har1101
8
1.4k
TAKTでAI駆動開発の品質を設計する
j5ik2o
6
1.1k
[2026年度第1回ORセミナー] 計画最適化ベンチャーと競技プログラミング人材
terryu16
0
250
並列実装の現場、2ヶ月間実務でAIを使い倒したAIもPCも私も限界が近い
ming_ayami
0
120
Oxlintのカスタムルールの現況
syumai
6
1k
CLIであることを活かしたGitHub Copilot CLI活用術 / GitHub Copilot CLI Pro Tips & Tricks
nao_mk2
1
1.2k
PHPで使える日時の表現と、その知り方 #frontend_phpcon_do
o0h
PRO
0
230
Technical Debt: Understanding it Rightly, Engaging it Rightly #LaravelLiveJP
shogogg
0
210
「エンジニアインターン、どうやって取った?」準備のリアルを語るLT会 Progate BAR
akiomatic
0
130
Spec-Driven Development with AI-Agents: From High-Level Requirements to Working Software
antonarhipov
2
480
AIとASP.NET Coreで雑Webアプリを作った話
mayuki
0
480
Featured
See All Featured
Exploring anti-patterns in Rails
aemeredith
3
400
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.7k
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
5
1.1k
Rails Girls Zürich Keynote
gr2m
96
14k
Principles of Awesome APIs and How to Build Them.
keavy
128
17k
Everyday Curiosity
cassininazir
0
230
WCS-LA-2024
lcolladotor
0
620
Accessibility Awareness
sabderemane
1
130
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
62
44k
Color Theory Basics | Prateek | Gurzu
gurzu
0
360
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.5k
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
720
Transcript
͍Βͳ͍$44Λ 1VQQFUFFSͰফ͢ !QJSPTJLJDL 8FC (PPHMF*0ͷ8FCΛ·ͱΊΔձ
ࣗݾհ w !QJSPTJLJDL w αΠϘζגࣜձࣾ ϑϩϯτΤϯυΤΩεύʔτνʔϜ w طʹ͝ଘͩͱࢥ͍·͕͢ɺ ࡢɺঁ͕࢈·Ε·ͨ͠!
࠷͍ۙͬͯΔࣄ w ڊେͳ$44ͷTUZMFEDPNQPOFOUTԽ w ສߦ͋Δ͕ɺશͯͷελΠϧ͕ඞཁͳΘ͚Ͱͳ͍ w ͦͷଞͷ w NJODTTͱ͍͏֦ுࢠͳͷʹѹॖ͞Ε͍ͯͳ͍ w
CPPUTUSBQGPOUBXFTPNFͷελΠϧΛ্ॻ͖͍ͯ͠Δ w ৄࡉ͕ߴ͗͢ΔελΠϧ͕݁ߏ͋ΔFUD
Ͳ͏ઓ͑Α͍ͷ͔ Θ͔ΒΜ
.PEFSO8FC5FTUJOHBOE"VUPNBUJPOXJUI1VQQFUFFS IUUQTXXXZPVUVCFDPNXBUDI W.CO"5-$V,* 1VQQFUFFSͰ +4ɾ$44ͷΧόϨοδ͕ औΕ·͢
͜ͷػೳΛ͑ ͬͯͳ͍ελΠϧΛ ୳͠ग़ͤΔͷͰʁ
1VQQFUFFSͰ $44ͷΧόϨοδΛऔಘ const puppeteer = require('puppeteer'); (async () => {
// ブラウザの起動 const browser = await puppeteer.launch(); const page = await browser.newPage(); // カバレッジの収集を開始 await page.coverage.startCSSCoverage(); // カバジッジを取りたいページを徘徊 await page.goto(…); … // カバレッジの収集を終了 const cssCoverage = await page.coverage.stopCSSCoverage(); … })();
QVQQFUFFSUPJTUBOCVMͰ OZD͕ॲཧՄೳͳϑΥʔϚοτʹม const pti = require('puppeteer-to-istanbul'); // .nyc_output/*を生成 pti.write(cssCoverage);
)5.-ܗࣜͷϨϙʔτΛੜ w OQYOZDSFQPSUSFQPSUFSIUNM w DPWFSBHFҎԼʹ)5.-Λग़ྗ w PQFODPWFSBHFJOEFYIUNM
εΫγϣషΔ
खಈͰফ͢ͷਏͦ͏ ΧόϨοδ͔ΒࣗಈͰ ফͤͳ͍͔ʁ
OZD@PVUQVUͷத w PVUKTPO w ֤ϑΝΠϧͷΧόϨοδใ w KT DTTKT w $44ϑΝΠϧͦͷͷ
w ֦ுࢠ͕KTʹͳ͍ͬͯΔͷṖ
OZD@PVUQVUPVUKTPOͷ TϑΟʔϧυ͕͑ͦ͏ // .nyc_output/out.jsonの構造 { "ファイルパス": { "path": "ファイルパス", "s":
{ "行数": 0 or 1 // 1の場合、カバレッジ有り … }, … }, … }
ෆཁͳߦΛফ͢ॲཧʢΠϝʔδʣ const fs = require('fs'); const readline = require('readline'); //
out.jsonのsフィールドから不要な行を消す処理のイメージ const removeUnusedLines = (filePath, s) => new Promise(resolve => { const reader = readline.createInterface({ input: fs.createReadStream(filePath) }); let currentLine = 0; const lines = []; // ファイルから1行ずつ読む reader.on('line', line => { // カバレッジがある行を残す if (s[currentLine++]) { lines.push(line); } }); reader.on('close', () => resolve(lines)); });
݁Ռ w ΧόϨοδ͕͔͠ͳ͔ͬͨ w ສߦˠߦ w ·ͩଟ͍͕ΪϦΪϦઓ͑Δߦʹͳͬͨ
ϋϚͬͨͱ͜Ζ
QBHFHPUPͷͨͼʹ ΧόϨοδ͕Ϧηοτ͞ΕΔ w ҎԼͷΑ͏ʹରॲ w HPUPຖʹΧόϨοδΛੜ w QUPJXSJUFҰͭͷΧόϨοδ͔͠ड͚͚ͳ͍ͷͰ w ෳͷΧόϨοδΛϚʔδͯ͠
ҰͭͷΧόϨοδΛੜ
QVQQFUFFS͕ग़ྗ͢Δ ΧόϨοδͷߏ [ { url: "ファイルのURL", text: "ファイルの中身", ranges: [
// カバレッジの開始位置・終了位置の配列 { start: 0, end: 100 }, … ] }, … ]
ෳͷΧόϨοδΛϚʔδ { url: "ファイルA", text: "…", ranges: [ { start:
0, end: 100 }, { start: 201, end: 300 } ] } { url: "ファイルA", text: "…", ranges: [ { start: 101, end: 200 }, { start: 250, end: 350 } ] } ΧόϨοδͦͷ ΧόϨοδͦͷ { url: "ファイルA", text: "…", ranges: [ { start: 0, end: 100 }, { start: 101, end: 200 }, { start: 201, end: 350 } ] }
ΧόϨοδ͕ൃੜ͠ͳ͍ w !NFEJBએݴɺ!GPOUGBDFએݴʹ ΧόϨοδ͕ൃੜ͠ͳ͍ w *TTVFʹొ͞Ε͍͕ͯͨόά͔༷͔͔Βͳ͍ w ҎԼͷΑ͏ʹରॲ w !GPOUGBDFએݴΧόϨοδ͋Γͳؔ͠ΘΒͣ͢
w !NFEJBએݴͷελΠϧʹΧόϨοδ͕͋Δ߹ ͢
͓ΘΓ w 1VQQFUFFS&&ςετҎ֎ͷ͍ํͰ͖Δʂ w ࠷ऴతʹεΫγϣΛऔ͓͍ͬͯͯ ը૾ࠩΛग़ͤΔΑ͏ʹͯ͠ΑΓ࣮֬ʹෆཁͳελΠϧΛ ফͤΔΑ͏ʹͨ͠
͋Γ͕ͱ͏ ͍͟͝·ͨ͠