Skip to content

Commit

Permalink
feat(perf): tsconfck perf improvement (#7055)
Browse files Browse the repository at this point in the history
  • Loading branch information
dominikg committed Mar 3, 2022
1 parent 47fbe29 commit 993ea39
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 22 deletions.
2 changes: 1 addition & 1 deletion packages/vite/package.json
Expand Up @@ -113,7 +113,7 @@
"source-map-support": "^0.5.21",
"strip-ansi": "^6.0.1",
"terser": "^5.10.0",
"tsconfck": "1.1.2",
"tsconfck": "^1.2.0",
"tslib": "^2.3.1",
"types": "link:./types",
"ws": "^8.5.0"
Expand Down
53 changes: 39 additions & 14 deletions packages/vite/src/node/plugins/esbuild.ts
Expand Up @@ -20,8 +20,9 @@ import type { SourceMap } from 'rollup'
import type { ResolvedConfig, ViteDevServer } from '..'
import { createFilter } from '@rollup/pluginutils'
import { combineSourcemaps } from '../utils'
import type { TSConfckParseResult } from 'tsconfck'
import { parse, TSConfckParseError } from 'tsconfck'
import type { TSConfckParseOptions, TSConfckParseResult } from 'tsconfck'
import { parse, findAll, TSConfckParseError } from 'tsconfck'
import { searchForWorkspaceRoot } from '..'

const debug = createDebugger('vite:esbuild')

Expand Down Expand Up @@ -179,6 +180,9 @@ export function esbuildPlugin(options: ESBuildOptions = {}): Plugin {
.on('change', reloadOnTsconfigChange)
.on('unlink', reloadOnTsconfigChange)
},
async configResolved(config) {
await initTSConfck(config)
},
buildEnd() {
// recycle serve to avoid preventing Node self-exit (#6815)
server = null as any
Expand Down Expand Up @@ -224,6 +228,9 @@ const rollupToEsbuildFormatMap: Record<
export const buildEsbuildPlugin = (config: ResolvedConfig): Plugin => {
return {
name: 'vite:esbuild-transpile',
async configResolved(config) {
await initTSConfck(config)
},
async renderChunk(code, chunk, opts) {
// @ts-ignore injected by @vitejs/plugin-legacy
if (opts.__vite_skip_esbuild__) {
Expand Down Expand Up @@ -274,15 +281,29 @@ function prettifyMessage(m: Message, code: string): string {
return res + `\n`
}

const tsconfigCache = new Map<string, TSConfckParseResult>()
const tsconfckParseOptions: TSConfckParseOptions = {
cache: new Map<string, TSConfckParseResult>(),
tsConfigPaths: undefined,
root: undefined,
resolveWithEmptyIfConfigNotFound: true
}

async function initTSConfck(config: ResolvedConfig) {
tsconfckParseOptions.cache!.clear()
const workspaceRoot = searchForWorkspaceRoot(config.root)
tsconfckParseOptions.root = workspaceRoot
tsconfckParseOptions.tsConfigPaths = new Set([
...(await findAll(workspaceRoot, {
skip: (dir) => dir === 'node_modules' || dir === '.git'
}))
])
}

async function loadTsconfigJsonForFile(
filename: string
): Promise<TSConfigJSON> {
try {
const result = await parse(filename, {
cache: tsconfigCache,
resolveWithEmptyIfConfigNotFound: true
})
const result = await parse(filename, tsconfckParseOptions)
// tsconfig could be out of root, make sure it is watched on dev
if (server && result.tsconfigFile !== 'no_tsconfig_file_found') {
ensureWatchedFile(server.watcher, result.tsconfigFile, server.config.root)
Expand All @@ -304,20 +325,24 @@ function reloadOnTsconfigChange(changedFile: string) {
// any json file in the tsconfig cache could have been used to compile ts
if (
path.basename(changedFile) === 'tsconfig.json' ||
(changedFile.endsWith('.json') && tsconfigCache.has(changedFile))
(changedFile.endsWith('.json') &&
tsconfckParseOptions?.cache?.has(changedFile))
) {
server.config.logger.info(
`changed tsconfig file detected: ${changedFile} - Clearing cache and forcing full-reload to ensure typescript is compiled with updated config values.`,
{ clear: server.config.clearScreen, timestamp: true }
)
// clear tsconfig cache so that recompile works with up2date configs
tsconfigCache.clear()

// clear module graph to remove code compiled with outdated config
server.moduleGraph.invalidateAll()
// force full reload
server.ws.send({
type: 'full-reload',
path: '*'

// reset tsconfck so that recompile works with up2date configs
initTSConfck(server.config).finally(() => {
// force full reload
server.ws.send({
type: 'full-reload',
path: '*'
})
})
}
}
14 changes: 7 additions & 7 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 993ea39

Please sign in to comment.