From 5f6de2430343de13d8f016851bd1f1409be9ce20 Mon Sep 17 00:00:00 2001 From: Julien Ripouteau Date: Mon, 22 Apr 2024 00:35:51 +0200 Subject: [PATCH] fix: windows paths handling (#6) --- .changeset/fifty-roses-heal.md | 6 ++++++ .github/workflows/check.yml | 9 +++++++-- packages/hot_hook/src/loader.ts | 1 + packages/hot_hook/src/matcher.ts | 24 ++++++++++++------------ 4 files changed, 26 insertions(+), 14 deletions(-) create mode 100644 .changeset/fifty-roses-heal.md diff --git a/.changeset/fifty-roses-heal.md b/.changeset/fifty-roses-heal.md new file mode 100644 index 0000000..5e2973a --- /dev/null +++ b/.changeset/fifty-roses-heal.md @@ -0,0 +1,6 @@ +--- +"hot-hook": patch +--- + +`--import=hot-hook/register` was broken due to a bug in path handling that wasn't cross platform. This has been fixed and also added a Windows CI to prevent this from happening again. + diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 74fddc3..3064ab6 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -50,7 +50,10 @@ jobs: run: pnpm typecheck tests: - runs-on: ubuntu-latest + strategy: + matrix: + os: [ubuntu-latest, windows-latest] + runs-on: ${{ matrix.os }} timeout-minutes: 10 steps: @@ -72,4 +75,6 @@ jobs: pnpm -r build - name: Run tests - run: FORCE_COLOR=1 pnpm test + env: + FORCE_COLOR: 1 + run: pnpm test diff --git a/packages/hot_hook/src/loader.ts b/packages/hot_hook/src/loader.ts index 791860d..e43ee4d 100644 --- a/packages/hot_hook/src/loader.ts +++ b/packages/hot_hook/src/loader.ts @@ -63,6 +63,7 @@ export class HotHookLoader { */ const isReloadable = this.#dependencyTree.isReloadable(realFilePath) if (!isReloadable) { + debug('Full reload %s', realFilePath) return this.#messagePort?.postMessage({ type: 'hot-hook:full-reload', path: realFilePath }) } diff --git a/packages/hot_hook/src/matcher.ts b/packages/hot_hook/src/matcher.ts index 448336d..4f5a6a1 100644 --- a/packages/hot_hook/src/matcher.ts +++ b/packages/hot_hook/src/matcher.ts @@ -2,32 +2,32 @@ import { resolve } from 'node:path' import picomatch from 'picomatch' export class Matcher { - #rootDirectory: string #matcher: picomatch.Matcher constructor(rootDirectory: string, patterns: picomatch.Glob = []) { - this.#rootDirectory = rootDirectory - patterns = Array.isArray(patterns) ? patterns : [patterns] + const absolutePatterns = patterns .map((pattern) => { - if (pattern.startsWith('../')) return resolve(rootDirectory, pattern) - return pattern + /** + * Do not resolve double star patterns because they are not relative to the root + */ + if (pattern.startsWith('**')) return pattern + + /** + * Resolve the pattern to the root directory. All patterns are relative to the root + */ + return resolve(rootDirectory, pattern) }) .map((path) => path.replace(/\\/g, '/')) - this.#matcher = picomatch(absolutePatterns || [], { dot: true }) + this.#matcher = picomatch(absolutePatterns || [], { dot: true, posixSlashes: true }) } /** * Check if a path matches the patterns */ match(filePath: string) { - filePath = filePath.replace(/\\/g, '/') - if (filePath.startsWith(this.#rootDirectory)) { - filePath = filePath.slice(this.#rootDirectory.length).replace(/^\//, '') - } - - return this.#matcher(filePath) + return this.#matcher(resolve(filePath)) } }