Skip to content

Commit

Permalink
feat: support log level of ESLint
Browse files Browse the repository at this point in the history
  • Loading branch information
fi3ework committed Feb 6, 2022
1 parent d59030c commit 256ba5a
Show file tree
Hide file tree
Showing 34 changed files with 412 additions and 112 deletions.
4 changes: 2 additions & 2 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ node_modules
playground/react-ts
playground/vue2-vls
playground/vue3-vue-tsc
playground/vanilla-ts/__tests__
playground/vanilla-ts/dist
playground/eslint/__tests__
playground/eslint/dist
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ _coming soon._

### config.eslint

<<<<<<< HEAD
<<<<<<< HEAD
| field | Type | Default value | Description |
| :------------------- | ---------------------------------------------------------------------------------------------------------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
Expand All @@ -192,6 +193,13 @@ _coming soon._
| lintCommand | `string` | This value is required | `lintCommand` will be executed at build mode, and will also be used as default config for dev mode when `eslint.dev.eslint` is nullable. |
| `dev.eslint` | [`ESLint.Options`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/eslint/index.d.ts) | `undefined` | You can override the options of the translated from `lintCommand`. Config priority: `const eslint = new ESLint({cwd: root, ...translatedOptions, ...pluginConfig.eslint.dev, })`. |
>>>>>>> refactor: change ESLint property
=======
| field | Type | Default value | Description |
| :------------------- | ---------------------------------------------------------------------------------------------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| lintCommand | `string` | This value is required | `lintCommand` will be executed at build mode, and will also be used as default config for dev mode when `eslint.dev.eslint` is nullable. |
| `dev.overrideConfig` | [`ESLint.Options`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/eslint/index.d.ts) | `undefined` | **(Only in dev mode)** You can override the options of the translated from `lintCommand`. Config priority: `const eslint = new ESLint({cwd: root, ...translatedOptions, ...pluginConfig.eslint.dev, })`. |
| dev.logLevel | `('error' \| 'warning')[]` | `['error', 'warning']` | **(Only in dev mode)** Which level of ESLint should be emitted to terminal and overlay in dev mode |
>>>>>>> feat: support log level of ESLint
## Playground

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"chalk": "^4.1.1",
"conventional-changelog-cli": "^2.1.1",
"cross-env": "^7.0.3",
"eslint": "^7.20.0",
"eslint": "^7.28.0",
"eslint-config-alloy": "^3.10.0",
"eslint-plugin-svelte3": "^3.4.0",
"execa": "^5.1.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

exports[`logger diagnosticToTerminalLog get error 1`] = `
" ERROR(ESLint) Unexpected var, use let or const instead.
FILE /Users/vite-plugin-checker/playground/vanilla-ts/src/main.ts:3:1
FILE /Users/vite-plugin-checker/playground/eslint/src/main.ts:3:1

1 | import { text } from './text'
2 |
Expand All @@ -16,7 +16,7 @@ exports[`logger diagnosticToTerminalLog get error 1`] = `

