Skip to content
This repository was archived by the owner on Sep 28, 2020. It is now read-only.
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: webpack-contrib/eslint-loader
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v2.2.1
Choose a base ref
...
head repository: webpack-contrib/eslint-loader
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v3.0.0
Choose a head ref
  • 7 commits
  • 79 files changed
  • 5 contributors

Commits on Jul 4, 2019

  1. docs: update gotchas (#284)

    ricardogobbosouza authored and evilebottnawi committed Jul 4, 2019
    Copy the full SHA
    8cb02a6 View commit details
  2. Copy the full SHA
    997cce5 View commit details

Commits on Jul 10, 2019

  1. Copy the full SHA
    4204560 View commit details

Commits on Jul 22, 2019

  1. Copy the full SHA
    dcbac5f View commit details

Commits on Aug 20, 2019

  1. chore(release): 3.0.0

    ricardogobbosouza authored and evilebottnawi committed Aug 20, 2019
    Copy the full SHA
    fc8b4e4 View commit details

Commits on Aug 23, 2019

  1. ci: fix (#291)

    evilebottnawi authored Aug 23, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    78626bb View commit details

Commits on Aug 24, 2019

  1. chore(release): 3.0.0

    alexander-akait committed Aug 24, 2019
    Copy the full SHA
    4895987 View commit details
Showing with 19,147 additions and 4,109 deletions.
  1. +4 −7 .editorconfig
  2. +5 −4 .eslintignore
  3. +8 −0 .eslintrc.js
  4. +4 −0 .gitattributes
  5. +1 −1 .github/CODEOWNERS
  6. +1 −0 .github/CONTRIBUTING.md
  7. +19 −2 .gitignore
  8. +6 −0 .prettierignore
  9. +5 −0 .prettierrc.js
  10. +0 −27 .travis.yml
  11. +31 −0 CHANGELOG.md
  12. +125 −95 README.md
  13. +192 −0 azure-pipelines.yml
  14. +19 −0 babel.config.js
  15. +3 −0 commitlint.config.js
  16. +6 −0 husky.config.js
  17. +0 −279 index.js
  18. +4 −0 lint-staged.config.js
  19. +11,891 −0 package-lock.json
  20. +70 −48 package.json
  21. +7 −0 src/ESLintError.js
  22. +186 −0 src/Linter.js
  23. +42 −0 src/cacheLoader.js
  24. +3 −0 src/cjs.js
  25. +17 −0 src/createEngine.js
  26. +46 −0 src/getOptions.js
  27. +19 −0 src/index.js
  28. +64 −0 src/options.json
  29. +0 −56 test/autofix-stop.js
  30. +43 −0 test/autofix-stop.test.js
  31. +0 −47 test/autofix.js
  32. +35 −0 test/autofix.test.js
  33. +0 −268 test/cache.js
  34. +170 −0 test/cache.test.js
  35. +8 −0 test/cjs.test.js
  36. +0 −25 test/error.js
  37. +18 −0 test/error.test.js
  38. +0 −39 test/eslint-path.js
  39. +26 −0 test/eslint-path.test.js
  40. +0 −29 test/eslintignore.js
  41. +23 −0 test/eslintignore.test.js
  42. +0 −62 test/fail-on-error-async-and-emit.js
  43. +44 −0 test/fail-on-error.test.js
  44. +44 −0 test/fail-on-warning.test.js
  45. +2 −0 test/fixtures/fixable.js
  46. +1 −3 test/fixtures/good-semi.js
  47. +0 −2 test/fixtures/good.js
  48. +1 −1 test/fixtures/ignore.js
  49. +2 −2 test/fixtures/warn.js
  50. +0 −32 test/force-emit-error.js
  51. +24 −0 test/force-emit-error.test.js
  52. +0 −32 test/force-emit-warning.js
  53. +24 −0 test/force-emit-warning.test.js
  54. +0 −37 test/formatter-custom.js
  55. +41 −0 test/formatter-custom.test.js
  56. +0 −29 test/formatter-eslint.js
  57. +18 −0 test/formatter-eslint.test.js
  58. +0 −61 test/formatter-multiple-entries.js
  59. +43 −0 test/formatter-multiple-entries.test.js
  60. +23 −0 test/formatter-official.test.js
  61. +0 −61 test/formatter-write.js
  62. +59 −0 test/formatter-write.test.js
  63. +20 −18 test/mock/eslint/index.js
  64. +1 −1 test/mock/eslint/lib/cli-engine/formatters/stylish.js
  65. +3 −3 test/mock/eslint/lib/formatters/stylish.js
  66. +0 −52 test/multiple-engines.js
  67. +50 −0 test/multiple-engines.test.js
  68. +26 −0 test/no-eslint-configuration.test.js
  69. +0 −24 test/ok.js
  70. +19 −0 test/ok.test.js
  71. +0 −33 test/parameters.js
  72. +26 −0 test/parameters.test.js
  73. +0 −40 test/quiet.js
  74. +24 −0 test/quiet.test.js
  75. +29 −46 test/utils/conf.js
  76. +0 −3 test/utils/version.js
  77. +0 −31 test/warning.js
  78. +19 −0 test/warning.test.js
  79. +5,503 −2,609 yarn.lock
11 changes: 4 additions & 7 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
# editorconfig.org
root = true

[*]
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[*.md]
insert_final_newline = true
trim_trailing_whitespace = false

[Makefile]
indent_style = tab
9 changes: 5 additions & 4 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
node_modules

test/fixtures/
test/output/
/coverage
/dist
/node_modules
/test/fixtures
/test/output
8 changes: 8 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
root: true,
extends: ['@webpack-contrib/eslint-config-webpack', 'prettier'],
rules: {
'global-require': 'off',
'import/no-dynamic-require': 'off',
},
};
4 changes: 4 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
* text=auto
bin/* eol=lf
package-lock.json -diff
yarn.lock -diff
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -3,4 +3,4 @@
@webpack-contrib/org-maintainers

# Add repository specific users / groups
# below here for libs that are not maintained by the org.
# below here for libs that are not maintained by the org.
1 change: 1 addition & 0 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -128,6 +128,7 @@ BREAKING CHANGE: Updates to `Chunk.mapModules`.
This release is not backwards compatible with `Webpack 2.x` due to breaking changes in webpack/webpack#4764
Migration: see webpack/webpack#5225
```

## Testing Your Pull Request
21 changes: 19 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
node_modules
logs
*.log
npm-debug.log*
yarn-debug.log*
.eslintcache

test/output/
/coverage
/dist
/local
/reports
/node_modules
/test/output

.DS_Store
Thumbs.db
.idea
.vscode
*.sublime-project
*.sublime-workspace
*.iml
6 changes: 6 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/coverage
/dist
/node_modules
/test/fixtures
/test/output
CHANGELOG.md
5 changes: 5 additions & 0 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
singleQuote: true,
trailingComma: 'es5',
arrowParens: 'always',
};
27 changes: 0 additions & 27 deletions .travis.yml

This file was deleted.

31 changes: 31 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,34 @@
# Changelog

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

### [3.0.0](https://github.com/webpack-contrib/eslint-loader/compare/v2.2.1...v3.0.0) (2019-08-24)


### Bugfix

* fix corrupted filenames if cwd == "/"
* cannot use string formatter in outputReport
* no Output Report in File when build fails under webpack 4
* add posibility to use absolute file path in outputReport.filePath
* it should be possible to use absolute file path in outputReport.filePath
* try load official formatter ([#285](https://github.com/webpack-contrib/eslint-loader/issues/285)) ([997cce5](https://github.com/webpack-contrib/eslint-loader/commit/997cce5))
* emit warning/error if no config was found/given ([#286](https://github.com/webpack-contrib/eslint-loader/issues/286)) ([4204560](https://github.com/webpack-contrib/eslint-loader/commit/4204560))


### Features

* validate schema options


### Breaking Changes

* drop support for Node < 8.9.0
* minimum supported webpack version is 4
* minimum supported eslint version is 5



# 2.2.1 - 2019-07-04

- Fixed: path to eslint version for cache
220 changes: 125 additions & 95 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,30 @@
# eslint-loader [![Build Status](https://travis-ci.org/webpack-contrib/eslint-loader.svg?branch=master)](https://travis-ci.org/webpack-contrib/eslint-loader)
<div align="center">
<a href="https://github.com/eslint/eslint"><img width="200" height="200" src="https://cdn.worldvectorlogo.com/logos/eslint.svg"></a>
<a href="https://github.com/webpack/webpack"><img width="200" height="200" src="https://webpack.js.org/assets/icon-square-big.svg"></a>
</div>

> eslint loader for webpack
[![npm][npm]][npm-url]
[![node][node]][node-url]
[![deps][deps]][deps-url]
[![tests][tests]][tests-url]
[![coverage][cover]][cover-url]
[![chat][chat]][chat-url]
[![size][size]][size-url]

# eslint-loader

> ESlint loader for webpack
## Install

```console
$ npm install eslint-loader --save-dev
```bash
npm install eslint-loader --save-dev
```

**NOTE**: You also need to install `eslint` from npm, if you haven't already:

```console
$ npm install eslint --save-dev
```bash
npm install eslint --save-dev
```

## Usage
@@ -26,13 +39,13 @@ module.exports = {
{
test: /\.js$/,
exclude: /node_modules/,
loader: "eslint-loader",
loader: 'eslint-loader',
options: {
// eslint options (if necessary)
}
}
]
}
},
},
],
},
// ...
};
```
@@ -48,15 +61,15 @@ module.exports = {
{
test: /\.js$/,
exclude: /node_modules/,
use: ["babel-loader", "eslint-loader"]
}
]
}
use: ['babel-loader', 'eslint-loader'],
},
],
},
// ...
};
```

To be safe, you can use `enforce: "pre"` section to check source files, not modified
To be safe, you can use `enforce: 'pre'` section to check source files, not modified
by other loaders (like `babel-loader`)

```js
@@ -65,18 +78,18 @@ module.exports = {
module: {
rules: [
{
enforce: "pre",
enforce: 'pre',
test: /\.js$/,
exclude: /node_modules/,
loader: "eslint-loader"
loader: 'eslint-loader',
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
}
]
}
loader: 'babel-loader',
},
],
},
// ...
};
```
@@ -107,29 +120,29 @@ This can either be a `boolean` value or the cache directory path(ex: `'./.eslint
If `cache: true` is used, the cache file is written to the `./node_modules/.cache` directory.
This is the recommended usage.

#### `formatter` (default: eslint stylish formatter)
#### `formatter` (default: 'stylish')

Loader accepts a function that will have one argument: an array of eslint messages (object).
The function must return the output as a string.
You can use official eslint formatters.
You can use official [eslint formatters](https://eslint.org/docs/user-guide/formatters/).

```js
module.exports = {
entry: "...",
entry: '...',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "eslint-loader",
loader: 'eslint-loader',
options: {
// several examples !

// default value
formatter: require("eslint/lib/formatters/stylish"),
formatter: 'stylish',

// community formatter
formatter: require("eslint-friendly-formatter"),
formatter: require('eslint-friendly-formatter'),

// custom formatter
formatter: function(results) {
@@ -138,35 +151,36 @@ module.exports = {

// you should return a string
// DO NOT USE console.*() directly !
return "OUTPUT";
}
}
}
]
}
return 'OUTPUT';
},
},
},
],
},
};
```

#### `eslintPath` (default: "eslint")
#### `eslintPath` (default: 'eslint')

Path to `eslint` instance that will be used for linting.
If the `eslintPath` is a folder like a official eslint, or specify a `formatter` option. now you dont have to install `eslint` .
Path to `eslint` instance that will be used for linting.
If the `eslintPath` is a folder like a official eslint, or specify a `formatter` option.
now you dont have to install `eslint`.

```js
module.exports = {
entry: "...",
entry: '...',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "eslint-loader",
loader: 'eslint-loader',
options: {
eslintPath: path.join(__dirname, "reusable-eslint")
}
}
]
}
eslintPath: path.join(__dirname, 'reusable-eslint'),
},
},
],
},
};
```

@@ -182,45 +196,46 @@ Loader will always return errors if this option is set to `true`.

```js
module.exports = {
entry: "...",
entry: '...',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "eslint-loader",
loader: 'eslint-loader',
options: {
emitError: true
}
}
]
}
emitError: true,
},
},
],
},
};
```

##### `emitWarning` (default: `false`)

Loader will always return warnings if option is set to `true`. If you're using hot module replacement, you may wish to enable this in development, or else updates will be skipped when there's an eslint error.
Loader will always return warnings if option is set to `true`. If you're using hot module replacement,
you may wish to enable this in development, or else updates will be skipped when there's an eslint error.

#### `quiet` (default: `false`)
##### `quiet` (default: `false`)

Loader will process and report errors only and ignore warnings if this option is set to true

```js
module.exports = {
entry: "...",
entry: '...',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "eslint-loader",
loader: 'eslint-loader',
options: {
quiet: true
}
}
]
}
quiet: true,
},
},
],
},
};
```

@@ -230,19 +245,19 @@ Loader will cause the module build to fail if there are any eslint warnings.

```js
module.exports = {
entry: "...",
entry: '...',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "eslint-loader",
loader: 'eslint-loader',
options: {
failOnWarning: true
}
}
]
}
failOnWarning: true,
},
},
],
},
};
```

@@ -252,71 +267,86 @@ Loader will cause the module build to fail if there are any eslint errors.

```js
module.exports = {
entry: "...",
entry: '...',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "eslint-loader",
loader: 'eslint-loader',
options: {
failOnError: true
}
}
]
}
failOnError: true,
},
},
],
},
};
```

##### `outputReport` (default: `false`)
##### `outputReport` (default: `null`)

Write the output of the errors to a file, for example a checkstyle xml file for use for reporting on Jenkins CI

The `filePath` is relative to the webpack config: output.path
You can pass in a different formatter for the output file, if none is passed in the default/configured formatter will be used
The `filePath` is an absolute path or relative to the webpack config: output.path
You can pass in a different formatter for the output file,
if none is passed in the default/configured formatter will be used

```js
module.exports = {
entry: "...",
entry: '...',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "eslint-loader",
loader: 'eslint-loader',
options: {
outputReport: {
filePath: "checkstyle.xml",
formatter: require("eslint/lib/formatters/checkstyle")
}
}
}
]
}
filePath: 'checkstyle.xml',
formatter: 'checkstyle',
},
},
},
],
},
};
```

## Gotchas

### NoErrorsPlugin

`NoErrorsPlugin` prevents webpack from outputting anything into a bundle. So even ESLint warnings
will fail the build. No matter what error settings are used for `eslint-loader`.
### NoEmitOnErrorsPlugin

So if you want to see ESLint warnings in console during development using `WebpackDevServer`
remove `NoErrorsPlugin` from webpack config.
`NoEmitOnErrorsPlugin` is now automatically enabled in webpack 4, when mode is either unset,
or set to production. So even ESLint warnings will fail the build.
No matter what error settings are used for `eslint-loader`, except if `emitWarning` enabled.

### Defining `configFile` or using `eslint -c path/.eslintrc`

Bear in mind that when you define `configFile`, `eslint` doesn't automatically look for
`.eslintrc` files in the directory of the file to be linted.
More information is available in official eslint documentation in section [_Using Configuration Files_](http://eslint.org/docs/user-guide/configuring#using-configuration-files).
More information is available in official eslint documentation in section
[_Using Configuration Files_](http://eslint.org/docs/user-guide/configuring#using-configuration-files).
See [#129](https://github.com/webpack-contrib/eslint-loader/issues/129).

---

## Changelog

[Changelog](CHANGELOG.md)

## License

[MIT](./LICENSE)

[npm]: https://img.shields.io/npm/v/eslint-loader.svg
[npm-url]: https://npmjs.com/package/eslint-loader
[node]: https://img.shields.io/node/v/eslint-loader.svg
[node-url]: https://nodejs.org
[deps]: https://david-dm.org/webpack-contrib/eslint-loader.svg
[deps-url]: https://david-dm.org/webpack-contrib/eslint-loader
[tests]: https://dev.azure.com/webpack-contrib/eslint-loader/_apis/build/status/webpack-contrib.eslint-loader?branchName=master
[tests-url]: https://dev.azure.com/webpack-contrib/eslint-loader/_build/latest?definitionId=4&branchName=master
[cover]: https://codecov.io/gh/webpack-contrib/eslint-loader/branch/master/graph/badge.svg
[cover-url]: https://codecov.io/gh/webpack-contrib/eslint-loader
[chat]: https://badges.gitter.im/webpack/webpack.svg
[chat-url]: https://gitter.im/webpack/webpack
[size]: https://packagephobia.now.sh/badge?p=eslint-loader
[size-url]: https://packagephobia.now.sh/result?p=eslint-loader
192 changes: 192 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
trigger:
- master
- next

jobs:
- job: Lint
pool:
vmImage: ubuntu-16.04
steps:
- task: NodeTool@0
inputs:
versionSpec: ^10.13.0
displayName: 'Install Node.js'
- task: Npm@1
inputs:
command: custom
customCommand: i -g npm@latest
displayName: 'Install latest NPM'
- script: |
node -v
npm -v
displayName: 'Print versions'
- task: Npm@1
inputs:
command: custom
customCommand: ci
displayName: 'Install dependencies'
- script: npm run lint
displayName: 'Run lint'
- script: npm run security
displayName: 'Run NPM audit'
- script: ./node_modules/.bin/commitlint-azure-pipelines
displayName: 'Run lint commit message'

- job: Linux
pool:
vmImage: ubuntu-16.04
strategy:
maxParallel: 4
matrix:
node-12:
node_version: ^12.0.0
webpack_version: latest
node-10:
node_version: ^10.13.0
webpack_version: latest
node-8:
node_version: ^8.9.0
webpack_version: latest
node-8-canary:
node_version: ^8.9.0
webpack_version: next
continue_on_error: true
steps:
- task: NodeTool@0
inputs:
versionSpec: $(node_version)
displayName: 'Install Node.js $(node_version)'
- task: Npm@1
inputs:
command: custom
customCommand: i -g npm@latest
displayName: 'Install latest NPM'
- script: |
node -v
npm -v
displayName: 'Print versions'
- task: Npm@1
inputs:
command: custom
customCommand: ci
displayName: 'Install dependencies'
- script: npm i webpack@$(webpack_version)
displayName: 'Install "webpack@$(webpack_version)"'
- script: npm run test:coverage -- --ci --reporters="default" --reporters="jest-junit" || $(continue_on_error)
displayName: 'Run tests with coverage'
- task: PublishTestResults@2
inputs:
testRunTitle: 'Linux with Node.js $(node_version)'
testResultsFiles: '**/junit.xml'
condition: succeededOrFailed()
displayName: 'Publish test results'
- script: curl -s https://codecov.io/bash | bash -s -- -t $(CODECOV_TOKEN)
condition: succeededOrFailed()
displayName: 'Submit coverage data to codecov'

- job: macOS
pool:
vmImage: macOS-10.14
strategy:
maxParallel: 4
matrix:
node-12:
node_version: ^12.0.0
webpack_version: latest
node-10:
node_version: ^10.13.0
webpack_version: latest
node-8:
node_version: ^8.9.0
webpack_version: latest
node-8-canary:
node_version: ^8.9.0
webpack_version: next
continue_on_error: true
steps:
- task: NodeTool@0
inputs:
versionSpec: $(node_version)
displayName: 'Install Node.js $(node_version)'
- task: Npm@1
inputs:
command: custom
customCommand: i -g npm@latest
displayName: 'Install latest NPM'
- script: |
node -v
npm -v
displayName: 'Print versions'
- task: Npm@1
inputs:
command: custom
customCommand: ci
displayName: 'Install dependencies'
- script: npm i webpack@$(webpack_version)
displayName: 'Install "webpack@$(webpack_version)"'
- script: npm run test:coverage -- --ci --reporters="default" --reporters="jest-junit" || $(continue_on_error)
displayName: 'Run tests with coverage'
- task: PublishTestResults@2
inputs:
testRunTitle: 'Linux with Node.js $(node_version)'
testResultsFiles: '**/junit.xml'
condition: succeededOrFailed()
displayName: 'Publish test results'
- script: curl -s https://codecov.io/bash | bash -s -- -t $(CODECOV_TOKEN)
condition: succeededOrFailed()
displayName: 'Submit coverage data to codecov'

- job: Windows
pool:
vmImage: windows-2019
strategy:
maxParallel: 4
matrix:
node-12:
node_version: ^12.0.0
webpack_version: latest
node-10:
node_version: ^10.13.0
webpack_version: latest
node-8:
node_version: ^8.9.0
webpack_version: latest
node-8-canary:
node_version: ^8.9.0
webpack_version: next
continue_on_error: true
steps:
- script: 'git config --global core.autocrlf input'
displayName: 'Config git core.autocrlf'
- checkout: self
- task: NodeTool@0
inputs:
versionSpec: $(node_version)
displayName: 'Install Node.js $(node_version)'
- task: Npm@1
inputs:
command: custom
customCommand: i -g npm@latest
displayName: 'Install latest NPM'
- script: |
node -v
npm -v
displayName: 'Print versions'
- task: Npm@1
inputs:
command: custom
customCommand: ci
displayName: 'Install dependencies'
- script: npm i webpack@$(webpack_version)
displayName: 'Install "webpack@$(webpack_version)"'
- script: npm run test:coverage -- --ci --reporters="default" --reporters="jest-junit" || $(continue_on_error)
displayName: 'Run tests with coverage'
- task: PublishTestResults@2
inputs:
testRunTitle: 'Linux with Node.js $(node_version)'
testResultsFiles: '**/junit.xml'
condition: succeededOrFailed()
displayName: 'Publish test results'
- script: curl -s https://codecov.io/bash | bash -s -- -t $(CODECOV_TOKEN)
condition: succeededOrFailed()
displayName: 'Submit coverage data to codecov'
19 changes: 19 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const MIN_BABEL_VERSION = 7;

module.exports = (api) => {
api.assertVersion(MIN_BABEL_VERSION);
api.cache(true);

return {
presets: [
[
'@babel/preset-env',
{
targets: {
node: '8.9.0',
},
},
],
],
};
};
3 changes: 3 additions & 0 deletions commitlint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
extends: ['@commitlint/config-conventional'],
};
6 changes: 6 additions & 0 deletions husky.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
hooks: {
'pre-commit': 'lint-staged',
'commit-msg': 'commitlint -E HUSKY_GIT_PARAMS',
},
};
279 changes: 0 additions & 279 deletions index.js

