From 8c152bd650c37134d21ef5fdb4b04d67e231bee3 Mon Sep 17 00:00:00 2001 From: Brad Cornes Date: Fri, 27 Jan 2023 11:24:28 +0000 Subject: [PATCH] Only watch directories up to workspace root (#709) * Don't watch beyond workspace root * Catch errors when adding paths to chokidar watcher * Normalize paths * wip --- .../tailwindcss-language-server/src/server.ts | 32 ++++++++++++------- .../src/util/getModuleDependencies.ts | 2 ++ 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/packages/tailwindcss-language-server/src/server.ts b/packages/tailwindcss-language-server/src/server.ts index 67bd665..113231e 100644 --- a/packages/tailwindcss-language-server/src/server.ts +++ b/packages/tailwindcss-language-server/src/server.ts @@ -346,16 +346,22 @@ function changeAffectsFile(change: string, files: string[]): boolean { // We need to add parent directories to the watcher: // https://github.com/microsoft/vscode/issues/60813 -function getWatchPatternsForFile(file: string): string[] { +function getWatchPatternsForFile(file: string, root: string): string[] { let tmp: string let dir = path.dirname(file) let patterns: string[] = [file, dir] + if (dir === root) { + return patterns + } while (true) { dir = path.dirname((tmp = dir)) if (tmp === dir) { break } else { patterns.push(dir) + if (dir === root) { + break + } } } return patterns @@ -440,8 +446,8 @@ async function createProjectService( deps = getModuleDependencies(projectConfig.configPath) } catch {} watchPatterns([ - ...getWatchPatternsForFile(projectConfig.configPath), - ...deps.flatMap((dep) => getWatchPatternsForFile(dep)), + ...getWatchPatternsForFile(projectConfig.configPath, projectConfig.folder), + ...deps.flatMap((dep) => getWatchPatternsForFile(dep, projectConfig.folder)), ]) } @@ -459,7 +465,7 @@ async function createProjectService( let file = normalizePath(change.file) let isConfigFile = changeAffectsFile(file, [projectConfig.configPath]) - let isDependency = changeAffectsFile(change.file, state.dependencies ?? []) + let isDependency = changeAffectsFile(file, state.dependencies ?? []) let isPackageFile = minimatch(file, `**/${PACKAGE_LOCK_GLOB}`, { dot: true }) if (!isConfigFile && !isDependency && !isPackageFile) continue @@ -564,7 +570,7 @@ async function createProjectService( throw new SilentError('No config file found.') } - watchPatterns(getWatchPatternsForFile(configPath)) + watchPatterns(getWatchPatternsForFile(configPath, projectConfig.folder)) const pnpPath = findUp.sync( (dir) => { @@ -576,7 +582,7 @@ async function createProjectService( if (findUp.sync.exists(pnpFile)) { return pnpFile } - if (dir === folder) { + if (dir === path.normalize(folder)) { return findUp.stop } }, @@ -1062,7 +1068,11 @@ async function createProjectService( // } state.dependencies = getModuleDependencies(state.configPath) // chokidarWatcher?.add(state.dependencies) - watchPatterns((state.dependencies ?? []).flatMap((dep) => getWatchPatternsForFile(dep))) + watchPatterns( + (state.dependencies ?? []).flatMap((dep) => + getWatchPatternsForFile(dep, projectConfig.folder) + ) + ) state.configId = getConfigId(state.configPath, state.dependencies) @@ -1515,7 +1525,7 @@ async function getConfigFileFromCssFile(cssFile: string): Promise if (!match) { return null } - return path.resolve(path.dirname(cssFile), match.groups.config.slice(1, -1)) + return normalizePath(path.resolve(path.dirname(cssFile), match.groups.config.slice(1, -1))) } function getPackageRoot(cwd: string, rootDir: string) { @@ -1526,7 +1536,7 @@ function getPackageRoot(cwd: string, rootDir: string) { if (findUp.sync.exists(pkgJson)) { return pkgJson } - if (dir === rootDir) { + if (dir === path.normalize(rootDir)) { return findUp.stop } }, @@ -1606,7 +1616,7 @@ class TW { let ignore = globalSettings.tailwindCSS.files.exclude let configFileOrFiles = globalSettings.tailwindCSS.experimental.configFile - let base = normalizeFileNameToFsPath(this.initializeParams.rootPath) + let base = normalizePath(normalizeFileNameToFsPath(this.initializeParams.rootPath)) let cssFileConfigMap: Map = new Map() let configTailwindVersionMap: Map = new Map() @@ -1640,7 +1650,7 @@ class TW { ([relativeConfigPath, relativeDocumentSelectorOrSelectors]) => { return { folder: base, - configPath: path.resolve(userDefinedConfigBase, relativeConfigPath), + configPath: normalizePath(path.resolve(userDefinedConfigBase, relativeConfigPath)), documentSelector: [].concat(relativeDocumentSelectorOrSelectors).map((selector) => ({ priority: DocumentSelectorPriority.USER_CONFIGURED, pattern: normalizePath(path.resolve(userDefinedConfigBase, selector)), diff --git a/packages/tailwindcss-language-server/src/util/getModuleDependencies.ts b/packages/tailwindcss-language-server/src/util/getModuleDependencies.ts index feae51c..84de7f8 100644 --- a/packages/tailwindcss-language-server/src/util/getModuleDependencies.ts +++ b/packages/tailwindcss-language-server/src/util/getModuleDependencies.ts @@ -2,11 +2,13 @@ import fs from 'fs' import path from 'path' import resolve from 'resolve' import detective from 'detective' +import normalizePath from 'normalize-path' export function getModuleDependencies(modulePath: string): string[] { return _getModuleDependencies(modulePath) .map(({ file }) => file) .filter((file) => file !== modulePath) + .map((file) => normalizePath(file)) } function createModule(file) {