Closed kubosho closed 2 years ago
Getting started: https://markuplint.dev/getting-started
まずは npx markuplint --init
を実行する。いくつか選択肢が出てくるのでそれに答えていく。
テンプレートエンジンの選択はスペースキーを押してチェックを付けないと何も選ばれていないことになるので注意が必要。
React向けに設定した結果、markuplintの設定は次のようになった。
{
"parser": {
"\\.[jt]sx?$": "@markuplint/jsx-parser"
},
"specs": {
"\\.[jt]sx?$": "@markuplint/react-spec"
},
"extends": [
"markuplint:recommended"
]
}
markuplintを実行した結果。
$ markuplint **/*.tsx
<markuplint> passed /Users/kubosho/src/github.com/kubosho/blog.kubosho.com/src/components/EntryList.tsx
<markuplint> passed /Users/kubosho/src/github.com/kubosho/blog.kubosho.com/src/components/ErrorBoundary.tsx
<markuplint> passed /Users/kubosho/src/github.com/kubosho/blog.kubosho.com/src/components/FacebookLink.tsx
<markuplint> warning: 属性「xmlns」は効果がありません。属性は不要です (ineffective-attr) /Users/kubosho/src/github.com/kubosho/blog.kubosho.com/src/components/icon/facebook.tsx:7:5
6: ••<svg
7: ••••xmlns="http://www.w3.org/2000/svg"
8: ••••viewBox="0•0•320•512"
<markuplint> error: 属性「focusable」は許可されていません (invalid-attr) /Users/kubosho/src/github.com/kubosho/blog.kubosho.com/src/components/icon/facebook.tsx:11:5
10: ••••role="img"
11: ••••focusable="false"
12: ••>
<markuplint> warning: 属性「xmlns」は効果がありません。属性は不要です (ineffective-attr) /Users/kubosho/src/github.com/kubosho/blog.kubosho.com/src/components/icon/twitter.tsx:6:5
5: ••<svg
6: ••••xmlns="http://www.w3.org/2000/svg"
7: ••••viewBox="0•0•512•512"
<markuplint> error: 属性「focusable」は許可されていません (invalid-attr) /Users/kubosho/src/github.com/kubosho/blog.kubosho.com/src/components/icon/twitter.tsx:10:5
9: ••••role="img"
10: ••••focusable="false"
11: ••>
<markuplint> passed /Users/kubosho/src/github.com/kubosho/blog.kubosho.com/src/components/PublishedDate.tsx
<markuplint> passed /Users/kubosho/src/github.com/kubosho/blog.kubosho.com/src/components/SiteContents.tsx
<markuplint> passed /Users/kubosho/src/github.com/kubosho/blog.kubosho.com/src/components/SnsShare.tsx
<markuplint> passed /Users/kubosho/src/github.com/kubosho/blog.kubosho.com/src/components/TwitterLink.tsx
<markuplint> error: 属性「property」は次のパターンにマッチしませんでした /^og:[a-z_]+/ (invalid-attr) /Users/kubosho/src/github.com/kubosho/blog.kubosho.com/src/pages/_app.tsx:50:25
49: ••••••••<meta•property="og:image:height"•content="630"•/>
50: ••••••••<meta•property="fb:app_id"•content={FACEBOOK_APP_ID}•/>
51: ••••••••<meta•name="twitter:card"•content="summary_large_image"•/>
<markuplint> error: 属性「property」は次のパターンにマッチしませんでした /^og:[a-z_]+/ (invalid-attr) /Users/kubosho/src/github.com/kubosho/blog.kubosho.com/src/pages/_app.tsx:52:25
51: ••••••••<meta•name="twitter:card"•content="summary_large_image"•/>
52: ••••••••<meta•property="twitter:image"•content={OG_IMAGE_URL}•/>
53: ••••••••<meta•name="twitter:site"•content={`@${TWITTER_ACCOUNT_ID}`}•/>
<markuplint> passed /Users/kubosho/src/github.com/kubosho/blog.kubosho.com/src/pages/_document.tsx
<markuplint> passed /Users/kubosho/src/github.com/kubosho/blog.kubosho.com/src/pages/categories/[category].tsx
<markuplint> passed /Users/kubosho/src/github.com/kubosho/blog.kubosho.com/src/pages/draft/[id].tsx
<markuplint> passed /Users/kubosho/src/github.com/kubosho/blog.kubosho.com/src/pages/entry/[id].tsx
<markuplint> passed /Users/kubosho/src/github.com/kubosho/blog.kubosho.com/src/pages/feed.tsx
<markuplint> passed /Users/kubosho/src/github.com/kubosho/blog.kubosho.com/src/pages/index.tsx
<markuplint> passed /Users/kubosho/src/github.com/kubosho/blog.kubosho.com/src/pages/policy.tsx
<markuplint> passed /Users/kubosho/src/github.com/kubosho/blog.kubosho.com/src/pages/tags/[tag].tsx
<markuplint> error: 要素「script」には属性「defer」が必要です (required-attr) /Users/kubosho/src/github.com/kubosho/blog.kubosho.com/src/tracking/gtm.tsx:16:10
15: ••});
16: ••return•<script src={`https://www.googletagmanager.com/gtm.js?id=${id}`} async />;
17: }
<markuplint> error: 要素「iframe」には属性「title」が必要です (required-attr) /Users/kubosho/src/github.com/kubosho/blog.kubosho.com/src/tracking/gtm.tsx:22:7
21: ••••<noscript>
22: ••••••<iframe
src={`https://www.googletagmanager.com/ns.html?id=${id}`}
height="0"
width="0"
style={{ display: 'none', visibility: 'hidden' }}
/>
23: ••••••••src={`https://www.googletagmanager.com/ns.html?id=${id}`}
<markuplint> error: 要素「iframe」には属性「loading」が必要です (required-attr) /Users/kubosho/src/github.com/kubosho/blog.kubosho.com/src/tracking/gtm.tsx:22:7
21: ••••<noscript>
22: ••••••<iframe
src={`https://www.googletagmanager.com/ns.html?id=${id}`}
height="0"
width="0"
style={{ display: 'none', visibility: 'hidden' }}
/>
23: ••••••••src={`https://www.googletagmanager.com/ns.html?id=${id}`}
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
warning: 属性「xmlns」は効果がありません。属性は不要です (ineffective-attr)
根拠としては https://html.spec.whatwg.org/multipage/syntax.html#elements-2 のノートっぽい。
The HTML syntax does not support namespace declarations, even in foreign elements. https://html.spec.whatwg.org/multipage/syntax.html#elements-2 より
https://www.w3.org/TR/SVG2/struct.html#Namespace にも書いてあった。
As the example shows there's no need to have an ‘xmlns’ attribute declaring that the element is in the SVG namespace when using the HTML parser. The HTML parser will automatically create the SVG elements in the proper namespace.
error: 属性「focusable」は許可されていません (invalid-attr)
error: 属性「property」は次のパターンにマッチしませんでした /^og:[a-z_]+/ (invalid-attr) <meta•property="fb:app_id"•content={FACEBOOK_APP_ID}•/>
fb:app_id Facebookインサイトを使用するには、アプリIDをページに追加する必要があります。インサイトにより、Facebookからサイトへのトラフィックに関する分析を確認できます。アプリIDはアプリダッシュボードで確認できます。 https://developers.facebook.com/docs/sharing/webmasters/?locale=ja_JP
Facebookインサイトを使う場合は必須っぽい。
error: 属性「property」は次のパターンにマッチしませんでした /^og:[a-z_]+/ (invalid-attr) <meta•property="twitter:image"•content={OG_IMAGE_URL}•/>
https://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/summary-card-with-large-image を見る限りだと、<meta name="">
の形式で定義して良さそう。
<meta name="twitter:image" content="http://graphics8.nytimes.com/images/2012/02/19/us/19whitney-span/19whitney-span-articleLarge.jpg">
error: 要素「script」には属性「defer」が必要です (required-attr) <script src={
https://www.googletagmanager.com/gtm.js?id=${id}
} async />The defer attribute may be specified even if the async attribute is specified, to cause legacy web browsers that only support defer (and not async) to fall back to the defer behavior instead of the blocking behavior that is the default. https://html.spec.whatwg.org/multipage/scripting.html#the-script-element
という記述があるようにレガシーブラウザーのフォールバック用として、async属性を定義したときにdefer属性も一緒に定義して良いという記述はあるが、必須ではない認識。
そして async
と defer
両方定義したら defer
は必要ないというwarningが出力されて、defer
のみ定義したら何のエラーも出なくなった。ルールの調整が必要そう。
error: 要素「iframe」には属性「title」が必要です (required-attr)
21: ••••<noscript>
22: ••••••<iframe
src={`https://www.googletagmanager.com/ns.html?id=${id}`}
height="0"
width="0"
style={{ display: 'none', visibility: 'hidden' }}
/>
23: ••••••••src={`https://www.googletagmanager.com/ns.html?id=${id}`}
などで書かれているように、iframe要素の説明のためにtitle属性が必要となる。 ただGoogle Tag Managerのiframeかつ、スタイル的にも不可視となっているため、title属性を定義したとしても値は空で良さそう。
error: 要素「iframe」には属性「loading」が必要です (required-attr)
仕様では値が lazy
または eager
の2つしか定義されていないが、Chromeは独自に非標準の値である auto
を既定値としているので明示的に定義しておいたほうがいい?
ref: https://web.dev/i18n/ja/iframe-lazy-loading/#iframe-2
既定だと loading="eager"
にすると loading="lazy"
にしろと怒られる。ルールの調整が必要そう。
https://github.com/markuplint/markuplint