Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(perf): tsconfck perf improvement #7055

Merged
merged 3 commits into from Mar 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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.