メインコンテンツまでスキップ

プロパティを設定する

設定は、以下のプロパティを持ちます。

{
"extends": [],
"plugins": {},
"parser": {},
"parserOptions": {},
"specs": [],
"excludeFiles": [],
"rules": {},
"nodeRules": [],
"childNodeRules": [],
"pretenders": [],
"overrideMode": "reset",
"overrides": {}
}
プロパティ初期ガイドインターフェイス
extendsプリセットをつかうインターフェイス
pluginsカスタムルールの適用, カスタムルールをつくるインターフェイス
parserHTML以外につかうインターフェイス
parserOptions-インターフェイス
specsHTML以外につかうインターフェイス
excludeFilesファイルの除外インターフェイス
rulesルールを適用するインターフェイス
nodeRules部分的な適用インターフェイス
childNodeRules部分的な適用インターフェイス
pretendersプリテンダー(偽装機能)インターフェイス
overrideModeルールを上書きして無効化インターフェイス
overridesルールを上書きして無効化インターフェイス

パスの解決

extendspluginsparserspecsexcludeFilesはパスを指定できます。そのうちextendspluginsparserspecsの4つでは、パスの代わりにnpmパッケージを指定できます。

まず、パッケージとしてインポートします。パッケージが存在しない、文字列がパッケージでないなど、失敗した場合は、文字列を単なるパスとして解決します。相対パスは、設定ファイルのあるディレクトリが基準となります。

各プロパティの詳細

extends

他の設定ファイルへのパスを指定した場合、その設定をマージします。

{
"extends": [
// ローカルファイルとして読み込む
"../../.markuplintrc",
// パッケージとして読み込む
"third-party-config"
]
}

markuplint:というプレフィックスがついた名前は、Markuplintから提供されたpresetを読み込みます。

{
"extends": ["markuplint:recommended"]
}

plugin:というプレフィックスがついた名前は、プラグインから提供された設定を読み込みます。スラッシュの前はプラグインがもつ名前空間です。スラッシュの後ろは、そのプラグイン固有の設定名です。

{
"extends": ["plugin:third-party-plugin-name/config-name"],
"plugins": ["third-party-plugin"]
}

インターフェイス

interface Config {
extends?: string[];
}

plugins

任意のプラグインを読み込むことができます。パッケージ名またはパスを指定します。プラグインが設定をもつ場合はsettingsに指定できます。

{
"plugins": [
"third-party-plugin",
"@third-party/markuplint-plugin",
{
"name": "third-party-plugin2",
"settings": {
"foo": "bar"
}
},
"./path/to/local-plugin.js",
{
"name": "./path/to/local-plugin.js2",
"settings": {
"foo": "bar"
}
}
]
}

インターフェイス

interface Config {
plugins?: (
| string
| {
name: string;
settings?: Record<string, string | number | boolean | Object>;
}
)[];
}

parser

キーに正規表現を、値にパーサのファイルパスまたはパッケージ名を指定します。正規表現は、対象ファイルにマッチするものを指定します(例は拡張子を示しています)。

{
"parser": {
"\\.pug$": "@markuplint/pug-parser",
"\\.[jt]sx?$": "@markuplint/jsx-parser",
"\\.vue$": "@markuplint/vue-parser",
"\\.svelte$": "@markuplint/svelte-parser",
"\\.ext$": "./path/to/custom-parser/any-lang.js"
}
}

インターフェイス

interface Config {
parser?: {
[regex: string]: string;
};
}

parserOptions

{
"parserOptions": {
"ignoreFrontMatter": true,
"authoredElementName": ["AuthoredElement"]
}
}

ignoreFrontMatter

trueを設定すると、パーサはソースコードのFront Matterフォーマット部分を無視します。デフォルトはfalseです。

---
prop: value
---

<html>
...
</html>

authoredElementName

ReactVueなどを使っている場合、Markuplintのパーサーはコンポーネントに小文字の名前を付けると、ネイティブのHTML要素として検出します。ほとんどの場合、コンポーネントは大文字から命名する必要がありますが、パーサプラグインごとに特定のパターンがあります(例:Vue: Built-in Special Elements)。もし、異なる命名パターンが必要な場合は、authoredElementNameオプションを指定することで解決できます。デフォルトはundefinedです。

{
"parserOptions": {
"authoredElementName": ["custom", "mine"]
}
}
<template>
<custom><!-- 指定がない場合はネイティブのHTML要素として検出されます。 --></custom>
<mine><!-- 指定がない場合はネイティブのHTML要素として検出されます。 --></mine>
</template>

インターフェイス