This file was deleted.

4 changes: 4 additions & 0 deletions lint-staged.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
'*.js': ['prettier --write', 'eslint --fix', 'git add'],
'*.{json,md,yml,css}': ['prettier --write', 'git add'],
};
11,891 changes: 11,891 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

118 changes: 70 additions & 48 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,61 +1,83 @@
{
"name": "eslint-loader",
"version": "2.2.1",
"description": "eslint loader (for webpack)",
"keywords": [
"lint",
"linter",
"eslint",
"loader",
"webpack"
],
"repository": "https://github.com/webpack-contrib/eslint-loader.git",
"author": "Maxime Thirouin",
"version": "3.0.0",
"description": "ESlint loader for webpack",
"license": "MIT",
"repository": "webpack-contrib/eslint-loader",
"author": "Maxime Thirouin",
"homepage": "https://github.com/webpack-contrib/eslint-loader",
"bugs": "https://github.com/webpack-contrib/eslint-loader/issues",
"main": "dist/cjs.js",
"engines": {
"node": ">= 8.9.0"
},
"scripts": {
"start": "npm run build -- -w",
"prebuild": "npm run clean",
"build": "cross-env NODE_ENV=production babel src -d dist --ignore \"src/**/*.test.js\" --copy-files",
"clean": "del-cli dist",
"commitlint": "commitlint --from=master",
"lint:prettier": "prettier \"{**/*,*}.{js,json,md,yml,css}\" --list-different",
"lint:js": "eslint --cache src test",
"lint": "npm-run-all -l -p \"lint:**\"",
"prepare": "npm run build",
"release": "standard-version",
"security": "npm audit",
"test:only": "cross-env NODE_ENV=test jest --env=node",
"test:watch": "cross-env NODE_ENV=test jest --env=node --watch",
"test:coverage": "cross-env NODE_ENV=test jest --env=node --collectCoverageFrom=\"src/**/*.js\" --coverage",
"pretest": "npm run lint",
"test": "cross-env NODE_ENV=test npm run test:coverage",
"defaults": "webpack-defaults"
},
"files": [
"index.js"
"dist"
],
"peerDependencies": {
"eslint": ">=1.6.0 <7.0.0",
"webpack": ">=2.0.0 <5.0.0"
"eslint": "^5.0.0 || ^6.0.0",
"webpack": "^4.0.0"
},
"dependencies": {
"loader-fs-cache": "^1.0.0",
"loader-utils": "^1.0.2",
"object-assign": "^4.0.1",
"object-hash": "^1.1.4",
"rimraf": "^2.6.1"
"loader-fs-cache": "^1.0.2",
"loader-utils": "^1.2.3",
"object-hash": "^1.3.1",
"schema-utils": "^2.1.0"
},
"devDependencies": {
"ava": "^0.17.0",
"eslint": "^6.0.1",
"eslint-config-i-am-meticulous": "^11.0.0",
"eslint-friendly-formatter": "^2.0.4",
"husky": "^0.14.3",
"@babel/cli": "^7.5.5",
"@babel/core": "^7.5.5",
"@babel/preset-env": "^7.5.5",
"@commitlint/cli": "^8.1.0",
"@commitlint/config-conventional": "^8.1.0",
"@webpack-contrib/defaults": "^5.0.2",
"@webpack-contrib/eslint-config-webpack": "^3.0.0",
"babel-eslint": "^10.0.2",
"babel-jest": "^24.9.0",
"chokidar": "^3.0.2",
"commitlint-azure-pipelines-cli": "^1.0.2",
"cross-env": "^5.2.0",
"del": "^5.0.0",
"del-cli": "^2.0.0",
"eslint": "^6.2.0",
"eslint-config-prettier": "^6.1.0",
"eslint-friendly-formatter": "^4.0.1",
"eslint-plugin-import": "^2.18.2",
"fs-extra": "^8.1.0",
"husky": "^3.0.4",
"jest": "^24.9.0",
"jest-junit": "^7.0.0",
"lint-staged": "^9.2.3",
"mkdirp": "^0.5.1",
"npmpub": "^4.0.1",
"prettier": "^1.13.7",
"pretty-quick": "^1.6.0",
"webpack": "^4.0.0"
},
"scripts": {
"precommit": "pretty-quick --staged",
"lint": "eslint .",
"ava": "ava",
"test": "npm run lint && npm run ava",
"release": "npmpub"
},
"eslintConfig": {
"extends": "eslint-config-i-am-meticulous",
"rules": {
"no-var": 0,
"prefer-const": 0
}
"npm-run-all": "^4.1.5",
"prettier": "^1.18.2",
"standard-version": "^7.0.0",
"webpack": "^4.39.2"
},
"ava": {
"files": [
"test/*.js"
],
"verbose": true
}
"keywords": [
"eslint",
"lint",
"linter",
"loader",
"webpack"
]
}
7 changes: 7 additions & 0 deletions src/ESLintError.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default class ESLintError extends Error {
constructor(messages) {
super(messages);
this.name = 'ESLintError';
this.stack = false;
}
}
186 changes: 186 additions & 0 deletions src/Linter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
import process from 'process';
import { isAbsolute, join } from 'path';
import { writeFileSync } from 'fs';

