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
アクセシビリティチェックを自動化するためのmarkuplintのロードマップ
Search
Yusuke Hirao
August 10, 2018
Programming
2
2.2k
アクセシビリティチェックを自動化するためのmarkuplintのロードマップ
Accessibility Step Vol.01
Yusuke Hirao
August 10, 2018
Tweet
Share
More Decks by Yusuke Hirao
See All by Yusuke Hirao
ユニバーサルHTMLとWebのポテンシャル
yusukehirao
1
850
TypeScriptでつくるNode.jsパッケージ
yusukehirao
3
660
READMEにバッヂが欲しくてテストを書き始めました
yusukehirao
1
800
ユニバーサルなマークアップをしよう
yusukehirao
2
940
本当に必要ですか?そのJavaScript 〜スクロールイベント・リサイズイベント編〜
yusukehirao
0
670
コードレビュー なんてしてられるかッ!!
yusukehirao
24
14k
自動化をデザインしよう
yusukehirao
1
920
JSONの型のはなし
yusukehirao
0
620
トランスパイラという文化(…とその後) - PHPカンファレンス福岡2016
yusukehirao
1
2.8k
Other Decks in Programming
See All in Programming
Let's Write a Train Tracking Algorithm
twocentstudios
0
220
なぜGoのジェネリクスはこの形なのか? Featherweight Goが明かす設計の核心
ryotaros
7
1k
Breaking Up with Big ViewModels — Without Breaking Your Architecture (droidcon Berlin 2025)
steliosf
PRO
1
290
AIエージェント時代における TypeScriptスキーマ駆動開発の新たな役割
bicstone
4
1.3k
タスクの特性や不確実性に応じた最適な作業スタイルの選択(ペアプロ・モブプロ・ソロプロ)と実践 / Optimal Work Style Selection: Pair, Mob, or Solo Programming.
honyanya
2
110
iOSエンジニア向けの英語学習アプリを作る!
yukawashouhei
0
170
2分台で1500examples完走!爆速CIを支える環境構築術 - Kaigi on Rails 2025
falcon8823
3
2.8k
Django Ninja による API 開発効率化とリプレースの実践
kashewnuts
0
860
Model Pollution
hschwentner
1
180
実践AIチャットボットUI実装入門
syumai
7
2.4k
Back to the Future: Let me tell you about the ACP protocol
terhechte
0
120
なぜあの開発者はDevRelに伴走し続けるのか / Why Does That Developer Keep Running Alongside DevRel?
nrslib
1
330
Featured
See All Featured
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
30
2.9k
We Have a Design System, Now What?
morganepeng
53
7.8k
Building a Scalable Design System with Sketch
lauravandoore
462
33k
What’s in a name? Adding method to the madness
productmarketing
PRO
23
3.7k
Automating Front-end Workflow
addyosmani
1371
200k
Why You Should Never Use an ORM
jnunemaker
PRO
59
9.5k
Balancing Empowerment & Direction
lara
4
670
Building a Modern Day E-commerce SEO Strategy
aleyda
43
7.7k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
7
890
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
Scaling GitHub
holman
463
140k
Transcript
ΞΫηγϏϦςΟνΣοΫΛࣗಈԽ͢ΔͨΊͷ NBSLVQMJOUͷϩʔυϚοϓ "DDFTTJCJMJUZ4UFQ7PM
©2018 Yusuke Hirao ࣗݾհ ฏඌ༏యʢͻΒ͓Ώ͏ͯΜʣ גࣜձࣾσΟʔθϩ ϑϩϯτΤϯυΤϯδχΞ #-0(IUUQTOPUFNVZVTVLFIJSBP Yusuke Hirao
@cloud10designs
©2018 Yusuke Hirao ΞΫηγϏϦςΟνΣοΫΛࣗಈԽ͢ΔͨΊͷ NBSLVQMJOUͷϩʔυϚοϓ
©2018 Yusuke Hirao ࠓͪΐͬͱϑϩϯτدΓͷ ٕज़Ϊδϡπͨ͠Ͱ͢
©2018 Yusuke Hirao NBSLVQMJOU͝ଘͷํ✋
©2018 Yusuke Hirao &4-JOUɾTUZMFMJOU͝ଘͷํ✋
©2018 Yusuke Hirao -JOUFSͱ қ͘͠આ໌͢Δͱ ίʔυΛղੳͯ͠ɺ ϧʔϧʹଇͬͯͳ͍෦Λࢦఠ͢ΔπʔϧͰ͢ɻ
©2018 Yusuke Hirao )5.-ͷ-JOUFS Φʔϓϯιʔε/PEFKT)5.--JOUFS
©2018 Yusuke Hirao )5.-ͷ-JOUFS ͖͔͚ͬ IUUQTTQFBLFSEFDLDPNZVTVLFIJSBPLPEPSFCJZVOBOUFTJUFSBSFSVLBUV
©2018 Yusuke Hirao )5.-ͷ-JOUFS ͓͔͛͞·Ͱ4UBS͑·ͨ͠
©2018 Yusuke Hirao ։ൃ్্ ݱࡏW ʹؔΘΒͣ ͍͍ͨͩͯຊʹخ͍͠Ͱ͢
©2018 Yusuke Hirao ͱ͍͏Θ͚Ͱ ϩʔυϚοϓ ࠓޙͷ։ൃ༧ఆ ͷͳ͠
©2018 Yusuke Hirao ΞδΣϯμ ࠓ͢͜ͱ ࠓɺͲ͏͍͏ར༻Λ͍ͯ͠Δͷ͔ ࠓޙɺͲ͏͍͏ར༻Λ͍͔ͨ͠ɾͯ͠΄͍͔͠ ΞΫηγϏϦςΟνΣοΫͷࣗಈԽʹ͍ͭͯ
©2018 Yusuke Hirao ίʔυ࣭νΣοΫ ࣾπʔϧͱͯ͠ ίϚϯυʢλʔϛφϧʣ͔Β ͘͠ HVMQλεΫ͔Β ࠷ۙ—fixΦϓγϣϯ࣮͠·ͨ͠ ࠓɺͲΜͳར༻Λ͍ͯ͠Δͷ͔
©2018 Yusuke Hirao ΤσΟλʔͷػೳͱͯ͠ 7JTVBM4UVEJP$PEF "UPN 7JN ʹϓϥάΠϯ͕ఏڙ͞Ε͍ͯΔ ࠓɺͲΜͳར༻Λ͍ͯ͠Δͷ͔
©2018 Yusuke Hirao νΣοΫ͍ͯ͠Δ͜ͱ ϑΥʔϚοτɾίʔυελΠϧ Πϯσϯτ εϖʔεɾվߦҐஔ ໋໊نଇ όϦσʔγϣϯ γϯλοΫε
ن֨ ඇਪɾΞϯνύλʔϯ ࠓɺͲΜͳར༻Λ͍ͯ͠Δͷ͔
©2018 Yusuke Hirao ΞδΣϯμ ࠓ͢͜ͱ ࠓɺͲ͏͍͏ར༻Λ͍ͯ͠Δͷ͔ ࠓޙɺͲ͏͍͏ར༻Λ͍͔ͨ͠ɾͯ͠΄͍͔͠ ΞΫηγϏϦςΟνΣοΫͷࣗಈԽʹ͍ͭͯ
©2018 Yusuke Hirao ࠓޙɺͲ͏͍͏ར༻Λ͍͔ͨ͠ɾͯ͠΄͍͔͠ NBSLVQMJOUͷϩʔυϚοϓ ݄WBMQIBΞϧϑΝ൛ύϒϦογϡ ݄Wਖ਼ࣜ൛ύϒϦογϡ ⾣ੜπʔϧల։ͷͨΊͷ"1*࣮ ⾣ϓϥάΠϯɾΧελϜϧʔϧͷ"1*࣮ ⾣ΠϯσϯτϑΥʔϚοτɾίʔυελΠϧΛ౷Ұ͢ΔϏϧτΠϯϧʔϧ࣮
⾣ཁૉɾଐੑνΣοΫ͕࠷ݶՄೳͳϏϧτΠϯϧʔϧ࣮ ⾣7JTVBM4UVEJP$PEF֦ுWਖ਼ࣜ൛ύϒϦογϡ ݄WϚΠφʔόʔδϣϯΞοϓ ⾣)5.--JWJOHTUBOEBSEͷόϦσʔγϣϯ͕Ͱ͖ΔϏϧτΠϯϧʔϧՃ ⾣8$8"*"3*"ͷόϦσʔγϣϯ͕Ͱ͖ΔϏϧτΠϯϧʔϧՃ ⾣ϒϥβ༻Ϟδϡʔϧ։ൃ ݄पลϓϥάΠϯ։ൃ ⾣)5.-JO+4ʢ5FNQMBUFMJUFSBMʣରԠϓϥάΠϯ ⾣QVHରԠϓϥάΠϯ ⾣QIQରԠϓϥάΠϯ
©2018 Yusuke Hirao ࠓޙɺͲ͏͍͏ར༻Λ͍͔ͨ͠ɾͯ͠΄͍͔͠ NBSLVQMJOUͷϩʔυϚοϓ ݄WBMQIBΞϧϑΝ൛ύϒϦογϡ ݄Wਖ਼ࣜ൛ύϒϦογϡ ⾣ੜπʔϧల։ͷͨΊͷ"1*࣮ ⾣ϓϥάΠϯɾΧελϜϧʔϧͷ"1*࣮ ⾣ΠϯσϯτϑΥʔϚοτɾίʔυελΠϧΛ౷Ұ͢ΔϏϧτΠϯϧʔϧ࣮
⾣ཁૉɾଐੑνΣοΫ͕࠷ݶՄೳͳϏϧτΠϯϧʔϧ࣮ ⾣7JTVBM4UVEJP$PEF֦ுWਖ਼ࣜ൛ύϒϦογϡ ݄WϚΠφʔόʔδϣϯΞοϓ ⾣)5.--JWJOHTUBOEBSEͷόϦσʔγϣϯ͕Ͱ͖ΔϏϧτΠϯϧʔϧՃ ⾣8$8"*"3*"ͷόϦσʔγϣϯ͕Ͱ͖ΔϏϧτΠϯϧʔϧՃ ⾣ϒϥβ༻Ϟδϡʔϧ։ൃ ݄पลϓϥάΠϯ։ൃ ⾣)5.-JO+4ʢ5FNQMBUFMJUFSBMʣରԠϓϥάΠϯ ⾣QVHରԠϓϥάΠϯ ⾣QIQରԠϓϥάΠϯ
©2018 Yusuke Hirao ࠓޙɺͲ͏͍͏ར༻Λ͍͔ͨ͠ɾͯ͠΄͍͔͠ ੜπʔϧల։ͷͨΊͷ"1*࣮ ੜπʔϧ͕࡞ΕΔΈʹ͍ͭͯཁ͕͋ͬͨ
©2018 Yusuke Hirao ࠓޙɺͲ͏͍͏ར༻Λ͍͔ͨ͠ɾͯ͠΄͍͔͠ ੜπʔϧల։ͷͨΊͷ"1*࣮ ੜπʔϧ੍࡞ʹऔΓֻ͔ͬͯ͘Ε͍ͯΔํʑ͕͍Δ
©2018 Yusuke Hirao ࠓޙɺͲ͏͍͏ར༻Λ͍͔ͨ͠ɾͯ͠΄͍͔͠ ੜπʔϧల։ͷͨΊͷ"1*࣮ ੜπʔϧͷͨΊͷ"1*ఏڙ ࣮த !// ॊೈͰඪ४ͳAPIΛఏڙ͢ΔຊՈ
import * as markuplint from 'markuplint'; !// ࣮ߦڥΛΘͳ͍Universal JavaScriptͰར༻Ͱ͖ΔAPI import { MLCore } from '@markuplint/ml-core'; ˞@textlint/kernelʹӨڹΛड͚͍ͯ·͢ɻ
©2018 Yusuke Hirao ࠓޙɺͲ͏͍͏ར༻Λ͍͔ͨ͠ɾͯ͠΄͍͔͠ ϑϩϯτΤϯυΤϯδχΞʹ ؾܰʹ ϛχϚϜʹ ΞυϗοΫʹ ར༻ͯ͠΄͍͠ ͳͷͰϥΠηϯε.*5Ͱ͢
©2018 Yusuke Hirao ࠓޙɺͲ͏͍͏ར༻Λ͍͔ͨ͠ɾͯ͠΄͍͔͠ NBSLVQMJOUͷϩʔυϚοϓ ݄WBMQIBΞϧϑΝ൛ύϒϦογϡ ݄Wਖ਼ࣜ൛ύϒϦογϡ ⾣ੜπʔϧల։ͷͨΊͷ/PEFKT"1*࣮ ⾣ϓϥάΠϯɾΧελϜϧʔϧͷ"1*࣮ ⾣ΠϯσϯτϑΥʔϚοτɾίʔυελΠϧΛ౷Ұ͢ΔϏϧτΠϯϧʔϧ࣮
⾣ཁૉɾଐੑνΣοΫ͕࠷ݶՄೳͳϏϧτΠϯϧʔϧ࣮ ⾣7JTVBM4UVEJP$PEF֦ுWਖ਼ࣜ൛ύϒϦογϡ ݄WϚΠφʔόʔδϣϯΞοϓ ⾣)5.--JWJOHTUBOEBSEͷόϦσʔγϣϯ͕Ͱ͖ΔϏϧτΠϯϧʔϧՃ ⾣8$8"*"3*"ͷόϦσʔγϣϯ͕Ͱ͖ΔϏϧτΠϯϧʔϧՃ ⾣ϒϥβ༻Ϟδϡʔϧ։ൃ ݄पลϓϥάΠϯ։ൃ ⾣)5.-JO+4ʢ5FNQMBUFMJUFSBMʣରԠϓϥάΠϯ ⾣QVHରԠϓϥάΠϯ ⾣QIQରԠϓϥάΠϯ
©2018 Yusuke Hirao ࠓޙɺͲ͏͍͏ར༻Λ͍͔ͨ͠ɾͯ͠΄͍͔͠ 8$8"*"3*"ͷόϦσʔγϣϯ SPMFଐੑ BSJB ଐੑ ࢦఆཁૉͷଥੑ ଐੑͷنఆɾλΠϙνΣοΫ
aria-***byଐੑͳͲͱ#idͷ߹ੑ aria-labelͷ্ॻ͖νΣοΫ ͳͲ
©2018 Yusuke Hirao ࠓޙɺͲ͏͍͏ར༻Λ͍͔ͨ͠ɾͯ͠΄͍͔͠ 8$8"*"3*"ͷόϦσʔγϣϯ SPMFଐੑ BSJB ଐੑ ࢦఆཁૉͷଥੑ ଐੑͷنఆɾλΠϙνΣοΫ
aria-***byଐੑͳͲͱ#idͷ߹ੑ aria-labelͷ্ॻ͖νΣοΫ ͳͲ ਓ͕ؒνΣοΫ͢Δͷʹݶք͕͋Δͭ
©2018 Yusuke Hirao ΞδΣϯμ ࠓ͢͜ͱ ࠓɺͲ͏͍͏ར༻Λ͍ͯ͠Δͷ͔ ࠓޙɺͲ͏͍͏ར༻Λ͍͔ͨ͠ɾͯ͠΄͍͔͠ ΞΫηγϏϦςΟνΣοΫͷࣗಈԽʹ͍ͭͯ
©2018 Yusuke Hirao Έͳ͞ΜŊͪΖΜςετॻ͍ͯ·͢ΑͶʁ ʢಥͳἤΓʣ
©2018 Yusuke Hirao ΞΫηγϏϦςΟνΣοΫͷࣗಈԽ ͏ͻͱͭར༻͍ͨ͠γʔϯ ίϯϙʔωϯτςετ ✕ ΞΫηγϏϦςΟ 8"*"3*" νΣοΫ
✕ ࣗಈςετπʔϧ
©2018 Yusuke Hirao ΞΫηγϏϦςΟνΣοΫͷࣗಈԽ ίϯϙʔωϯτςετ 7VFKTͷྫ import { render }
from '@vue/server-test-utils'; import Foo from './Foo.vue'; describe('Foo', () !=> { it('renders a div', () !=> { const wrapper = render(Foo); expect(wrapper.text()).toContain('<div>!</div>'); }); }); Ҿ༻IUUQTWVFUFTUVUJMTWVFKTPSHKBBQJSFOEFS
©2018 Yusuke Hirao ΞΫηγϏϦςΟνΣοΫͷࣗಈԽ ίϯϙʔωϯτςετʹ8"*"3*"νΣοΫΛಋೖ NBSLVQMJOU)5.-ͷஅย %PDVNFOU'SBHNFOU Λѻ͑Δ import {
render } from '@vue/server-test-utils'; import * as markuplint from 'markuplint'; import Foo from './Foo.vue'; describe('Foo', () !=> { it('renders a div', () !=> { const wrapper = render(Foo, { propsData: { pressed: true } }); expect( markuplint.verify({ sourceCodes: wrapper.html(), reportType: 'exception', }), ).toBe(true); }); }); ࢀߟIUUQTWVFUFTUVUJMTWVFKTPSHKBBQJSFOEFS
©2018 Yusuke Hirao ΞΫηγϏϦςΟνΣοΫͷࣗಈԽ ίϯϙʔωϯτςετʹ8"*"3*"νΣοΫΛಋೖ NBSLVQMJOU)5.-ͷஅย %PDVNFOU'SBHNFOU Λѻ͑Δ ࢀߟIUUQTWVFUFTUVUJMTWVFKTPSHKBBQJSFOEFS import
{ render } from '@vue/server-test-utils'; import * as markuplint from 'markuplint'; import Foo from './Foo.vue'; describe('Foo', () !=> { it('renders a div', () !=> { const wrapper = render(Foo, { propsData: { pressed: true } }); expect( markuplint.verify({ sourceCodes: wrapper.html(), reportType: 'exception', }), ).toBe(true); }); }); ීวతͳଐੑςετ·ͱΊͯ୲͏
©2018 Yusuke Hirao ΞΫηγϏϦςΟνΣοΫͷࣗಈԽ ίʔσΟϯά ίϯϙʔωϯτ ςετ ϦϯτνΣοΫ git push
ϦϙδτϦ post-receive $*αʔόʔ ϔουϨε ϒϥβʔ test —watch lint —watch ίϯϙʔωϯτ ςετ
©2018 Yusuke Hirao ͱ͜ΖͰ NBSLVQMJOUΞΫηγϏϦςΟνΣοΧʔͳͷ͔
©2018 Yusuke Hirao ΞΫηγϏϦςΟνΣοΫͷࣗಈԽ NBSLVQMJOUΞΫηγϏϦςΟνΣοΧʔͳͷ͔ νΣοΧʔͱ໊Δͱ͜Ζ·Ͱػೳ࣮͢ΔͭΓͳ͍Ͱ͢ɻ ͋͘·ͰNBSLVQMJOUϚʔΫΞοϓϥϯήʔδ༻ͷϦϯλʔͰ͢ɻ ͳͷͰɺཁૉଐੑΛνΣοΫ͢Δ্Ͱid foraltɺ ͦͯ͠8"*"3*"ରʹ͍ͯ͠Δ͚ͩͰ͢ɻ
άϥϑΟΧϧͳ෦$44࣮ʹٴͿͱ͜Ζ·Ͱαϙʔτ͠·ͤΜ͠ɺͰ͖·ͤΜɻ NBSLVQMJOUΛར༻ͯ͠ΞΫηγϏϦςΟνΣοΧʔΛ ։ൃ͍ͯͨͩ͘͠ͷͿ͔͞Ͱͳ͍Ͱ͢
©2018 Yusuke Hirao ΞΫηγϏϦςΟνΣοΫͷࣗಈԽ ͍ͯ͠ΔΞΫηγϏϦςΟνΣοΧʔ "ZD 8FC্ͰΞΫηγϏϦςΟνΣοΫ͕ Ͱ͖ΔαʔϏεπʔϧɻ .*5ϥΠηϯεͷΦʔϓϯιʔεͰ 1)1Ͱॻ͔Ε͍ͯΔͷͰ
$.4ͳͲʹΈࠐΈՄೳɻ 8PSE1SFTTϓϥάΠϯ͕͞Ε͍ͯ·͢ɻ CBTFS$.4ϓϥάΠϯ΄͍͠ʜ
©2018 Yusuke Hirao ·ͱΊ
©2018 Yusuke Hirao ·ͱΊ ؾܰʹɺϛχϚϜʹɺΞυϗοΫʹར༻ͯ͠΄͍͠ ίϯϙʔωϯτςετʹ͑Δ ࣗಈςετπʔϧʹΈࠐΉͷ͕Φεεϝ ΞΫηγϏϦςΟνΣοΫ͋͘·Ͱཁૉɾଐੑ͕ର
ΞΫηγϏϦςΟνΣοΫΛࣗಈԽ͢ΔͨΊͷ NBSLVQMJOUͷϩʔυϚοϓ "DDFTTJCJMJUZ4UFQ7PM