interface Config {
parserOptions?: {
ignoreFrontMatter?: boolean;
authoredElementName?: string | RegExp | Function | (string | RegExp | Function)[];
};
}

specs

キーに正規表現を、値にスペックファイルのパスまたはパッケージ名を指定します。正規表現は、対象ファイルにマッチするものを指定します(例は拡張子を示しています)。

{
"specs": {
"\\.vue$": "@markuplint/vue-spec",
"\\.ext$": "./path/to/custom-specs/any-lang.js"
}
}

インターフェイス

interface Config {
specs?: {
[regex: string]: string;
};
}
v1.xまで非推奨の構文

配列または文字列で指定可能ですが、非推奨です。

{
// 非推奨
"specs": ["@markuplint/vue-spec", "./path/to/custom-specs/any-lang"]
}
{
// 非推奨
"specs": "@markuplint/vue-spec"
}

excludeFiles

必要であれば、ファイルを除外できます。値は設定ファイルからの相対パスか絶対パスが必要です。パスはglob形式も可能です。否定を表す!シンボルを使うこともできます。後から指定したものが優先されます。パターンは.gitignoreの仕様に従って動作します。(node-ignoreを用いて解決されます)

{
"excludeFiles": ["./ignore.html", "./ignore/*.html", "!./ignore/no-ignore.html"]
}

インターフェイス

interface Config {
excludeFiles?: string[];
}

rules

ルールを有効にしたり、詳細を設定します。各ルールの値は、文字列、数値、および配列のいずれかです。

falseを指定した場合、ルールは無効になります。trueを指定すると、各ルールが持つデフォルト値として適用されます。

{
"rules": {
"rule-name": "value" // ここにルール名と値を設定します
}
}

もしくは、Objectで詳細を指定します。

{
"rules": {
"rule-name": {
"value": "any-value",
"severity": "error",
"options": {
"any-option": "any-optional-value"
}
}
}
}

value

省略可能です。省略した場合は、各ルールが持つデフォルト値として評価されます。

severity

"error"または"warning"を受け取ります。省略可能です。省略した場合は、各ルールが持つデフォルトの深刻度で評価されます。

options

ルールが定義するObjectを受け取ります。省略可能です。フィールドの一部がデフォルト値を持つ場合があります。

非推奨のoptionフィールド

optionフィールドは、v3.0.0からoptionsに置き換えられました。互換性のためにoptionを通しても適用できますが、非推奨です。代わりにoptionsを使用してください。

ルール名について

ルール名はスラッシュを含む場合があります。その場合、そのルールがプラグインによるものであることを示します。スラッシュの前はプラグインがもつ名前空間です。スラッシュの後ろは、そのプラグイン固有の一意なルール名です。

{
"plugins": ["third-party-plugin", "./path/to/local-plugin.js"],
"rules": {
"core-rule-name": true,
"third-party-plugin/rule-name": true,
"named-plugin-imported-form-local/rule-name": true
}
}

インターフェイス

interface Config {
rules?: {
[ruleName: string]: Rule<T, O>;
};
}

type Rule<T, O> =
| boolean
| T
| {
severity?: 'error' | 'warning' | 'info';
value?: T;
option?: O;
reason?: string;
};

nodeRules

特定の要素にのみルールを適用させたい場合、このプロパティを指定します。値が配列であることに注意してください。

selectorregexSelectorのどちらかが必要です。rulesフィールドも必須です。rulesプロパティと同じ値を指定します。

{
"nodeRules": [
{
"selector": "main",
"rules": {
"class-naming": "/[a-z]+(__[a-z]+)?/"
}
}
]
}

rules

rulesプロパティと同じ値を受け取ります。必須です。

selector

ターゲットにマッチさせるためのセレクタを受け取ります。regexSelectorを使用しない場合は必須です。

regexSelector

ターゲットにマッチさせるための正規表現を受け取ります。selectorを使用しない場合は必須。

このフィールドには、nodeNameattrNameattrValueの各フィールドがあり、任意に正規表現を受け取ります。そのため、それぞれ省略が可能です。組み合わせる場合はAND条件となります。

正規表現はスラッシュで挟む必要があります。そうでない場合は、単なる文字列として適用されます。

{
"nodeRules": [
{
"regexSelector": {
"nodeName": "/^[a-z]+$/",
"attrName": "/^[a-z]+$/",
"attrValue": "/^[a-z]+$/"
},
"rules": {
"any-rule": "any-value"
}
}
]
}
ヒント

正規表現で文字列をキャプチャし、rulesプロパティの値に展開する強力な機能を備えています。先頭に$マークを付けたキャプチャ番号を変数として展開します。値はMustache形式で指定します。