import { interpolateName } from 'loader-utils';

import ESLintError from './ESLintError';
import createEngine from './createEngine';

export default class Linter {
constructor(loaderContext, options) {
this.loaderContext = loaderContext;
this.options = options;
this.resourcePath = this.parseResourcePath();

const { CLIEngine, engine } = createEngine(options);
this.CLIEngine = CLIEngine;
this.engine = engine;
}

parseResourcePath() {
const cwd = process.cwd();
let { resourcePath } = this.loaderContext;

// remove cwd from resource path in case webpack has been started from project
// root, to allow having relative paths in .eslintignore
// istanbul ignore next
if (resourcePath.indexOf(cwd) === 0) {
resourcePath = resourcePath.substr(cwd.length + (cwd === '/' ? 0 : 1));
}

return resourcePath;
}

lint(content) {
try {
return this.engine.executeOnText(content, this.resourcePath, true);
} catch (_) {
this.getEmitter(false)(_);

return { src: content };
}
}

printOutput(data) {
const { options } = this;

// skip ignored file warning
if (this.constructor.skipIgnoredFileWarning(data)) {
return;
}

// quiet filter done now
// eslint allow rules to be specified in the input between comments
// so we can found warnings defined in the input itself
const res = this.filter(data);

// if enabled, use eslint auto-fixing where possible
if (options.fix) {
this.autoFix(res);
}

// skip if no errors or warnings
if (res.errorCount < 1 && res.warningCount < 1) {
return;
}

const results = this.parseResults(res);
const messages = options.formatter(results);

this.reportOutput(results, messages);
this.failOnErrorOrWarning(res, messages);

const emitter = this.getEmitter(res);
emitter(new ESLintError(messages));
}

static skipIgnoredFileWarning(res) {
return (
res.warningCount === 1 &&
res.results[0].messages[0] &&
res.results[0].messages[0].message &&
res.results[0].messages[0].message.indexOf('ignore') > 1
);
}

filter(data) {
const res = data;

// quiet filter done now
// eslint allow rules to be specified in the input between comments
// so we can found warnings defined in the input itself
if (this.options.quiet && res.warningCount) {
res.warningCount = 0;
res.results[0].warningCount = 0;
res.results[0].messages = res.results[0].messages.filter(
(message) => message.severity !== 1
);
}

return res;
}

autoFix(res) {
if (
res.results[0].output !== res.src ||
res.results[0].fixableErrorCount > 0 ||
res.results[0].fixableWarningCount > 0
) {
this.CLIEngine.outputFixes(res);
}
}

parseResults({ results }) {
// add filename for each results so formatter can have relevant filename
results.forEach((r) => {
// eslint-disable-next-line no-param-reassign
r.filePath = this.loaderContext.resourcePath;
});

return results;
}

reportOutput(results, messages) {
const { outputReport } = this.options;

if (!outputReport || !outputReport.filePath) {
return;
}

let content = messages;

// if a different formatter is passed in as an option use that
if (outputReport.formatter) {
content = outputReport.formatter(results);
}

let filePath = interpolateName(this.loaderContext, outputReport.filePath, {
content,
});

if (!isAbsolute(filePath)) {
filePath = join(
// eslint-disable-next-line no-underscore-dangle
this.loaderContext._compiler.options.output.path,
filePath
);
}

writeFileSync(filePath, content);
}

failOnErrorOrWarning({ errorCount, warningCount }, messages) {
const { failOnError, failOnWarning } = this.options;

if (failOnError && errorCount) {
throw new ESLintError(
`Module failed because of a eslint error.\n${messages}`
);
}

if (failOnWarning && warningCount) {
throw new ESLintError(
`Module failed because of a eslint warning.\n${messages}`
);
}
}

getEmitter({ errorCount }) {
const { options, loaderContext } = this;

// default behavior: emit error only if we have errors
let emitter = errorCount
? loaderContext.emitError
: loaderContext.emitWarning;

// force emitError or emitWarning if user want this
if (options.emitError) {
emitter = loaderContext.emitError;
} else if (options.emitWarning) {
emitter = loaderContext.emitWarning;
}

return emitter;
}
}
42 changes: 42 additions & 0 deletions src/cacheLoader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import createCache from 'loader-fs-cache';

