Skip to content

Commit

Permalink
fix(eslint): do not flush existing errors on changing file (#55)
Browse files Browse the repository at this point in the history
  • Loading branch information
fi3ework committed Jul 25, 2021
1 parent 9e46176 commit 4f7abbe
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 19 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
"@types/babel__code-frame": "^7.0.2",
"@types/debug": "^4.1.5",
"@types/fs-extra": "^9.0.11",
"@types/glob": "^7.1.3",
"@types/jest": "^26.0.23",
"@types/node": "^14.14.31",
"@types/prompts": "^2.0.13",
Expand Down
1 change: 0 additions & 1 deletion packages/vite-plugin-checker/src/Checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ export interface CheckerMeta<T extends BuildInCheckerNames> {
export abstract class Checker<T extends BuildInCheckerNames> implements CheckerMeta<T> {
public static watcher: chokidar.FSWatcher = chokidar.watch([], {
ignored: (path: string) => path.includes('node_modules'),
ignoreInitial: false,
})

public name: string
Expand Down
50 changes: 37 additions & 13 deletions packages/vite-plugin-checker/src/checkers/eslint/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import type { ErrorPayload } from 'vite'

const createDiagnostic: CreateDiagnostic<'eslint'> = (pluginConfig) => {
let overlay = true // Vite defaults to true
let currErr: ErrorPayload['err'] | null = null

return {
config: async ({ hmr }) => {
Expand All @@ -32,6 +31,7 @@ const createDiagnostic: CreateDiagnostic<'eslint'> = (pluginConfig) => {

const extensions = pluginConfig.eslint.extensions ?? ['.js']
const eslint = new ESLint({
cwd: root,
extensions,
})
invariant(pluginConfig.eslint, 'config.eslint should not be `false`')
Expand All @@ -45,21 +45,14 @@ const createDiagnostic: CreateDiagnostic<'eslint'> = (pluginConfig) => {
? [pluginConfig.eslint.files]
: pluginConfig.eslint.files

const diagnosticsCache: Record<string, NormalizedDiagnostic[]> = {}
let diagnosticsCache: NormalizedDiagnostic[] = []

Checker.watcher.add(paths)
Checker.watcher.on('all', async (event, filePath) => {
if (!['add', 'change'].includes(event)) return
if (!extensions.includes(path.extname(filePath))) return

const diagnostics = await eslint.lintFiles(filePath)
const normalized = diagnostics.map((p) => normalizeEslintDiagnostic(p)).flat(1)
normalized.forEach((n) => {
const dispatchDiagnostics = () => {
diagnosticsCache.forEach((n) => {
console.log(diagnosticToTerminalLog(n, 'ESLint'))
})
diagnosticsCache[filePath] = normalized

const lastErr = normalized[0]
const lastErr = diagnosticsCache[0]

if (!lastErr) return

Expand All @@ -72,6 +65,38 @@ const createDiagnostic: CreateDiagnostic<'eslint'> = (pluginConfig) => {
},
})
}
}

const handleFileChange = async (filePath: string, type: 'change' | 'unlink') => {
if (!extensions.includes(path.extname(filePath))) return

if (type === 'unlink') {
const absPath = path.resolve(root, filePath)
diagnosticsCache = diagnosticsCache.filter((d) => d.id !== absPath)
} else if (type === 'change') {
const diagnosticsOfChangedFile = await eslint.lintFiles(filePath)
const newDiagnostics = diagnosticsOfChangedFile
.map((d) => normalizeEslintDiagnostic(d))
.flat(1)
const absPath = diagnosticsOfChangedFile[0].filePath
diagnosticsCache = diagnosticsCache.filter((d) => d.id !== absPath).concat(newDiagnostics)
}

dispatchDiagnostics()
}

// initial lint
const diagnostics = await eslint.lintFiles(paths)
diagnosticsCache = diagnostics.map((p) => normalizeEslintDiagnostic(p)).flat(1)
dispatchDiagnostics()

// watch lint
Checker.watcher.add(paths)
Checker.watcher.on('change', async (filePath) => {
handleFileChange(filePath, 'change')
})
Checker.watcher.on('unlink', async (filePath) => {
handleFileChange(filePath, 'unlink')
})
},
}
Expand Down Expand Up @@ -104,7 +129,6 @@ export class EslintChecker extends Checker<'eslint'> {
public init() {
const createServeAndBuild = super.initMainThread()
module.exports.createServeAndBuild = createServeAndBuild

super.initWorkerThread()
}
}
Expand Down
16 changes: 16 additions & 0 deletions playground/vanilla-ts/__tests__/__snapshots__/test.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,22 @@ exports[`eslint serve get initial error and subsequent error 5`] = `
"
`;
exports[`eslint serve get initial error and subsequent error 6`] = `
"HH:MM:SS AM [vite] page reload src/text.ts
ERROR(ESLint) Unexpected var, use let or const instead.
FILE <PROJECT_ROOT>/temp/vanilla-ts/src/main.ts:3:1
1 | import { text } from './text'
2 |
> 3 | var hello = 'Hello~'
| ^^^^^^^^^^^^^^^^^^^^
4 |
5 | const rootDom = document.querySelector('#root')!
6 | rootDom.innerHTML = hello + text
"
`;
exports[`eslint serve overlay: false 1`] = `
"
vite v2.3.8 dev server running at:
Expand Down
9 changes: 7 additions & 2 deletions playground/vanilla-ts/__tests__/test.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,16 @@ describe('eslint', () => {
expect(frame1).toMatchSnapshot()
expect(stripedLog).toMatchSnapshot()

console.log('-- edit file --')
console.log('-- edit error file --')
resetTerminalLog()
editFile('src/main.ts', (code) => code.replace(`'Hello'`, `'Hello~'`))
await sleep(process.env.CI ? 5000 : 2000)
await pollingUntil(getHmrOverlay, (dom) => !!dom)
expect(stripedLog).toMatchSnapshot()

console.log('-- edit non error file --')
resetTerminalLog()
editFile('src/text.ts', (code) => code.replace(`Vanilla`, `vanilla`))
await sleep(process.env.CI ? 5000 : 2000)
expect(stripedLog).toMatchSnapshot()
})

Expand Down
2 changes: 0 additions & 2 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 4f7abbe

Please sign in to comment.