{
"nodeRules": [
{
"regexSelector": {
"attrName": "/^data-([a-z]+)$/"
},
"rules": {
"any-rule": "It is {{ $1 }} data attribute",
"any-rule2": {
"value": "It is {{ $1 }} data attribute",
"severity": "error"
}
}
}
]
}

もちろん、名前付きキャプチャグループを使うことも可能です。名前を変数として展開します。

{
"nodeRules": [
{
"regexSelector": {
"attrName": "/^data-(?<dataName>[a-z]+)$/"
},
"rules": {
"any-rule": "It is {{ dataName }} data attribute"
}
}
]
}
注意

名前付きキャプチャの使用を推奨します。番号付きキャプチャは衝突して上書きされる可能性があります。

{
"nodeRules": [
{
"regexSelector": {
"attrName": "/^data-([a-z]+)$/", // `$1`になります
"attrValue": "/^(.+)$/" // ここも`$1`になり、`$1`は上書きされます
},
"rules": {
"any-rule": "It is {{ $1 }} data attribute, and value is {{ $1 }}"
}
},
{
"regexSelector": {
"attrName": "/^data-(?<dataName>[a-z]+)$/", // `dataName`になります
"attrValue": "/^(?<dataValue>.+)$/" // `dataValue`になります
},
"rules": {
"any-rule": "It is {{ dataName }} data attribute, and value is {{ dataValue }}"
}
}
]
}

combinationフィールドを使えば、複雑な条件でも要素を選択できます。

{
"nodeRules": [
{
"regexSelector": {
"attrName": "img",
"combination": {
"combinator": ":has(~)",
"nodeName": "source"
}
}
}
]
}

上記はCSSのセレクタimg:has(~ source)と同等です。

combinatorは以下をサポートします。

  • " ": 子孫結合子
  • ">": 子結合子
  • "+": 後方隣接兄弟結合子
  • ":has(+)": 前方隣接兄弟結合子
  • "~": 後方兄弟結合子
  • ":has(~)": 前方兄弟結合子

ノードは無制限に深く定義できます。

{
"nodeRules": [
{
"regexSelector": {
"nodeName": "el1",
"combination": {
"combinator": " ",
"nodeName": "el2",
"combination": {
"combinator": ">",
"nodeName": "el3",
"combination": {
"combinator": "+",
"nodeName": "el4",
"combination": {
"combinator": "~",
"nodeName": "el5"
}
}
}
}
}
}
]
}

上記はCSSのセレクタel1 el2 > el3 + el4 ~ el5と同等です。

インターフェイス

interface Config {
nodeRules?: (
| {
selector: string;
rules: {
[ruleName: string]: Rule<T, O>;
};
}
| {
regexSelector: RegexSelector;
rules: {
[ruleName: string]: Rule<T, O>;
};
}
)[];
}

type RegexSelector = {
nodeName?: string;
attrName?: string;
attrValue?: string;
combination?: RegexSelector & {
combinator: ' ' | '>' | '+' | '~' | ':has(+)' | ':has(~)';
};
};

childNodeRules

特定の要素の子孫に何らかのルールを適用させたい場合、このプロパティで指定します。inheritanceフィールドにtrueを指定すると、対象要素のすべての子孫ノードに適用され、指定しなければ子ノードのみに適用されます。値が配列であることに注意してください。

注記

このプロパティはinheritanceフィールドを持つこと以外は、nodeRulesプロパティと同じフィールドを受け取ります。

inheritance

論理値を受け取ります。省略可能で、デフォルトはfalseです。

インターフェイス

interface Config {
childNodeRules?: (
| {
selector: string;
inheritance?: boolean;
rules: {
[ruleName: string]: Rule<T, O>;
};
}
| {
regexSelector: RegexSelector;
inheritance?: boolean;
rules: {
[ruleName: string]: Rule<T, O>;
};
}
)[];
}

pretenders

プリテンダー機能は、カスタムコンポーネントをネイティブのHTML要素のように見せかける機能です。いくつかのルールで、コンポーネントをレンダリングされた結果の要素として評価するために利用します。値が配列であることに注意してください。

selector

対象コンポーネントにマッチさせるためのセレクタを受け取ります。必須です。

as

要素名もしくは要素のプロパティを受け取ります。必須です。

要素名
{
"pretenders": [
{
"selector": "MyComponent",
"as": "div"
}
]
}
要素のプロパティ
{
"pretenders": [
{
"selector": "MyComponent",
"as": {
"element": "div",
"inheritAttrs": true,
"attrs": [
{
"name": "role",
"value": "region"
}
]
}
}
]
}