import { version } from '../package.json';

const cache = createCache('eslint-loader');

export default function cacheLoader(linter, content, map) {
const { loaderContext, options, CLIEngine } = linter;
const callback = loaderContext.async();
const cacheIdentifier = JSON.stringify({
'eslint-loader': version,
eslint: CLIEngine.version,
});

cache(
{
directory: options.cache,
identifier: cacheIdentifier,
options,
source: content,
transform() {
return linter.lint(content);
},
},
(err, res) => {
// istanbul ignore next
if (err) {
return callback(err);
}

let error = err;

try {
linter.printOutput({ ...res, src: content });
} catch (e) {
error = e;
}

return callback(error, content, map);
}
);
}
3 changes: 3 additions & 0 deletions src/cjs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const loader = require('./index');

module.exports = loader.default;
17 changes: 17 additions & 0 deletions src/createEngine.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import objectHash from 'object-hash';

const engines = {};

export default function createEngine(options) {
const { CLIEngine } = require(options.eslintPath);
const hash = objectHash(options);

if (!engines[hash]) {
engines[hash] = new CLIEngine(options);
}

return {
CLIEngine,
engine: engines[hash],
};
}
46 changes: 46 additions & 0 deletions src/getOptions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import loaderUtils from 'loader-utils';
import validateOptions from 'schema-utils';

