Lint your JavaScript code inside ERB files (.js.erb
).
A zero-dependency plugin for ESLint.
Warning v2.0.0 is breaking. We use the new ESLint flat config format. Use
erb:recommended-legacy
if you want to keep using the old.eslintrc.js
format.
Install the plugin alongside ESLint:
npm install --save-dev eslint eslint-plugin-erb
Starting of v9 ESLint provides a new flat config format (eslint.config.js
). Also see the configuration migration guide. Use it as follows and it will automatically lint all your .js.erb
files:
// eslint.config.js
import erb from "eslint-plugin-erb";
export default [
// if you are using VSCode, don't forget to put
// "eslint.experimental.useFlatConfig": true
// in your settings.json
erb.configs.recommended,
{
linterOptions: {
// The "unused disable directive" is set to "warn" by default.
// For the ERB plugin to work correctly, you must disable
// this directive to avoid issues described here
// https://github.com/eslint/eslint/discussions/18114
// If you're using the CLI, you might also use the following flag:
// --report-unused-disable-directives-severity=off
reportUnusedDisableDirectives: "off",
},
// your other configuration options
}
];
See more complete example
// eslint.config.js
import js from "@eslint/js";
import stylistic from "@stylistic/eslint-plugin";
import globals from "globals";
import erb from "eslint-plugin-erb";
const customizedStylistic = stylistic.configs.customize({
"indent": 2,
"jsx": false,
"quote-props": "always",
"semi": "always",
"brace-style": "1tbs",
});
const customGlobals = {
MyGlobalVariableOrFunctionOrClassOrWhatever: "readable",
};
// [1] https://eslint.org/docs/latest/use/configure/configuration-files-new#globally-ignoring-files-with-ignores
export default [
js.configs.recommended,
erb.configs.recommended,
// Globally ignoring the following files
// "Note that only global ignores patterns can match directories.
// 'ignores' patterns that are specific to a configuration will
// only match file names." ~ see [1]
{
ignores: [
"node_modules/",
"tests/fixtures/",
"tmp/",
],
},
{
plugins: {
"@stylistic": stylistic,
},
rules: {
...customizedStylistic.rules,
"no-unused-vars": ["warn", { argsIgnorePattern: "^_" }],
"@stylistic/quotes": ["error", "double", { avoidEscape: true }],
},
languageOptions: {
ecmaVersion: 2022,
sourceType: "module",
globals: {
...customGlobals,
...globals.browser,
...globals.node,
},
},
linterOptions: {
// The "unused disable directive" is set to "warn" by default.
// For the ERB plugin to work correctly, you must disable
// this directive to avoid issues described here
// https://github.com/eslint/eslint/discussions/18114
// If you're using the CLI, you might also use the following flag:
// --report-unused-disable-directives-severity=off
reportUnusedDisableDirectives: "off",
},
},
];
Alternative way to configure the processor
With this variant you have a bit more control over what is going on, e.g. you could name your files .js.special-erb
and still lint them (if they contain JS and ERB syntax).
// eslint.config.js
import erb from "eslint-plugin-erb";
export default [
// if you are using VSCode, don't forget to put
// "eslint.experimental.useFlatConfig": true
// in your settings.json
{
files: ["**/*.js.erb"],
processor: erb.processors.erbProcessor,
},
{
linterOptions: {
// The "unused disable directive" is set to "warn" by default.
// For the ERB plugin to work correctly, you must disable
// this directive to avoid issues described here
// https://github.com/eslint/eslint/discussions/18114
// If you're using the CLI, you might also use the following flag:
// --report-unused-disable-directives-severity=off
reportUnusedDisableDirectives: "off",
},
// your other configuration options
}
];
Legacy: you can still use the old `.eslintrc.js` format
You can extend the plugin:erb/recommended-legacy
config that will enable the ERB processor on all .js.erb
files. Note that instead of "plugin:erb/recommended", you now have to use "plugin:erb/recommended-legacy".
// .eslintrc.js
module.exports = {
extends: "plugin:erb/recommended-legacy"
};
Or you can configure the processor manually (advanced):
// .eslintrc.js
module.exports = {
plugins: ["erb"],
overrides: [
{
files: ["**/*.js.erb"],
processor: "erb/erbProcessor"
}
]
};
The ESLint extension for VSCode has built-in support for the ERB processor once you've configured it in your .eslintrc.js
file as shown above.
If you're using VSCode, you may find this settings.json
options useful:
{
"editor.formatOnSave": false, // it still autosaves with the options below
//////////////////////////////////////
// JS (ESLint)
//////////////////////////////////////
// https://eslint.style/guide/faq#how-to-auto-format-on-save
// https://github.com/microsoft/vscode-eslint#settings-options
"eslint.format.enable": true,
"eslint.experimental.useFlatConfig": true, // use the new flat config format
"[javascript]": {
"editor.formatOnSave": false, // to avoid formatting twice (ESLint + VSCode)
"editor.defaultFormatter": "dbaeumer.vscode-eslint" // use ESLint plugin
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit" // Auto-fix ESLint errors on save
},
// this disables VSCode built-int formatter (instead we want to use ESLint)
"javascript.validate.enable": false,
//////////////////////////////////////
// Files
//////////////////////////////////////
"files.exclude": {
"node_modules/": false,
},
"files.associations": {
"*.js.erb": "javascript"
},
}
- Does not account for code indentation inside
if/else
ERB statements, e.g. this snippet
<% if you_feel_lucky %>
console.log("You are lucky 🍀");
<% end %>
will be autofixed to
<% if you_feel_lucky %>
console.log("You are lucky 🍀");
<% end %>
- No support for ESLint suggestions (but full support for Autofixes as shown in the GIF above)