Skip to content

Commit

Permalink
refactor: update to tsconfck3 with lazy cache (#14234)
Browse files Browse the repository at this point in the history
  • Loading branch information
dominikg authored Sep 15, 2023
1 parent 7371c5c commit 6e0b0ee
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 59 deletions.
2 changes: 1 addition & 1 deletion packages/vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@
"source-map-support": "^0.5.21",
"strip-ansi": "^7.1.0",
"strip-literal": "^1.3.0",
"tsconfck": "^2.1.2",
"tsconfck": "^3.0.0-next.8",
"tslib": "^2.6.1",
"types": "link:./types",
"ufo": "^1.2.0",
Expand Down
72 changes: 20 additions & 52 deletions packages/vite/src/node/plugins/esbuild.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import path from 'node:path'
import { performance } from 'node:perf_hooks'
import colors from 'picocolors'
import type {
Loader,
Expand All @@ -10,21 +9,19 @@ import type {
import { transform } from 'esbuild'
import type { RawSourceMap } from '@ampproject/remapping'
import type { InternalModuleFormat, SourceMap } from 'rollup'
import type { TSConfckParseOptions } from 'tsconfck'
import { TSConfckParseError, findAll, parse } from 'tsconfck'
import type { TSConfckParseResult } from 'tsconfck'
import { TSConfckCache, TSConfckParseError, parse } from 'tsconfck'
import {
cleanUrl,
combineSourcemaps,
createDebugger,
createFilter,
ensureWatchedFile,
generateCodeFrame,
timeFrom,
} from '../utils'
import type { ViteDevServer } from '../server'
import type { ResolvedConfig } from '../config'
import type { Plugin } from '../plugin'
import { searchForWorkspaceRoot } from '../server/searchRoot'

const debug = createDebugger('vite:esbuild')

Expand Down Expand Up @@ -257,8 +254,6 @@ export function esbuildPlugin(config: ResolvedConfig): Plugin {
keepNames: false,
}

initTSConfck(config.root)

return {
name: 'vite:esbuild',
configureServer(_server) {
Expand Down Expand Up @@ -311,8 +306,6 @@ const rollupToEsbuildFormatMap: Record<
}

export const buildEsbuildPlugin = (config: ResolvedConfig): Plugin => {
initTSConfck(config.root)

return {
name: 'vite:esbuild-transpile',
async renderChunk(code, chunk, opts) {
Expand Down Expand Up @@ -469,53 +462,28 @@ function prettifyMessage(m: Message, code: string): string {
return res + `\n`
}

let tsconfckRoot: string | undefined
let tsconfckParseOptions: TSConfckParseOptions | Promise<TSConfckParseOptions> =
{ resolveWithEmptyIfConfigNotFound: true }

function initTSConfck(root: string, force = false) {
// bail if already cached
if (!force && root === tsconfckRoot) return

const workspaceRoot = searchForWorkspaceRoot(root)

tsconfckRoot = root
tsconfckParseOptions = initTSConfckParseOptions(workspaceRoot)

// cached as the options value itself when promise is resolved
tsconfckParseOptions.then((options) => {
if (root === tsconfckRoot) {
tsconfckParseOptions = options
}
})
}

async function initTSConfckParseOptions(workspaceRoot: string) {
const start = debug ? performance.now() : 0

const options: TSConfckParseOptions = {
cache: new Map(),
root: workspaceRoot,
tsConfigPaths: new Set(
await findAll(workspaceRoot, {
skip: (dir) => dir === 'node_modules' || dir === '.git',
}),
),
resolveWithEmptyIfConfigNotFound: true,
}

debug?.(timeFrom(start), 'tsconfck init', colors.dim(workspaceRoot))

return options
}
let tsconfckCache: TSConfckCache<TSConfckParseResult>

async function loadTsconfigJsonForFile(
filename: string,
): Promise<TSConfigJSON> {
try {
const result = await parse(filename, await tsconfckParseOptions)
if (tsconfckCache) {
// shortcut, the cache stores resolved TSConfckParseResult
// so getting it from the cache directly we bypass aysnc fn call wrapping it in a promise again
if (tsconfckCache.hasParseResult(filename)) {
const result = await tsconfckCache.getParseResult(filename)
return result.tsconfig
}
} else {
tsconfckCache = new TSConfckCache<TSConfckParseResult>()
}
const result = await parse(filename, {
cache: tsconfckCache,
ignoreNodeModules: true,
})
// tsconfig could be out of root, make sure it is watched on dev
if (server && result.tsconfigFile !== 'no_tsconfig_file_found') {
if (server && result.tsconfigFile) {
ensureWatchedFile(server.watcher, result.tsconfigFile, server.config.root)
}
return result.tsconfig
Expand All @@ -538,7 +506,7 @@ async function reloadOnTsconfigChange(changedFile: string) {
if (
path.basename(changedFile) === 'tsconfig.json' ||
(changedFile.endsWith('.json') &&
(await tsconfckParseOptions)?.cache?.has(changedFile))
tsconfckCache?.hasParseResult(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.`,
Expand All @@ -549,7 +517,7 @@ async function reloadOnTsconfigChange(changedFile: string) {
server.moduleGraph.invalidateAll()

// reset tsconfck so that recompile works with up2date configs
initTSConfck(server.config.root, true)
tsconfckCache.clear()

// server may not be available if vite config is updated at the same time
if (server) {
Expand Down
12 changes: 6 additions & 6 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 6e0b0ee

Please sign in to comment.