eslint-loader
is deprecated. The replacement, is eslint-webpack-plugin
.
The README gives helpful information, but in looking for a full post on migration I came up empty. So this is that post for anyone else!
Existing Example
The README example is great for switching from rule to plugin syntax. So this,
const config = {module: {rules: [{test: /\.js$/,exclude: /node_modules/,loader: 'eslint-loader',options: {// eslint options (if necessary)},},],},}
Becomes this.
import ESLintPlugin from 'eslint-webpack-plugin')const config = {plugins: [new ESLintPlugin(options)],}
But what happens with all those additional key-value pairs included in the original ruleset? They can't just be dropped, it changes the functionality.
Plugin Options
Depending on what configuration you were passing, you may have to make some slight tweaks. For example, I had the following.
const config = {module: {rules: [{enforce: `pre`,test: /\.jsx?$/,exclude: (modulePath: string): boolean =>modulePath.includes(VIRTUAL_MODULES_BASE_PATH) ||vendorRegex.test(modulePath),loader: 'eslint-loader',},],},}
test
takes a glob for files to run the loader against. There are a few options in eslint-webpack-plugin
that provide the same functionality, I opted for extensions
.
exclude
still works but because plugins run against the entire chunk, whereas loaders run against single files, it's a bit different. Mainly, it takes an array of strings rather than a function. Note that it also defaults to /node_modules/
.
Finally, there is enforce
. I didn't find an options level equivalent for this. As it turns out, I was able to drop it in my implementation. However, I believe you can use a hook to execute the plugin at a specific point in the build process.
So my migrated config became this.
const options = {extensions: [`js`, `jsx`],exclude: [`/node_modules/`,`/bower_components/`,VIRTUAL_MODULES_BASE_PATH,],...eslintOptions, // these are the options we'd previously passed in}const config = {return new ESLintPlugin(options)}
And that should be it
I had to do a bit more to complete the migration in the existing codebase. If you'd like to see the code in the wild you can check out the PR. But hopefully, this helps someone else!