import schema from './options.json';

export default function getOptions(loaderContext) {
const options = {
eslintPath: 'eslint',
...loaderUtils.getOptions(loaderContext),
};

validateOptions(schema, options, {
name: 'ESLint Loader',
baseDataPath: 'options',
});

const { CLIEngine } = require(options.eslintPath);

options.formatter = getFormatter(CLIEngine, options.formatter);

if (options.outputReport && options.outputReport.formatter) {
options.outputReport.formatter = getFormatter(
CLIEngine,
options.outputReport.formatter
);
}

return options;
}

function getFormatter(CLIEngine, formatter) {
if (typeof formatter === 'function') {
return formatter;
}

// Try to get oficial formatter
if (typeof formatter === 'string') {
try {
return CLIEngine.getFormatter(formatter);
} catch (e) {
// ignored
}
}

return CLIEngine.getFormatter('stylish');
}
19 changes: 19 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import getOptions from './getOptions';
import Linter from './Linter';
import cacheLoader from './cacheLoader';

export default function loader(content, map) {
const options = getOptions(this);
const linter = new Linter(this, options);

this.cacheable();

// return early if cached
if (options.cache) {
cacheLoader(linter, content, map);
return;
}

linter.printOutput(linter.lint(content));
this.callback(null, content, map);
}
64 changes: 64 additions & 0 deletions src/options.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"type": "object",
"additionalProperties": true,
"properties": {
"fix": {
"description": "This option will enable ESLint autofix feature",
"type": "boolean"
},
"cache": {
"description": "This option will enable caching of the linting results into a file. This is particularly useful in reducing linting time when doing a full build.",
"anyOf": [{ "type": "boolean" }, { "type": "string" }]
},
"formatter": {
"description": "Loader accepts a function that will have one argument: an array of eslint messages (object). The function must return the output as a string.",
"anyOf": [{ "type": "string" }, { "instanceof": "Function" }]
},
"eslintPath": {
"description": "Path to `eslint` instance that will be used for linting. If the `eslintPath` is a folder like a official eslint, or specify a `formatter` option. now you dont have to install `eslint` .",
"type": "string"
},
"emitError": {
"description": "Loader will always return errors if this option is set to `true`.",
"type": "boolean"
},
"emitWarning": {
"description": "Loader will always return warnings if option is set to `true`. If you're using hot module replacement, you may wish to enable this in development, or else updates will be skipped when there's an eslint error.",
"type": "boolean"
},
"quiet": {
"description": "Loader will process and report errors only and ignore warnings if this option is set to true",
"type": "boolean"
},
"failOnWarning": {
"description": "Loader will cause the module build to fail if there are any eslint warnings.",
"type": "boolean"
},
"failOnError": {
"description": "Loader will cause the module build to fail if there are any eslint errors.",
"type": "boolean"
},
"outputReport": {
"description": "Write the output of the errors to a file, for example a checkstyle xml file for use for reporting on Jenkins CI",
"anyOf": [
{
"type": "boolean"
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"filePath": {
"description": "The `filePath` is relative to the webpack config: output.path",
"anyOf": [{ "type": "string" }]
},
"formatter": {
"description": "You can pass in a different formatter for the output file, if none is passed in the default/configured formatter will be used",
"anyOf": [{ "type": "string" }, { "instanceof": "Function" }]
}
}
}
]
}
}
}
56 changes: 0 additions & 56 deletions test/autofix-stop.js