as.element

要素名を受け取ります。必須です。

as.inheritAttrs

レンダリングされた要素が、コンポーネントで定義された属性を公開するかどうかを論理値を受け取ります。省略可能です。省略した場合のデフォルト値はfalseです。

const MyComponent = props => {
return <div {...props}>{props.children}</div>;
};
{
"pretenders": [
{
"selector": "MyComponent",
"as": {
"element": "div",
"inheritAttrs": true
}
}
]
}
<div>
{/* レンダリングされたdiv要素がaria-live="polite"を持つものとして評価します。 */}
<MyComponent aria-live="polite">Lorem Ipsam</MyComponent>
</div>;

as.attrs

配列を受け取ります。レンダリングされた要素に指定した属性を持っているものとして評価されます。省略可能です。

const MyPicture = () => {
return <img src="path/to/file.png" alt="Lorem ipsam" />;
};
{
"pretenders": [
{
"selector": "MyPicture",
"as": {
"element": "img",
"attrs": [
{
"name": "src"
},
{
"name": "alt",
"value": "Lorem ipsam"
}
]
}
}
]
}
<div>
{/* レンダリングされたimg要素がsrc属性とalt="Lorem ipsam"を持つものとして評価されます。*/}
<MyComponent />
</div>;

as.attrs[].name

属性名を受け取ります。必須であす。

as.attrs[].value

属性値を受け取ります。省略可能です。

as.aria

ARIAのプロパティをObjectで受け取ります。現在段階ではnameフィールドしかありません。省略可能です。

as.aria.name

アクセシブルな名前を論理値もしくはObjectで受け取ります。コンポーネントが名前を明確に持っている場合はtrueを指定する。そうでなければ、その名前を参照する属性名をfromAttrに設定する。

const MyIcon = ({ label }) => {
return (
<svg role="img" aria-label={label}>
<rect />
</svg>
);
};
{
"pretenders": [
{
"selector": "MyIcon",
"as": {
"element": "svg",
"aria": {
"name": {
"fromAttr": "label"
}
}
}
}
]
}
<div>
{/* アクセシブルな名前が「my icon name」であるとして評価します。 */}
<MyIcon label="my icon name" />
</div>;

インターフェイス

interface Config {
pretenders?: {
selector: string;
as: string | OriginalNode;
}[];
}

type OriginalNode = {
element: string;
namespace?: 'svg';

inheritAttrs?: boolean;
attrs?: {
name: string;
value?:
| string
| {
fromAttr: string;
};
}[];

aria?: {
name?:
| boolean
| {
fromAttr: string;
};
};
};

overrideMode

このオプションは、overrides セクションの振る舞いを制御します。このオプションを設定することで、プロジェクトの特定の部分に適用する異なるLintルールの設定の扱い方を指定できます。

reset

リセットモードでは、overrides セクションの設定は全く新しい設定として扱われ、既存の設定は無視されます。このモードは、特定のファイルやディレクトリに完全に新しいLintルールを適用したい場合に役立ちます。overrides セクションに指定された設定のみが使用され、他の設定は適用されません。

merge

このモードを選択すると、overrides セクションで指定された設定が既存の全体設定とマージされます。具体的には、overrides セクションに記載されたルールが追加されたり、既存のものを上書きしますが、他の設定は保持されます。このモードは、既存の設定に対して部分的な変更や追加を行いたい場合に適しています。

既定値と推奨

overrideMode の既定値は、互換性を保つために reset に設定されています。この設定は、デフォルトで overrides セクションが既存の設定を完全に置き換え、特定のファイルやディレクトリに特化したクリーンな状態を提供することを保証します。

既存のルールと新しいルールを融合させるより一般的な振る舞いを期待する場合は、overrideModemerge に明示的に設定するべきです。これにより、overrides の設定がグローバル設定とシームレスに統合され、指定された変更のみが適用される一方で、既存のルールも維持されます。

インターフェイス

interface Config {
overrideMode?: 'reset' | 'merge';
}

overrides

overridesオプションを指定すると、特定のファイルに対して設定を上書きできます。キーに指定されたglob形式のパスに適用します。(minimatchを用いて解決されます)

{
"rules": {
"any-rule": true
},
"overrides": {
"./path/to/**/*": {
"rules": {
"any-rule": false
}
}
}
}

以下のプロパティを上書きできます。

インターフェイス

interface Config {
overrides?: {
[path: string]: Omit<Config, 'extends' | 'overrideMode' | 'overrides'>;
};
}