Skip to content

Commit

Permalink
refactor!: resolve glob patterns from package.json directory when usi…
Browse files Browse the repository at this point in the history
…ng `hot-hook/register`
  • Loading branch information
Julien-R44 committed Apr 17, 2024
1 parent 5047afb commit c0defa6
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 9 deletions.
33 changes: 33 additions & 0 deletions .changeset/healthy-houses-kneel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
"hot-hook": minor
---

From this commit, if you are using `--import=hot-hook/register` for using hot-hook, the `package.json` will be used for resolving glob patterns in the `boundaries` config.

That means, if you had a `package.json` with the following content, and a root entrypoint in `./src/start.ts`, glob patterns were resolved from `./src/start.ts` file :

```json
{
"name": "my-package",
"version": "1.0.0",
"hot-hook": {
"boundaries": [
"./controllers/**/*",
]
}
}
```

This configuration was matching all files in the `./src/controllers` directory. To achieve the same result, you should now use the following configuration:

```json
{
"name": "my-package",
"version": "1.0.0",
"hot-hook": {
"boundaries": [
"./src/controllers/**/*",
]
}
}
```
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ To configure boundaries and other files, you'll need to use your application's `
}
```

Note that glob patterns are resolved from the `package.json` directory.

Or you can still use the `import.meta.hot?.boundary` attribute in your code to specify which files should be hot reloadable.

### Using `hot.init`
Expand Down
2 changes: 1 addition & 1 deletion examples/fastify/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
},
"hotHook": {
"boundaries": [
"./services/**/*.ts"
"./src/services/**/*.ts"
]
}
}
2 changes: 1 addition & 1 deletion examples/hono/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
},
"hotHook": {
"boundaries": [
"./views/**/*.tsx"
"./src/views/**/*.tsx"
]
}
}
2 changes: 1 addition & 1 deletion examples/node_http_basic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
},
"hotHook": {
"boundaries": [
"./app.ts"
"./src/app.ts"
]
}
}
3 changes: 2 additions & 1 deletion packages/hot_hook/src/hot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,11 @@ class Hot {
parentURL: import.meta.url,
transferList: [this.#messageChannel.port2],
data: {
messagePort: this.#messageChannel.port2,
root: this.#options.root,
ignore: this.#options.ignore,
boundaries: this.#options.boundaries,
messagePort: this.#messageChannel.port2,
rootDirectory: this.#options.rootDirectory,
} satisfies InitializeHookOptions,
})

Expand Down
3 changes: 2 additions & 1 deletion packages/hot_hook/src/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export class HotHookLoader {
constructor(options: InitializeHookOptions) {
this.#options = options
this.#messagePort = options.messagePort
this.#projectRoot = options.rootDirectory!

if (options.root) this.#initialize(options.root)

Expand All @@ -33,8 +34,8 @@ export class HotHookLoader {
* Initialize the class with the provided root path.
*/
#initialize(root: string) {
this.#projectRoot = dirname(root)
this.#watcher = this.#createWatcher().add(root)
this.#projectRoot = this.#projectRoot ?? dirname(root)
this.#pathIgnoredMatcher = new Matcher(this.#projectRoot, this.#options.ignore)
this.#hardcodedBoundaryMatcher = new Matcher(this.#projectRoot, this.#options.boundaries)
}
Expand Down
8 changes: 5 additions & 3 deletions packages/hot_hook/src/register.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { resolve } from 'node:path'
import { hot } from './hot.js'
import { dirname, resolve } from 'node:path'
import { readPackageUp } from 'read-package-up'

import { hot } from './hot.js'

const pkgJson = await readPackageUp()
if (!pkgJson) {
throw new Error('Could not find package.json')
Expand All @@ -11,7 +12,8 @@ const { packageJson, path: packageJsonPath } = pkgJson
const hotHookConfig = packageJson.hotHook

await hot.init({
root: hotHookConfig?.root ? resolve(packageJsonPath, hotHookConfig.root) : undefined,
rootDirectory: dirname(packageJsonPath),
boundaries: hotHookConfig?.boundaries,
ignore: ['**/node_modules/**'].concat(hotHookConfig?.ignore || []),
root: hotHookConfig?.root ? resolve(packageJsonPath, hotHookConfig.root) : undefined,
})
11 changes: 10 additions & 1 deletion packages/hot_hook/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,23 @@ export interface InitOptions {
*/
root?: string

/**
* Root Directory will be used to resolve relative paths.
* If not provided, it will be the directory of the root file.
*/
rootDirectory?: string

/**
* Files that will create an HMR boundary. This is equivalent of importing
* the module with `import.meta.hot.boundary` in the module.
*/
boundaries?: string[]
}

export type InitializeHookOptions = Pick<InitOptions, 'ignore' | 'root' | 'boundaries'> & {
export type InitializeHookOptions = Pick<
InitOptions,
'ignore' | 'root' | 'rootDirectory' | 'boundaries'
> & {
/**
* The message port to communicate with the parent thread.
*/
Expand Down
42 changes: 42 additions & 0 deletions packages/hot_hook/tests/register.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,46 @@ test.group('Register', () => {
await createHandlerFile({ path: 'app.js', response: 'Hello World! Updated new' })
await supertest('http://localhost:3333').get('/').expect(200).expect('Hello World! Updated new')
})

test('use package.json dirname as root directory', async ({ fs }) => {
await fakeInstall(fs.basePath)

await fs.createJson('package.json', {
type: 'module',
hotHook: { boundaries: ['./src/app.js'] },
})
await fs.create(
'bin/server.js',
`import * as http from 'http'
import { join } from 'node:path'
const server = http.createServer(async (request, response) => {
const app = await import('../src/app.js')
await app.default(request, response)
})
server.listen(3333, () => console.log('Server is running'))
`
)

await createHandlerFile({ path: 'src/app.js', response: 'Hello World!' })

const server = runProcess('bin/server.js', {
cwd: fs.basePath,
env: { NODE_DEBUG: 'hot-hook' },
nodeOptions: ['--import=hot-hook/register'],
})

await server.waitForOutput('Server is running')

await supertest('http://localhost:3333').get('/').expect(200).expect('Hello World!')

await setTimeout(100)
await createHandlerFile({ path: 'src/app.js', response: 'Hello World! Updated' })
await supertest('http://localhost:3333').get('/').expect(200).expect('Hello World! Updated')

await setTimeout(100)
await createHandlerFile({ path: 'src/app.js', response: 'Hello World! Updated new' })
await supertest('http://localhost:3333').get('/').expect(200).expect('Hello World! Updated new')
})
})

0 comments on commit c0defa6

Please sign in to comment.