This file was deleted.

43 changes: 43 additions & 0 deletions test/autofix-stop.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { copySync, removeSync } from 'fs-extra';
import webpack from 'webpack';
import chokidar from 'chokidar';

import conf from './utils/conf';

describe('autofix stop', () => {
const entry = './test/fixtures/nonfixable-clone.js';
let changed = false;
let watcher;

beforeAll(() => {
copySync('./test/fixtures/nonfixable.js', entry);

watcher = chokidar.watch(entry);
watcher.on('change', () => {
changed = true;
});
});

afterAll(() => {
watcher.close();
removeSync(entry);
});

it('should not change file if there are no fixable errors/warnings', (done) => {
const compiler = webpack(
conf(
{
entry,
},
{
fix: true,
}
)
);

compiler.run(() => {
expect(changed).toBe(false);
done();
});
});
});
47 changes: 0 additions & 47 deletions test/autofix.js

This file was deleted.

35 changes: 35 additions & 0 deletions test/autofix.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { copySync, removeSync } from 'fs-extra';
import webpack from 'webpack';

import conf from './utils/conf';

describe('autofix stop', () => {
const entry = './test/fixtures/fixable-clone.js';

beforeAll(() => {
copySync('./test/fixtures/fixable.js', entry);
});

afterAll(() => {
removeSync(entry);
});

it('should not throw error if file ok after auto-fixing', (done) => {
const compiler = webpack(
conf(
{
entry,
},
{
fix: true,
}
)
);

compiler.run((err, stats) => {
expect(stats.hasWarnings()).toBe(false);
expect(stats.hasErrors()).toBe(false);
done();
});
});
});
268 changes: 0 additions & 268 deletions test/cache.js

This file was deleted.

170 changes: 170 additions & 0 deletions test/cache.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import { join } from 'path';

import { readdirSync, removeSync } from 'fs-extra';
import mkdirp from 'mkdirp';
import webpack from 'webpack';

jest.setTimeout(30000);

const defaultCacheDir = join(__dirname, '../node_modules/.cache/eslint-loader');
const cacheDir = join(__dirname, 'output/cache/cachefiles');
const outputDir = join(__dirname, 'output/cache');
const eslintLoader = join(__dirname, '../src/index');
const globalConfig = {
entry: join(__dirname, 'fixtures/cache.js'),
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: eslintLoader,
},
],
},
};

function createTestDirectory(dir) {
const directory = join(dir, 'cache');

removeSync(directory);
mkdirp.sync(directory);

return directory;
}

describe('cache', () => {
let directory;
let cache;

beforeEach(() => {
directory = createTestDirectory(outputDir);
cache = createTestDirectory(cacheDir);
removeSync(defaultCacheDir);
});

afterEach(() => {
removeSync(cache);
removeSync(directory);
});

it('should output files to cache directory', (done) => {
const compiler = webpack({
...globalConfig,
output: {
path: directory,
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: `${eslintLoader}?cache=${cache}`,
},
],
},
});
compiler.run(() => {
const files = readdirSync(cache);
expect(files.length).toBeGreaterThan(0);
done();
});
});

it('should output files to standard cache dir if set to true in query', (done) => {
const compiler = webpack({
...globalConfig,
output: {
path: directory,
},
module: {
rules: [
{
test: /\.jsx?/,
exclude: /node_modules/,
use: `${eslintLoader}?cache=true`,
},
],
},
});
compiler.run(() => {
const files = readdirSync(defaultCacheDir).filter((file) =>
/\b[0-9a-f]{5,40}\.json\.gz\b/.test(file)
);
expect(files.length).toBeGreaterThan(0);
done();
});
});