exports[`logger diagnosticToTerminalLog get warning 1`] = `
" WARNING(ESLint) Unexpected var, use let or const instead.
FILE /Users/vite-plugin-checker/playground/vanilla-ts/src/main.ts:3:1
FILE /Users/vite-plugin-checker/playground/eslint/src/main.ts:3:1

1 | import { text } from './text'
2 |
Expand All @@ -40,7 +40,7 @@ Array [
  5 |
  6 | const rootDom = document.querySelector('#root')!",
"conclusion": "",
"id": "/Users/vite-plugin-checker/playground/vanilla-ts/src/main.ts",
"id": "/Users/vite-plugin-checker/playground/eslint/src/main.ts",
"level": 1,
"loc": Object {
"end": Object {
Expand Down Expand Up @@ -71,7 +71,7 @@ Array [
  6 | const rootDom = document.querySelector('#root')!
  7 | rootDom.innerHTML = hello + text",
"conclusion": "",
"id": "/Users/vite-plugin-checker/playground/vanilla-ts/src/main.ts",
"id": "/Users/vite-plugin-checker/playground/eslint/src/main.ts",
"level": 1,
"loc": Object {
"end": Object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const error1: NormalizedDiagnostic = {
" \u001b[0m \u001b[90m 1 |\u001b[39m \u001b[36mimport\u001b[39m { text } \u001b[36mfrom\u001b[39m \u001b[32m'./text'\u001b[39m\u001b[0m\n \u001b[0m \u001b[90m 2 |\u001b[39m\u001b[0m\n \u001b[0m\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 3 |\u001b[39m \u001b[36mvar\u001b[39m hello \u001b[33m=\u001b[39m \u001b[32m'Hello'\u001b[39m\u001b[0m\n \u001b[0m \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\u001b[31m\u001b[1m^\u001b[22m\u001b[39m\u001b[31m\u001b[1m^\u001b[22m\u001b[39m\u001b[31m\u001b[1m^\u001b[22m\u001b[39m\u001b[31m\u001b[1m^\u001b[22m\u001b[39m\u001b[31m\u001b[1m^\u001b[22m\u001b[39m\u001b[31m\u001b[1m^\u001b[22m\u001b[39m\u001b[31m\u001b[1m^\u001b[22m\u001b[39m\u001b[31m\u001b[1m^\u001b[22m\u001b[39m\u001b[31m\u001b[1m^\u001b[22m\u001b[39m\u001b[31m\u001b[1m^\u001b[22m\u001b[39m\u001b[31m\u001b[1m^\u001b[22m\u001b[39m\u001b[31m\u001b[1m^\u001b[22m\u001b[39m\u001b[31m\u001b[1m^\u001b[22m\u001b[39m\u001b[31m\u001b[1m^\u001b[22m\u001b[39m\u001b[31m\u001b[1m^\u001b[22m\u001b[39m\u001b[31m\u001b[1m^\u001b[22m\u001b[39m\u001b[31m\u001b[1m^\u001b[22m\u001b[39m\u001b[31m\u001b[1m^\u001b[22m\u001b[39m\u001b[0m\n \u001b[0m \u001b[90m 4 |\u001b[39m\u001b[0m\n \u001b[0m \u001b[90m 5 |\u001b[39m \u001b[36mconst\u001b[39m rootDom \u001b[33m=\u001b[39m document\u001b[33m.\u001b[39mquerySelector(\u001b[32m'#root'\u001b[39m)\u001b[33m!\u001b[39m\u001b[0m\n \u001b[0m \u001b[90m 6 |\u001b[39m rootDom\u001b[33m.\u001b[39minnerHTML \u001b[33m=\u001b[39m hello \u001b[33m+\u001b[39m text\u001b[0m",
stripedCodeFrame:
" 1 | import { text } from './text'\n 2 |\n > 3 | var hello = 'Hello'\n | ^^^^^^^^^^^^^^^^^^^\n 4 |\n 5 | const rootDom = document.querySelector('#root')!\n 6 | rootDom.innerHTML = hello + text",
id: '/Users/vite-plugin-checker/playground/vanilla-ts/src/main.ts',
id: '/Users/vite-plugin-checker/playground/eslint/src/main.ts',
checker: 'ESLint',
loc: { start: { line: 3, column: 1 }, end: { line: 3, column: 20 } },
level: 1,
Expand All @@ -17,7 +17,7 @@ export const error1: NormalizedDiagnostic = {
export const warning1: NormalizedDiagnostic = { ...error1, level: 0 }

export const eslintResult1: ESLint.LintResult = {
filePath: '/Users/vite-plugin-checker/playground/vanilla-ts/src/main.ts',
filePath: '/Users/vite-plugin-checker/playground/eslint/src/main.ts',
messages: [
{
ruleId: 'no-var',
Expand Down
28 changes: 21 additions & 7 deletions packages/vite-plugin-checker/src/checkers/eslint/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@ import invariant from 'tiny-invariant'
import { parentPort } from 'worker_threads'

import { Checker } from '../../Checker'
import { FileDiagnosticManager } from '../../FileDiagnosticManager'
import {
consoleLog,
diagnosticToTerminalLog,
diagnosticToViteError,
toViteCustomPayload,
diagnosticToRuntimeError,
filterLogLevel,
normalizeEslintDiagnostic,
toViteCustomPayload,
} from '../../logger'
import { ACTION_TYPES } from '../../types'
import { ACTION_TYPES, DiagnosticLevel } from '../../types'
import { translateOptions } from './cli'
import { FileDiagnosticManager } from '../../FileDiagnosticManager'

const manager = new FileDiagnosticManager()

Expand All @@ -34,14 +35,27 @@ const createDiagnostic: CreateDiagnostic<'eslint'> = (pluginConfig) => {
const options = optionator.parse(pluginConfig.eslint.lintCommand)
const translatedOptions = translateOptions(options) as ESLint.Options

const logLevel = (() => {
if (typeof pluginConfig.eslint !== 'object') return undefined
const userLogLevel = pluginConfig.eslint.dev?.logLevel
if (!userLogLevel) return undefined
const map = {
error: DiagnosticLevel.Error,
warning: DiagnosticLevel.Warning,
} as const

return userLogLevel.map((l) => map[l])
})()

const eslint = new ESLint({
cwd: root,
...translatedOptions,
...pluginConfig.eslint.dev,
...pluginConfig.eslint.dev?.overrideConfig,
})

const dispatchDiagnostics = () => {
const diagnostics = manager.getDiagnostics()
const diagnostics = filterLogLevel(manager.getDiagnostics(), logLevel)

diagnostics.forEach((d) => {
consoleLog(diagnosticToTerminalLog(d, 'ESLint'))
})
Expand All @@ -51,7 +65,7 @@ const createDiagnostic: CreateDiagnostic<'eslint'> = (pluginConfig) => {
type: ACTION_TYPES.overlayError,
payload: toViteCustomPayload(
'eslint',
diagnostics.map((d) => diagnosticToViteError(d))
diagnostics.map((d) => diagnosticToRuntimeError(d))
),
})
}
Expand Down
22 changes: 11 additions & 11 deletions packages/vite-plugin-checker/src/checkers/typescript/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ import { Checker } from '../../Checker'
import {
consoleLog,
diagnosticToTerminalLog,
diagnosticToViteError,
diagnosticToRuntimeError,
ensureCall,
normalizeTsDiagnostic,
toViteCustomPayload,
} from '../../logger'
import { ACTION_TYPES, CreateDiagnostic, DiagnosticToRuntime } from '../../types'
import { ACTION_TYPES, CreateDiagnostic, DiagnosticLevel, DiagnosticToRuntime } from '../../types'

const createDiagnostic: CreateDiagnostic<'typescript'> = (pluginConfig) => {
let overlay = true
let currErrs: DiagnosticToRuntime[] = []
let currDiagnostics: DiagnosticToRuntime[] = []

return {
config: async ({ enableOverlay }) => {
Expand Down Expand Up @@ -47,13 +47,13 @@ const createDiagnostic: CreateDiagnostic<'typescript'> = (pluginConfig) => {

// https://github.com/microsoft/TypeScript/blob/a545ab1ac2cb24ff3b1aaf0bfbfb62c499742ac2/src/compiler/watch.ts#L12-L28
const reportDiagnostic = (diagnostic: ts.Diagnostic) => {
const normalizedDiagnostics = normalizeTsDiagnostic(diagnostic)
currErrs.push(diagnosticToViteError(normalizedDiagnostics))
// if (!currErr) {
// currErr = diagnosticToViteError(normalizedDiagnostics)
// }
const normalizedDiagnostic = normalizeTsDiagnostic(diagnostic)
if (normalizedDiagnostic === null) {
return
}

logChunk += os.EOL + diagnosticToTerminalLog(normalizedDiagnostics, 'TypeScript')
currDiagnostics.push(diagnosticToRuntimeError(normalizedDiagnostic))
logChunk += os.EOL + diagnosticToTerminalLog(normalizedDiagnostic, 'TypeScript')
}

const reportWatchStatusChanged: ts.WatchStatusReporter = (
Expand All @@ -72,7 +72,7 @@ const createDiagnostic: CreateDiagnostic<'typescript'> = (pluginConfig) => {
// clear current error and use the newer errors
logChunk = ''
// currErr = null
currErrs = []
currDiagnostics = []
return
case 6193: // 1 Error
case 6194: // 0 errors or 2+ errors
Expand All @@ -81,7 +81,7 @@ const createDiagnostic: CreateDiagnostic<'typescript'> = (pluginConfig) => {
// parentPort?.postMessage(toWsPayload(currErrs))
parentPort?.postMessage({
type: ACTION_TYPES.overlayError,
payload: toViteCustomPayload('typescript', currErrs),
payload: toViteCustomPayload('typescript', currDiagnostics),
})
}
}
Expand Down
11 changes: 6 additions & 5 deletions packages/vite-plugin-checker/src/checkers/vls/diagnostics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import { URI } from 'vscode-uri'
import {
consoleLog,
diagnosticToTerminalLog,
diagnosticToViteError,
diagnosticToRuntimeError,
normalizeLspDiagnostic,
normalizePublishDiagnosticParams,
} from '../../logger'
Expand Down Expand Up @@ -166,12 +166,13 @@ export async function prepareClientConnection(
const nextDiagnosticInFile = await normalizePublishDiagnosticParams(publishDiagnostics)
fileDiagnosticManager.updateByFileId(absFilePath, nextDiagnosticInFile)

const res = fileDiagnosticManager.getDiagnostics()
const diagnostics = fileDiagnosticManager.getDiagnostics()

vlsConsoleLog(os.EOL)
vlsConsoleLog(res.map((d) => diagnosticToTerminalLog(d, 'VLS')).join(os.EOL))
vlsConsoleLog(diagnostics.map((d) => diagnosticToTerminalLog(d, 'VLS')).join(os.EOL))

if (res) {
const normalized = diagnosticToViteError(res)
if (diagnostics) {
const normalized = diagnosticToRuntimeError(diagnostics)
options.errorCallback?.(publishDiagnostics, normalized)
}
}
Expand Down
38 changes: 34 additions & 4 deletions packages/vite-plugin-checker/src/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,36 @@ export interface NormalizedDiagnostic {
level?: DiagnosticLevel
}

const defaultLogLevel = [
DiagnosticLevel.Warning,
DiagnosticLevel.Error,
DiagnosticLevel.Suggestion,
DiagnosticLevel.Message,
]

export function filterLogLevel(
diagnostics: NormalizedDiagnostic,
level?: DiagnosticLevel[]
): NormalizedDiagnostic | null
export function filterLogLevel(
diagnostics: NormalizedDiagnostic[],
level?: DiagnosticLevel[]
): NormalizedDiagnostic[]
export function filterLogLevel(
diagnostics: NormalizedDiagnostic | NormalizedDiagnostic[],
level: DiagnosticLevel[] = defaultLogLevel
): NormalizedDiagnostic | null | NormalizedDiagnostic[] {
if (Array.isArray(diagnostics)) {
return diagnostics.filter((d) => {
if (typeof d.level !== 'number') return false
return level.includes(d.level)
})
} else {
if (!diagnostics.level) return null
return level.includes(diagnostics.level) ? diagnostics : null
}
}

export function diagnosticToTerminalLog(
d: NormalizedDiagnostic,
name?: 'TypeScript' | 'vue-tsc' | 'VLS' | 'ESLint'
Expand Down Expand Up @@ -75,9 +105,9 @@ export function diagnosticToTerminalLog(
.join(os.EOL)
}

export function diagnosticToViteError(d: NormalizedDiagnostic): DiagnosticToRuntime
export function diagnosticToViteError(d: NormalizedDiagnostic[]): DiagnosticToRuntime[]
export function diagnosticToViteError(
export function diagnosticToRuntimeError(d: NormalizedDiagnostic): DiagnosticToRuntime
export function diagnosticToRuntimeError(d: NormalizedDiagnostic[]): DiagnosticToRuntime[]
export function diagnosticToRuntimeError(
diagnostics: NormalizedDiagnostic | NormalizedDiagnostic[]
): DiagnosticToRuntime | DiagnosticToRuntime[] {
const diagnosticsArray = Array.isArray(diagnostics) ? diagnostics : [diagnostics]
Expand Down Expand Up @@ -280,7 +310,7 @@ export function normalizeEslintDiagnostic(diagnostic: ESLint.LintResult): Normal
.map((d) => {
let level = DiagnosticLevel.Error
switch (d.severity) {
case 0: // off, ignore
case 0: // off, ignore this
level = DiagnosticLevel.Error
return null
case 1: // warn
Expand Down
8 changes: 5 additions & 3 deletions packages/vite-plugin-checker/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@ export type EslintConfig =
* default config for dev mode when options.eslint.dev.eslint is nullable.
*/
lintCommand: string
dev?: {
dev?: Partial<{
/** You can override the options of translated from lintCommand. */
eslint?: ESLint.Options
}
overrideConfig: ESLint.Options
/** which level of the diagnostic will be emitted from plugin */
logLevel: ('error' | 'warning')[]
}>
}

export enum DiagnosticLevel {
Expand Down
3 changes: 3 additions & 0 deletions playground/eslint-config/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
}
49 changes: 49 additions & 0 deletions playground/eslint-config/__tests__/__snapshots__/test.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`eslint-config serve get initial error and subsequent error 1`] = `"[{\\"checkerId\\":\\"ESLint\\",\\"frame\\":\\" 3 | var hello = 'Hello'/n 4 |/n > 5 | const rootDom = document.querySelector('#root')!/n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^/n 6 | rootDom.innerHTML = hello + text/n 7 |/n 8 | export {}\\",\\"id\\":\\"<PROJECT_ROOT>/temp/eslint-config/src/main.ts\\",\\"level\\":0,\\"loc\\":{\\"column\\":17,\\"file\\":\\"<PROJECT_ROOT>/temp/eslint-config/src/main.ts\\",\\"line\\":5},\\"message\\":\\"Forbidden non-null assertion.\\",\\"stack\\":\\"\\"}]"`;

exports[`eslint-config serve get initial error and subsequent error 2`] = `
" WARNING(ESLint) Forbidden non-null assertion.
FILE <PROJECT_ROOT>/temp/eslint-config/src/main.ts:5:17
3 | var hello = 'Hello'
4 |
> 5 | const rootDom = document.querySelector('#root')!
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6 | rootDom.innerHTML = hello + text
7 |
8 | export {}
"
`;
exports[`eslint-config serve get initial error and subsequent error 3`] = `"[{\\"checkerId\\":\\"ESLint\\",\\"frame\\":\\" 3 | var hello = 'Hello~'/n 4 |/n > 5 | const rootDom = document.querySelector('#root')!/n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^/n 6 | rootDom.innerHTML = hello + text/n 7 |/n 8 | export {}\\",\\"id\\":\\"<PROJECT_ROOT>/temp/eslint-config/src/main.ts\\",\\"level\\":0,\\"loc\\":{\\"column\\":17,\\"file\\":\\"<PROJECT_ROOT>/temp/eslint-config/src/main.ts\\",\\"line\\":5},\\"message\\":\\"Forbidden non-null assertion.\\",\\"stack\\":\\"\\"}]"`;
exports[`eslint-config serve get initial error and subsequent error 4`] = `
" WARNING(ESLint) Forbidden non-null assertion.
FILE <PROJECT_ROOT>/temp/eslint-config/src/main.ts:5:17
3 | var hello = 'Hello~'
4 |
> 5 | const rootDom = document.querySelector('#root')!
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6 | rootDom.innerHTML = hello + text
7 |
8 | export {}
"
`;
exports[`eslint-config serve get initial error and subsequent error 5`] = `"[{\\"checkerId\\":\\"ESLint\\",\\"frame\\":\\" 3 | var hello = 'Hello~'/n 4 |/n > 5 | const rootDom = document.querySelector('#root')!/n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^/n 6 | rootDom.innerHTML = hello + text/n 7 |/n 8 | export {}\\",\\"id\\":\\"<PROJECT_ROOT>/temp/eslint-config/src/main.ts\\",\\"level\\":0,\\"loc\\":{\\"column\\":17,\\"file\\":\\"<PROJECT_ROOT>/temp/eslint-config/src/main.ts\\",\\"line\\":5},\\"message\\":\\"Forbidden non-null assertion.\\",\\"stack\\":\\"\\"}]"`;
exports[`eslint-config serve get initial error and subsequent error 6`] = `
" WARNING(ESLint) Forbidden non-null assertion.
FILE <PROJECT_ROOT>/temp/eslint-config/src/main.ts:5:17
3 | var hello = 'Hello~'
4 |
> 5 | const rootDom = document.querySelector('#root')!
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6 | rootDom.innerHTML = hello + text
7 |
8 | export {}
"
`;
Loading

0 comments on commit 256ba5a

Please sign in to comment.