Skip to content

Commit

Permalink
fix(nuxt): pass (and handle) relative paths in builder:watch (#22333)
Browse files Browse the repository at this point in the history
  • Loading branch information
danielroe committed Jul 26, 2023
1 parent e3437c6 commit e2c7edd
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 45 deletions.
18 changes: 10 additions & 8 deletions packages/nuxt/src/components/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,14 @@ export default defineNuxtModule<ComponentsOptions>({
})

// Restart dev server when component directories are added/removed
nuxt.hook('builder:watch', (event, path) => {
const isDirChange = ['addDir', 'unlinkDir'].includes(event)
const fullPath = resolve(nuxt.options.srcDir, path)
nuxt.hook('builder:watch', (event, relativePath) => {
if (!['addDir', 'unlinkDir'].includes(event)) {
return
}

if (isDirChange && componentDirs.some(dir => dir.path === fullPath)) {
console.info(`Directory \`${path}/\` ${event === 'addDir' ? 'created' : 'removed'}`)
const path = resolve(nuxt.options.srcDir, relativePath)
if (componentDirs.some(dir => dir.path === path)) {
console.info(`Directory \`${relativePath}/\` ${event === 'addDir' ? 'created' : 'removed'}`)
return nuxt.callHook('restart')
}
})
Expand Down Expand Up @@ -183,12 +185,12 @@ export default defineNuxtModule<ComponentsOptions>({
})

// Watch for changes
nuxt.hook('builder:watch', async (event, path) => {
nuxt.hook('builder:watch', async (event, relativePath) => {
if (!['add', 'unlink'].includes(event)) {
return
}
const fPath = resolve(nuxt.options.srcDir, path)
if (componentDirs.find(dir => fPath.startsWith(dir.path))) {
const path = resolve(nuxt.options.srcDir, relativePath)
if (componentDirs.some(dir => path.startsWith(dir.path + '/'))) {
await updateTemplates({
filter: template => [
'components.plugin.mjs',
Expand Down
29 changes: 18 additions & 11 deletions packages/nuxt/src/core/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import chokidar from 'chokidar'
import { isIgnored, tryResolveModule, useNuxt } from '@nuxt/kit'
import { interopDefault } from 'mlly'
import { debounce } from 'perfect-debounce'
import { normalize, resolve } from 'pathe'
import { normalize, relative, resolve } from 'pathe'
import type { Nuxt } from 'nuxt/schema'

import { generateApp as _generateApp, createApp } from './app'
Expand All @@ -19,12 +19,16 @@ export async function build (nuxt: Nuxt) {

if (nuxt.options.dev) {
watch(nuxt)
nuxt.hook('builder:watch', async (event, path) => {
if (event !== 'change' && /^(app\.|error\.|plugins\/|middleware\/|layouts\/)/i.test(path)) {
if (path.startsWith('app')) {
nuxt.hook('builder:watch', async (event, relativePath) => {
if (event === 'change') { return }
const path = resolve(nuxt.options.srcDir, relativePath)
const relativePaths = nuxt.options._layers.map(l => relative(l.config.srcDir || l.cwd, path))
const restartPath = relativePaths.find(relativePath => /^(app\.|error\.|plugins\/|middleware\/|layouts\/)/i.test(relativePath))
if (restartPath) {
if (restartPath.startsWith('app')) {
app.mainComponent = undefined
}
if (path.startsWith('error')) {
if (restartPath.startsWith('error')) {
app.errorComponent = undefined
}
await generateApp()
Expand Down Expand Up @@ -72,15 +76,15 @@ function createWatcher () {

const watcher = chokidar.watch(nuxt.options._layers.map(i => i.config.srcDir as string).filter(Boolean), {
...nuxt.options.watchers.chokidar,
cwd: nuxt.options.srcDir,
ignoreInitial: true,
ignored: [
isIgnored,
'node_modules'
]
})

watcher.on('all', (event, path) => nuxt.callHook('builder:watch', event, normalize(path)))
// TODO: consider moving to emit absolute path in 3.8 or 4.0
watcher.on('all', (event, path) => nuxt.callHook('builder:watch', event, normalize(relative(nuxt.options.srcDir, path))))
nuxt.hook('close', () => watcher?.close())
}

Expand All @@ -94,7 +98,7 @@ function createGranularWatcher () {
let pending = 0

const ignoredDirs = new Set([...nuxt.options.modulesDir, nuxt.options.buildDir])
const pathsToWatch = nuxt.options._layers.map(layer => layer.config.srcDir).filter(d => d && !isIgnored(d))
const pathsToWatch = nuxt.options._layers.map(layer => layer.config.srcDir || layer.cwd).filter(d => d && !isIgnored(d))
for (const pattern of nuxt.options.watch) {
if (typeof pattern !== 'string') { continue }
const path = resolve(nuxt.options.srcDir, pattern)
Expand All @@ -109,15 +113,17 @@ function createGranularWatcher () {
watcher.on('all', (event, path) => {
path = normalize(path)
if (!pending) {
nuxt.callHook('builder:watch', event, path)
// TODO: consider moving to emit absolute path in 3.8 or 4.0
nuxt.callHook('builder:watch', event, relative(nuxt.options.srcDir, path))
}
if (event === 'unlinkDir' && path in watchers) {
watchers[path]?.close()
delete watchers[path]
}
if (event === 'addDir' && path !== dir && !ignoredDirs.has(path) && !pathsToWatch.includes(path) && !(path in watchers) && !isIgnored(path)) {
watchers[path] = chokidar.watch(path, { ...nuxt.options.watchers.chokidar, ignored: [isIgnored] })
watchers[path].on('all', (event, path) => nuxt.callHook('builder:watch', event, normalize(path)))
// TODO: consider moving to emit absolute path in 3.8 or 4.0
watchers[path].on('all', (event, p) => nuxt.callHook('builder:watch', event, normalize(relative(nuxt.options.srcDir, p))))
nuxt.hook('close', () => watchers[path]?.close())
}
})
Expand All @@ -144,7 +150,8 @@ async function createParcelWatcher () {
if (err) { return }
for (const event of events) {
if (isIgnored(event.path)) { continue }
nuxt.callHook('builder:watch', watchEvents[event.type], normalize(event.path))
// TODO: consider moving to emit absolute path in 3.8 or 4.0
nuxt.callHook('builder:watch', watchEvents[event.type], normalize(relative(nuxt.options.srcDir, event.path)))
}
}, {
ignore: [
Expand Down
7 changes: 4 additions & 3 deletions packages/nuxt/src/core/nuxt.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { join, normalize, relative, resolve } from 'pathe'
import { join, normalize, resolve } from 'pathe'
import { createDebugger, createHooks } from 'hookable'
import type { LoadNuxtOptions } from '@nuxt/kit'
import { addBuildPlugin, addComponent, addPlugin, addVitePlugin, addWebpackPlugin, installModule, loadNuxtConfig, logger, nuxtCtx, resolveAlias, resolveFiles, resolvePath, tryResolveModule, useNitro } from '@nuxt/kit'
Expand Down Expand Up @@ -180,7 +180,7 @@ async function initNuxt (nuxt: Nuxt) {
`${config.dir?.modules || 'modules'}/*/index{${nuxt.options.extensions.join(',')}}`
])
for (const mod of layerModules) {
watchedPaths.add(relative(config.srcDir, mod))
watchedPaths.add(mod)
if (specifiedModules.has(mod)) { continue }
specifiedModules.add(mod)
modulesToInstall.push(mod)
Expand Down Expand Up @@ -341,7 +341,8 @@ async function initNuxt (nuxt: Nuxt) {

await nuxt.callHook('modules:done')

nuxt.hooks.hook('builder:watch', (event, path) => {
nuxt.hooks.hook('builder:watch', (event, relativePath) => {
const path = resolve(nuxt.options.srcDir, relativePath)
// Local module patterns
if (watchedPaths.has(path)) {
return nuxt.callHook('restart', { hard: true })
Expand Down
16 changes: 8 additions & 8 deletions packages/nuxt/src/imports/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,12 @@ export default defineNuxtModule<Partial<ImportsOptions>>({
composablesDirs = composablesDirs.map(dir => normalize(dir))

// Restart nuxt when composable directories are added/removed
nuxt.hook('builder:watch', (event, path) => {
const isDirChange = ['addDir', 'unlinkDir'].includes(event)
const fullPath = resolve(nuxt.options.srcDir, path)
nuxt.hook('builder:watch', (event, relativePath) => {
if (!['addDir', 'unlinkDir'].includes(event)) { return }

if (isDirChange && composablesDirs.includes(fullPath)) {
console.info(`Directory \`${path}/\` ${event === 'addDir' ? 'created' : 'removed'}`)
const path = resolve(nuxt.options.srcDir, relativePath)
if (composablesDirs.includes(path)) {
console.info(`Directory \`${relativePath}/\` ${event === 'addDir' ? 'created' : 'removed'}`)
return nuxt.callHook('restart')
}
})
Expand Down Expand Up @@ -119,9 +119,9 @@ export default defineNuxtModule<Partial<ImportsOptions>>({
'imports.d.ts',
'imports.mjs'
]
nuxt.hook('builder:watch', async (_, path) => {
const _resolved = resolve(nuxt.options.srcDir, path)
if (composablesDirs.find(dir => _resolved.startsWith(dir))) {
nuxt.hook('builder:watch', async (_, relativePath) => {
const path = resolve(nuxt.options.srcDir, relativePath)
if (composablesDirs.some(dir => dir === path || path.startsWith(dir + '/'))) {
await updateTemplates({
filter: template => templates.includes(template.filename)
})
Expand Down
32 changes: 17 additions & 15 deletions packages/nuxt/src/pages/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { mkdir, readFile } from 'node:fs/promises'
import { addComponent, addPlugin, addTemplate, addVitePlugin, addWebpackPlugin, defineNuxtModule, findPath, updateTemplates } from '@nuxt/kit'
import { dirname, join, relative, resolve } from 'pathe'
import { genImport, genObjectFromRawEntries, genString } from 'knitwork'
import escapeRE from 'escape-string-regexp'
import { joinURL } from 'ufo'
import type { NuxtApp, NuxtPage } from 'nuxt/schema'
import { createRoutesContext } from 'unplugin-vue-router'
Expand Down Expand Up @@ -52,12 +51,13 @@ export default defineNuxtModule({

// Restart Nuxt when pages dir is added or removed
const restartPaths = nuxt.options._layers.flatMap(layer => [
join(layer.config.srcDir, 'app/router.options.ts'),
join(layer.config.srcDir, layer.config.dir?.pages || 'pages')
join(layer.config.srcDir || layer.cwd, 'app/router.options.ts'),
join(layer.config.srcDir || layer.cwd, layer.config.dir?.pages || 'pages')
])
nuxt.hooks.hook('builder:watch', async (event, path) => {
const fullPath = join(nuxt.options.srcDir, path)
if (restartPaths.some(path => path === fullPath || fullPath.startsWith(path + '/'))) {

nuxt.hooks.hook('builder:watch', async (event, relativePath) => {
const path = resolve(nuxt.options.srcDir, relativePath)
if (restartPaths.some(p => p === path || path.startsWith(p + '/'))) {
const newSetting = await isPagesEnabled()
if (nuxt.options.pages !== newSetting) {
console.info('Pages', newSetting ? 'enabled' : 'disabled')
Expand Down Expand Up @@ -174,15 +174,17 @@ export default defineNuxtModule({
})

// Regenerate templates when adding or removing pages
nuxt.hook('builder:watch', async (event, path) => {
const dirs = [
nuxt.options.dir.pages,
nuxt.options.dir.layouts,
nuxt.options.dir.middleware
].filter(Boolean)

const pathPattern = new RegExp(`(^|\\/)(${dirs.map(escapeRE).join('|')})/`)
if (event !== 'change' && pathPattern.test(path)) {
const updateTemplatePaths = nuxt.options._layers.flatMap(l => [
join(l.config.srcDir || l.cwd, l.config.dir?.pages || 'pages') + '/',
join(l.config.srcDir || l.cwd, l.config.dir?.layouts || 'layouts') + '/',
join(l.config.srcDir || l.cwd, l.config.dir?.middleware || 'middleware') + '/'
])

nuxt.hook('builder:watch', async (event, relativePath) => {
if (event === 'change') { return }

const path = resolve(nuxt.options.srcDir, relativePath)
if (updateTemplatePaths.some(dir => path.startsWith(dir))) {
await updateTemplates({
filter: template => template.filename === 'routes.mjs'
})
Expand Down

0 comments on commit e2c7edd

Please sign in to comment.