it('should read from cache directory if cached file exists', (done) => {
const compiler = webpack({
...globalConfig,
output: {
path: directory,
},
module: {
rules: [
{
test: /\.jsx?/,
exclude: /node_modules/,
use: `${eslintLoader}?cache=${cache}`,
},
],
},
});
compiler.run(() => {
const files = readdirSync(cache);
expect(files.length).toBe(3);
done();
});
});

it('should generate a new file if the identifier changes', (done) => {
const configs = [
{
...globalConfig,
output: {
path: directory,
},
module: {
rules: [
{
test: /\.jsx?/,
exclude: /node_modules/,
use: `${eslintLoader}?cache=${cache}&cacheIdentifier=a`,
},
],
},
},
{
...globalConfig,
output: {
path: directory,
},
module: {
rules: [
{
test: /\.jsx?/,
exclude: /node_modules/,
use: `${eslintLoader}?cache=${cache}&cacheIdentifier=b`,
},
],
},
},
];

let counter = configs.length;

configs.forEach((config) => {
const compiler = webpack(config);
compiler.run(() => {
counter -= 1;

if (!counter) {
const files = readdirSync(cache);
expect(files.length).toBe(6);
done();
}
});
});
});
});
8 changes: 8 additions & 0 deletions test/cjs.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import EslintLoader from '../src';
import CJSEslintLoader from '../src/cjs';

describe('cjs', () => {
it('should exported plugin', () => {
expect(CJSEslintLoader).toEqual(EslintLoader);
});
});
25 changes: 0 additions & 25 deletions test/error.js

This file was deleted.

18 changes: 18 additions & 0 deletions test/error.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import webpack from 'webpack';

import conf from './utils/conf';

describe('error', () => {
it('should return error if file is bad', (done) => {
const compiler = webpack(
conf({
entry: './test/fixtures/error.js',
})
);

compiler.run((err, stats) => {
expect(stats.hasErrors()).toBe(true);
done();
});
});
});
39 changes: 0 additions & 39 deletions test/eslint-path.js

This file was deleted.

26 changes: 26 additions & 0 deletions test/eslint-path.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { join } from 'path';

import webpack from 'webpack';

import conf from './utils/conf';

describe('eslint path', () => {
it('should use another instance of eslint via eslintPath config', (done) => {
const compiler = webpack(
conf(
{
entry: './test/fixtures/good.js',
},
{
eslintPath: join(__dirname, 'mock/eslint'),
}
)
);

compiler.run((err, stats) => {
expect(stats.hasErrors()).toBe(true);
expect(stats.compilation.errors[0].message).toContain('Fake error');
done();
});
});
});
29 changes: 0 additions & 29 deletions test/eslintignore.js

This file was deleted.

23 changes: 23 additions & 0 deletions test/eslintignore.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import webpack from 'webpack';

import conf from './utils/conf';

describe('eslintignore', () => {
it('should ignores files present in .eslintignore', (done) => {
const compiler = webpack(
conf(
{
entry: './test/fixtures/ignore.js',
},
{
ignore: true,
}
)
);

compiler.run((err, stats) => {
expect(stats.hasWarnings()).toBe(false);
done();
});
});
});
62 changes: 0 additions & 62 deletions test/fail-on-error-async-and-emit.js

This file was deleted.

44 changes: 44 additions & 0 deletions test/fail-on-error.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import webpack from 'webpack';

import conf from './utils/conf';

describe('fail on error', () => {
it('should emits errors', (done) => {
const compiler = webpack(
conf(
{
cache: true,
entry: './test/fixtures/error.js',
},
{
failOnError: true,
cache: true,
}
)
);

compiler.run((err, stats) => {
expect(stats.hasErrors()).toBe(true);
done();
});
});

it('should correctly indentifies a success', (done) => {
const compiler = webpack(
conf(
{
cache: true,
entry: './test/fixtures/good.js',
},
{
failOnError: true,
cache: true,
}
)
);
compiler.run((err, stats) => {
expect(stats.hasErrors()).toBe(false);
done();
});
});
});
44 changes: 44 additions & 0 deletions test/fail-on-warning.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import webpack from 'webpack';

import conf from './utils/conf';

describe('fail on warning', () => {
it('should emits errors', (done) => {
const compiler = webpack(
conf(
{
cache: true,
entry: './test/fixtures/warn.js',
},
{
failOnWarning: true,
cache: true,
}
)
);

compiler.run((err, stats) => {
expect(stats.hasErrors()).toBe(true);
done();
});
});

it('should correctly indentifies a success', (done) => {
const compiler = webpack(
conf(
{
cache: true,
entry: './test/fixtures/good.js',
},
{
failOnWarning: true,
cache: true,
}
)
);
compiler.run((err, stats) => {
expect(stats.hasErrors()).toBe(false);
done();
});
});
});
2 changes: 2 additions & 0 deletions test/fixtures/fixable.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use strict'

function foo() {
return true
}
4 changes: 1 addition & 3 deletions test/fixtures/good-semi.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
"use strict"

function test() {
return "value"
return 'value'
}

test()
2 changes: 0 additions & 2 deletions test/fixtures/good.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
"use strict"

function test() {
return "value"
}
2 changes: 1 addition & 1 deletion test/fixtures/ignore.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// this file should be totally ignore since it's present in .eslintignore
var -dasdas;
var -dasdas;
4 changes: 2 additions & 2 deletions test/fixtures/warn.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
/* eslint no-unused-vars: 1 */
var foo = this
/* eslint no-unused-vars: warn */
const foo = this
32 changes: 0 additions & 32 deletions test/force-emit-error.js

This file was deleted.

24 changes: 24 additions & 0 deletions test/force-emit-error.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import webpack from 'webpack';

import conf from './utils/conf';

describe('force emit error', () => {
it('should force to emit error', (done) => {
const compiler = webpack(
conf(
{
entry: './test/fixtures/warn.js',
},
{
emitError: true,
}
)
);

compiler.run((err, stats) => {
expect(stats.hasWarnings()).toBe(false);
expect(stats.hasErrors()).toBe(true);
done();
});
});
});
32 changes: 0 additions & 32 deletions test/force-emit-warning.js

This file was deleted.

24 changes: 24 additions & 0 deletions test/force-emit-warning.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import webpack from 'webpack';

import conf from './utils/conf';

describe('force emit warning', () => {
it('should force to emit warning', (done) => {
const compiler = webpack(
conf(
{
entry: './test/fixtures/error.js',
},
{
emitWarning: true,
}
)
);

compiler.run((err, stats) => {
expect(stats.hasWarnings()).toBe(true);
expect(stats.hasErrors()).toBe(false);
done();
});
});
});
37 changes: 0 additions & 37 deletions test/formatter-custom.js

This file was deleted.

41 changes: 41 additions & 0 deletions test/formatter-custom.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import webpack from 'webpack';

