Skip to content

Commit

Permalink
feat: support for running muliple checks in parallel
Browse files Browse the repository at this point in the history
  • Loading branch information
fi3ework committed Jun 10, 2021
1 parent 5e10b53 commit 2588205
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 117 deletions.
2 changes: 1 addition & 1 deletion examples/vue2-vls/src/components/HelloWorld.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div class="hello">
<h1>{{ msg1 }}</h1>
<h1>{{ msg11 }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br />
check out the
Expand Down
2 changes: 2 additions & 0 deletions examples/vue2-vls/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ new Vue({
store,
render: (h) => h(App),
}).$mount('#app')

export const str: string = 1
6 changes: 2 additions & 4 deletions examples/vue2-vls/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { defineConfig } from 'vite'
import { createVuePlugin } from 'vite-plugin-vue2'
import ViteComponents from 'vite-plugin-components'
import Checker from 'vite-plugin-checker'
import { serveAndBuild } from 'vite-plugin-checker-preset-vls'
import { VlsChecker } from 'vite-plugin-checker-preset-vls'
import { resolve } from 'path'

const config = defineConfig({
Expand All @@ -18,9 +18,7 @@ const config = defineConfig({
plugins: [
createVuePlugin({}),
ViteComponents({ transformer: 'vue2' }),
Checker({
checker: serveAndBuild(),
}),
Checker({ tsc: true, vls: VlsChecker({ volar: true }) }),
],
server: {
port: 8080,
Expand Down
10 changes: 5 additions & 5 deletions presets/vls/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
createScript,
lspDiagnosticToViteError,
uriToAbsPath,
ServeAndBuild,
} from 'vite-plugin-checker'
import { isMainThread, parentPort } from 'worker_threads'

Expand Down Expand Up @@ -64,12 +65,11 @@ const { mainScript, workerScript } = createScript({
})!

if (isMainThread) {
const { createWorker, serveAndBuild } = mainScript()
module.exports.createWorker = createWorker
module.exports.serveAndBuild = serveAndBuild
const { createServeAndBuild } = mainScript()
module.exports.VlsChecker = module.exports.createServeAndBuild = createServeAndBuild
} else {
workerScript()
}

declare const serveAndBuild: any
export { serveAndBuild }
declare const VlsChecker: (options?: { volar?: boolean }) => ServeAndBuild
export { VlsChecker }
84 changes: 46 additions & 38 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,33 @@ export * from './codeFrame'
export * from './utils'
export * from './worker'

function createServeAndBuild(
checker: PluginOptions['checker'],
userOptions?: Partial<PluginOptions>
): ServeAndBuild {
if (typeof checker === 'string') {
// build in checkers
function createServeAndBuild(userOptions: Partial<PluginOptions>): ServeAndBuild[] {
const checkers: ServeAndBuild[] = []
const { tsc, vueTsc, vls } = userOptions

if (tsc) {
// eslint-disable-next-line @typescript-eslint/no-require-imports
const { createServeAndBuild, buildBin } = require('./presets/tsc')
checkers.push(createServeAndBuild(userOptions.tsc))
}

if (vueTsc) {
// eslint-disable-next-line @typescript-eslint/no-require-imports
const { createWorker, buildBin } = require(`./presets/${checker}`)
return { serve: createWorker(userOptions), build: { buildBin } }
const { createServeAndBuild } = require('./presets/vue-tsc')
checkers.push(createServeAndBuild(userOptions.vueTsc))
}

return checker
if (vls) {
checkers.push(vls)
}

return checkers
}

export default function Plugin(userOptions?: Partial<PluginOptions>): Plugin {
const {
serve: { worker, config: workerConfig, configureServer: workerConfigureServer },
build: { buildBin },
} = createServeAndBuild(userOptions?.checker || 'tsc', userOptions)
const serveAndBuilds = createServeAndBuild(userOptions || {})
const enableBuild = userOptions?.enableBuild ?? true
let viteMode: ConfigEnv['command'] | undefined
// let diagnostic: ReturnType<CreateDiagnostic> | null = null

return {
name: 'ts-checker',
Expand All @@ -41,16 +46,13 @@ export default function Plugin(userOptions?: Partial<PluginOptions>): Plugin {
viteMode = env.command
if (viteMode !== 'serve') return

workerConfig({
hmr: config.server?.hmr,
env,
serveAndBuilds.forEach((serveAndBuild) => {
const workerConfig = serveAndBuild.serve.config
workerConfig({
hmr: config.server?.hmr,
env,
})
})
// diagnostic = checker.createDiagnostic({
// root: userOptions?.root,
// tsconfigPath: userOptions?.tsconfigPath,
// })

// diagnostic.config(config, env)
},
buildStart: () => {
// for build mode
Expand All @@ -63,26 +65,32 @@ export default function Plugin(userOptions?: Partial<PluginOptions>): Plugin {
execPath: process.execPath,
})

const proc = spawn(buildBin[0], buildBin[1], {
cwd: process.cwd(),
stdio: 'inherit',
env: localEnv,
})

if (enableBuild) {
proc.on('exit', (code) => {
if (code !== null && code !== 0) {
process.exit(code)
}
serveAndBuilds.forEach((serveAndBuild) => {
const buildBin = serveAndBuild.build.buildBin
const proc = spawn(buildBin[0], buildBin[1], {
cwd: process.cwd(),
stdio: 'inherit',
env: localEnv,
})
}

if (enableBuild) {
proc.on('exit', (code) => {
if (code !== null && code !== 0) {
process.exit(code)
}
})
}
})
},
configureServer(server) {
// for dev mode (2/2)
// Get the server instance and keep reference in a closure
workerConfigureServer({ root: server.config.root })
worker.on('message', (action: OverlayErrorAction) => {
server.ws.send(action.payload)
serveAndBuilds.forEach((serveAndBuild) => {
const { worker, configureServer: workerConfigureServer } = serveAndBuild.serve
workerConfigureServer({ root: server.config.root })
worker.on('message', (action: OverlayErrorAction) => {
server.ws.send(action.payload)
})
})

return () => {
Expand Down
5 changes: 2 additions & 3 deletions src/presets/tsc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,8 @@ const { mainScript, workerScript } = createScript({
})!

if (isMainThread) {
const { createWorker, serveAndBuild } = mainScript()
module.exports.createWorker = createWorker
module.exports.serveAndBuild = serveAndBuild
const { createServeAndBuild } = mainScript()
module.exports.createServeAndBuild = createServeAndBuild
} else {
workerScript()
}
5 changes: 2 additions & 3 deletions src/presets/vue-tsc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,8 @@ const { mainScript, workerScript } = createScript({
})!

if (isMainThread) {
const { createWorker, serveAndBuild } = mainScript()
module.exports.createWorker = createWorker
module.exports.serveAndBuild = serveAndBuild
const { createServeAndBuild } = mainScript()
module.exports.createServeAndBuild = createServeAndBuild
} else {
workerScript()
}
111 changes: 60 additions & 51 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,45 @@
import type { HMRPayload, ServerOptions, ConfigEnv } from 'vite'
import type { Worker } from 'worker_threads'

export type ServeCheckerFactory = (options?: unknown) => ServeChecker

export interface ServeChecker {
createDiagnostic: CreateDiagnostic
}

export type BuildCheckBin = [string, ReadonlyArray<string>]

export interface ConfigureChecker {
worker: Worker
config: (config: ConfigAction['payload']) => void
configureServer: (serverConfig: ConfigureServerAction['payload']) => void
}
/* ----------------------------- userland plugin options ----------------------------- */

export interface ServeAndBuild {
serve: ConfigureChecker
build: { buildBin: BuildCheckBin }
}
type TscConfig = boolean | Partial<{ tsconfigPath: string; root: string }>
type VueTscConfig = boolean | Partial<{ root: string }>
type VlsConfig = ServeAndBuild

export interface DiagnosticOfCheck {
config: (options: Pick<ServerOptions, 'hmr'> & { env: ConfigEnv }) => unknown
configureServer: (options: { root: string }) => unknown
export interface PluginOptions {
tsc: TscConfig
vueTsc: VueTscConfig
vls: VlsConfig
/**
* Use `"tsc"` or `"vue-tsc"` or an custom checker
* @defaultValue `"tcs"`
*/
// checker: 'tsc' | 'vue-tsc' | ServeAndBuild
/**
* Enable checking in build mode
* @defaultValue `true`
*/
enableBuild: boolean
/**
* Show overlay when has TypeScript error
* @defaultValue
* Same as [Vite config](https://vitejs.dev/config/#root)
*/
overlay: boolean
/**
* Root path to find tsconfig file
* @defaultValue
* Same as [Vite config](https://vitejs.dev/config/#root)
*/
root: string
/**
* Relative tsconfig path to {@link (PluginOptions:interface).root}
* @defaultValue `"tsconfig.json"`
*/
tsconfigPath: string
}

export type CreateDiagnostic = (config?: Partial<PluginOptions>) => DiagnosticOfCheck

/* ----------------------------- worker actions ----------------------------- */

export enum ACTION_TYPES {
Expand Down Expand Up @@ -59,34 +72,30 @@ export interface ConfigureServerAction extends Action {

export type Actions = OverlayErrorAction | ConfigAction | ConfigureServerAction

/* ----------------------------- worker actions ----------------------------- */
/* ----------------------------- internal types ----------------------------- */

export interface PluginOptions {
/**
* Use `"tsc"` or `"vue-tsc"` or an custom checker
* @defaultValue `"tcs"`
*/
checker: 'tsc' | 'vue-tsc' | ServeAndBuild
/**
* Enable checking in build mode
* @defaultValue `true`
*/
enableBuild: boolean
/**
* Show overlay when has TypeScript error
* @defaultValue
* Same as [Vite config](https://vitejs.dev/config/#root)
*/
overlay: boolean
/**
* Root path to find tsconfig file
* @defaultValue
* Same as [Vite config](https://vitejs.dev/config/#root)
*/
root: string
/**
* Relative tsconfig path to {@link (PluginOptions:interface).root}
* @defaultValue `"tsconfig.json"`
*/
tsconfigPath: string
export type ServeCheckerFactory = (options?: unknown) => ServeChecker

export interface ServeChecker {
createDiagnostic: CreateDiagnostic
}

export type BuildCheckBin = [string, ReadonlyArray<string>]

export interface ConfigureChecker {
worker: Worker
config: (config: ConfigAction['payload']) => void
configureServer: (serverConfig: ConfigureServerAction['payload']) => void
}

export interface ServeAndBuild {
serve: ConfigureChecker
build: { buildBin: BuildCheckBin }
}

export interface DiagnosticOfCheck {
config: (options: Pick<ServerOptions, 'hmr'> & { env: ConfigEnv }) => unknown
configureServer: (options: { root: string }) => unknown
}

export type CreateDiagnostic = (config?: Partial<PluginOptions>) => DiagnosticOfCheck
17 changes: 5 additions & 12 deletions src/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ export function createScript({ absFilename, buildBin, checkerFactory }: WorkerSc
return {
mainScript: () => {
// initialized in main thread
const createWorker = (userConfigs?: Record<string, never>): ConfigureChecker => {
const createWorker = (checkerConfigs?: Record<string, never>): ConfigureChecker => {
const worker = new Worker(absFilename, {
workerData: userConfigs,
workerData: checkerConfigs,
})

// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
Expand All @@ -42,18 +42,11 @@ export function createScript({ absFilename, buildBin, checkerFactory }: WorkerSc
}

return {
createWorker,
serveAndBuild: (config: any) => ({
createServeAndBuild: (config: any) => ({
serve: createWorker(config),
build: buildBin,
}),
}

// module.exports.createWorker = createWorker
// module.exports.serveAndBuild = (config: any) => ({
// serve: createWorker(config),
// build: buildBin,
// })
},
workerScript: () => {
// runs in worker thread
Expand All @@ -63,8 +56,8 @@ export function createScript({ absFilename, buildBin, checkerFactory }: WorkerSc
parentPort.on('message', (action: ConfigAction | ConfigureServerAction) => {
if (action.type === ACTION_TYPES.config) {
const checker = checkerFactory()
const userConfigs = workerData
diagnostic = checker.createDiagnostic(userConfigs)
const checkerConfig = workerData
diagnostic = checker.createDiagnostic(checkerConfig)
diagnostic.config(action.payload)
} else if (action.type === ACTION_TYPES.configureServer) {
if (!diagnostic) throw Error('diagnostic should be initialized in `config` hook of Vite')
Expand Down

0 comments on commit 2588205

Please sign in to comment.