An ESLint plugin to lint and fix markdown files. It uses amazing remark-lint
under the hood. Also enables using prettier
to automatically format your markdown files right from eslint
!
ESLint is a tool for linting Javascript. There is another plugin called eslint-plugin-markdown
, however it is still
only linting Javascript parts inside *.md
files, and leaves Markdown itself untouched.
Wouldn't it be cool, if we could use ESLint to enforce style of Markdown itself? That is what this plugin is for!
You'll first need to install ESLint:
$ npm i eslint --save-dev
# or
$ yarn add -D eslint
Next, install eslint-plugin-md
:
$ npm install eslint-plugin-md --save-dev
# or
$ yarn add -D eslint-plugin-md
Note: If you installed ESLint globally (using the npm -g
or yarn global
) then you must also install
eslint-plugin-md
globally.
Add plugin:md/recommended
config to extends
section of your your .eslintrc
configuration file
// .eslintrc.js
module.exports = {
extends: ['plugin:md/recommended'],
overrides: [
{
files: ['*.md'],
parser: 'markdown-eslint-parser',
},
],
}
And this is it! By default it will apply all rules from Markdown style guide.
Note: By default ESLint won't lint *.md files. So:
- If you use ESLint from CLI, use
--ext
parameter (e.g.eslint . --ext js,md
) - If you use VSCode with ESLint plugin, add
"eslint.validate": ["markdown"]
in your VSCode preferences
Prettier is an amazing code formatter that supports many languages, including markdown. It is common to use prettier as a rule in ESLint via amazing eslint-plugin-prettier.
This plugin can play nicely together with eslint-plugin-prettier
(meaning that first code will be formatted via
prettier, and then remark rules will be applied). Typical eslint configuration will look like this:
yarn add -D eslint eslint-plugin-prettier eslint-plugin-md
// .eslintrc.js
module.exports = {
extends: ['plugin:prettier/recommended', 'plugin:md/recommended'],
overrides: [
{
files: ['*.md'],
parser: 'markdown-eslint-parser',
rules: {
'prettier/prettier': [
'error',
// Important to force prettier to use "markdown" parser - otherwise it wouldn't be able to parse *.md files.
// You also can configure other options supported by prettier here - "prose-wrap" is
// particularly useful for *.md files
{ parser: 'markdown' },
],
},
},
],
}
By default, code inside fenced code block marked as js language (```js
) will be linted against your default eslint
configuration for js files. However, that may be undesirable - usually you will want less strict rules for JS code in
*.md files.
To modify setup, you can use "overrides" section in your eslintrc in this way:
// .eslintrc.js
module.exports = {
extends: ['plugin:md/recommended'],
overrides: [
{
files: ['*.md'],
parser: 'markdown-eslint-parser',
},
{
files: ['*.md.js'], // Will match js code inside *.md files
rules: {
// Example - disable 2 core eslint rules 'no-unused-vars' and 'no-undef'
'no-unused-vars': 'off',
'no-undef': 'off',
},
},
],
}
This plugin exposes only one eslint rule - md/remark
. However, you can customize remark configuration however you
wish.
// .eslintrc.js
module.exports = {
extends: ['plugin:md/recommended'],
rules: {
'md/remark': [
'error',
{
// This object corresponds to object you would export in .remarkrc file
plugins: ['preset-lint-markdown-style-guide', 'frontmatter', ['lint-maximum-line-length', false]],
},
],
},
overrides: [
{
files: ['*.md'],
parser: 'markdown-eslint-parser',
},
],
}
"Plugin" in remark can mean many things, but for our purposes it can be either remark rule or remark preset. See list of available rules here, and list of available presets (=set of rules) here.
Remark also supports External rules. You can use those as well, just make sure to install corresponding package first. For example, if you want to use alphabetize-lists external rule:
yarn add -D remark-lint-alphabetize-lists
// .eslintrc.js
module.exports = {
extends: ['plugin:md/recommended'],
rules: {
'md/remark': [
'error',
{
// This object corresponds to object you would export in .remarkrc file
plugins: ['preset-lint-markdown-style-guide', 'frontmatter', 'remark-lint-alphabetize-lists'],
},
],
},
overrides: [
{
files: ['*.md'],
parser: 'markdown-eslint-parser',
},
],
}