import conf from './utils/conf';

describe('formatter eslint', () => {
it('should use custom formatter as function', (done) => {
const compiler = webpack(
conf(
{
entry: './test/fixtures/error.js',
},
{
formatter: require('eslint-friendly-formatter'),
}
)
);

compiler.run((err, stats) => {
expect(stats.compilation.errors[0].message).toBeTruthy();
done();
});
});

it('should use custom formatter as string', (done) => {
const compiler = webpack(
conf(
{
entry: './test/fixtures/error.js',
},
{
formatter: 'eslint-friendly-formatter',
}
)
);

compiler.run((err, stats) => {
expect(stats.compilation.errors[0].message).toBeTruthy();
done();
});
});
});
29 changes: 0 additions & 29 deletions test/formatter-eslint.js

This file was deleted.

18 changes: 18 additions & 0 deletions test/formatter-eslint.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import webpack from 'webpack';

import conf from './utils/conf';

describe('formatter eslint', () => {
it('should use eslint formatter', (done) => {
const compiler = webpack(
conf({
entry: './test/fixtures/error.js',
})
);

compiler.run((err, stats) => {
expect(stats.compilation.errors[0].message).toBeTruthy();
done();
});
});
});
61 changes: 0 additions & 61 deletions test/formatter-multiple-entries.js

This file was deleted.

43 changes: 43 additions & 0 deletions test/formatter-multiple-entries.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { basename } from 'path';

import { readFileSync } from 'fs-extra';
import { CLIEngine } from 'eslint';
import webpack from 'webpack';

import conf from './utils/conf';

describe('formatter multiple entries', () => {
it('should be configured to write multiple eslint result files', (done) => {
const formatter = CLIEngine.getFormatter('checkstyle');
const outputFilename = 'outputReport-[name].txt';
const config = conf(
{
entry: [
'./test/fixtures/error-multi-two.js',
'./test/fixtures/error-multi-one.js',
'./test/fixtures/error-multi.js',
],
},
{
formatter,
outputReport: {
filePath: outputFilename,
formatter,
},
}
);

const compiler = webpack(config);

compiler.run((err, stats) => {
stats.compilation.errors.forEach((e) => {
const name = basename(e.module.resource, '.js');
const filename = `${config.output.path}outputReport-${name}.txt`;
const contents = readFileSync(filename, 'utf8');
expect(e.error.message).toBe(contents);
});

done();
});
});
});
23 changes: 23 additions & 0 deletions test/formatter-official.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import webpack from 'webpack';

import conf from './utils/conf';

describe('formatter official', () => {
it('should use official formatter', (done) => {
const compiler = webpack(
conf(
{
entry: './test/fixtures/error.js',
},
{
formatter: 'table',
}
)
);

compiler.run((err, stats) => {
expect(stats.compilation.errors[0].message).toBeTruthy();
done();
});
});
});
61 changes: 0 additions & 61 deletions test/formatter-write.js

This file was deleted.

59 changes: 59 additions & 0 deletions test/formatter-write.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { join } from 'path';

import { readFileSync } from 'fs-extra';
import { CLIEngine } from 'eslint';
import webpack from 'webpack';

import conf from './utils/conf';

describe('formatter write', () => {
it('should configured to write eslint results to a file (relative path)', (done) => {
const outputFilename = 'outputReport-relative.txt';
const config = conf(
{
entry: './test/fixtures/error.js',
},
{
formatter: CLIEngine.getFormatter('checkstyle'),
outputReport: {
filePath: outputFilename,
},
}
);

const compiler = webpack(config);

compiler.run((err, stats) => {
const filePath = `${config.output.path}${outputFilename}`;
const contents = readFileSync(filePath, 'utf8');

expect(stats.compilation.errors[0].error.message).toBe(contents);
done();
});
});

it('should configured to write eslint results to a file (absolute path)', (done) => {
const outputFilename = 'outputReport-absolute.txt';
const outputFilepath = join(__dirname, 'output', outputFilename);
const config = conf(
{
entry: './test/fixtures/error.js',
},
{
formatter: CLIEngine.getFormatter('checkstyle'),
outputReport: {
filePath: outputFilepath,
},
}
);

const compiler = webpack(config);

compiler.run((err, stats) => {
const contents = readFileSync(outputFilepath, 'utf8');

expect(stats.compilation.errors[0].error.message).toBe(contents);
done();
});
});
});
38 changes: 20 additions & 18 deletions test/mock/eslint/index.js
Original file line number Diff line number Diff line change
@@ -1,47 +1,47 @@
function CLIEngine() {}

CLIEngine.prototype.executeOnText = function() {
CLIEngine.prototype.executeOnText = function executeOnText() {
return {
results: [
{
filePath: "",
filePath: '',
messages: [
{
ruleId: "no-undef",
ruleId: 'no-undef',
severity: 2,
message: "Fake error",
message: 'Fake error',
line: 1,
column: 11,
nodeType: "Identifier",
source: "var foo = stuff"
}
nodeType: 'Identifier',
source: 'var foo = stuff',
},
],
errorCount: 2,
warningCount: 0,
fixableErrorCount: 0,
fixableWarningCount: 0,
source: ""
}
source: '',
},
],
errorCount: 2,
warningCount: 0,
fixableErrorCount: 0,
fixableWarningCount: 0
fixableWarningCount: 0,
};
};

CLIEngine.prototype.getFormatter = function(format) {
const resolvedFormatName = format || "stylish";
CLIEngine.prototype.getFormatter = function getFormatter(format) {
const resolvedFormatName = format || 'stylish';

if (typeof resolvedFormatName !== "string") {
if (typeof resolvedFormatName !== 'string') {
return null;
}

const eslintVersion = require("./package.json").version;
const eslintVersion = require('./package.json').version;
const formatterPath =
eslintVersion >= "6.0.0"
? "./lib/cli-engine/formatters/stylish"
: "./lib/formatters/stylish";
eslintVersion >= '6.0.0'
? './lib/cli-engine/formatters/stylish'
: './lib/formatters/stylish';

try {
return require(formatterPath);
@@ -51,6 +51,8 @@ CLIEngine.prototype.getFormatter = function(format) {
}
};

CLIEngine.getFormatter = CLIEngine.prototype.getFormatter;

module.exports = {
CLIEngine: CLIEngine
CLIEngine,
};
2 changes: 1 addition & 1 deletion test/mock/eslint/lib/cli-engine/formatters/stylish.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module.exports = function(result) {
module.exports = function formatter(result) {
return JSON.stringify(result);
};
6 changes: 3 additions & 3 deletions test/mock/eslint/lib/formatters/stylish.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module.exports = function(result) {
return JSON.stringify(result)
}
module.exports = function formatter(result) {
return JSON.stringify(result);
};
Loading