mirror of
https://github.com/nuxt/nuxt.git
synced 2025-01-31 07:40:33 +00:00
perf: allow using @parcel/watcher
for dev watcher (#20179)
This commit is contained in:
parent
83f0103a47
commit
a086af9692
@ -99,6 +99,7 @@
|
|||||||
"vue-router": "^4.1.6"
|
"vue-router": "^4.1.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@parcel/watcher": "^2.1.0",
|
||||||
"@types/estree": "^1.0.1",
|
"@types/estree": "^1.0.1",
|
||||||
"@types/fs-extra": "^11.0.1",
|
"@types/fs-extra": "^11.0.1",
|
||||||
"@types/prompts": "^2.4.4",
|
"@types/prompts": "^2.4.4",
|
||||||
@ -109,8 +110,14 @@
|
|||||||
"vitest": "^0.30.1"
|
"vitest": "^0.30.1"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
"@parcel/watcher": "^2.1.0",
|
||||||
"@types/node": "^14.18.0 || ^16.10.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
"@types/node": "^14.18.0 || ^16.10.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||||
},
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@parcel/watcher": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^14.18.0 || ^16.10.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
"node": "^14.18.0 || ^16.10.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import { pathToFileURL } from 'node:url'
|
import { pathToFileURL } from 'node:url'
|
||||||
|
import type { EventType } from '@parcel/watcher'
|
||||||
import chokidar from 'chokidar'
|
import chokidar from 'chokidar'
|
||||||
import { isIgnored, tryResolveModule } from '@nuxt/kit'
|
import { isIgnored, tryResolveModule } from '@nuxt/kit'
|
||||||
|
import { interopDefault } from 'mlly'
|
||||||
import { debounce } from 'perfect-debounce'
|
import { debounce } from 'perfect-debounce'
|
||||||
import { normalize } from 'pathe'
|
import { normalize } from 'pathe'
|
||||||
import type { Nuxt } from 'nuxt/schema'
|
import type { Nuxt } from 'nuxt/schema'
|
||||||
@ -43,7 +45,45 @@ export async function build (nuxt: Nuxt) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function watch (nuxt: Nuxt) {
|
const watchEvents: Record<EventType, 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir'> = {
|
||||||
|
create: 'add',
|
||||||
|
delete: 'unlink',
|
||||||
|
update: 'change'
|
||||||
|
}
|
||||||
|
|
||||||
|
async function watch (nuxt: Nuxt) {
|
||||||
|
if (nuxt.options.experimental.watcher === 'parcel') {
|
||||||
|
if (nuxt.options.debug) {
|
||||||
|
console.time('[nuxt] builder:parcel:watch')
|
||||||
|
}
|
||||||
|
const watcherPath = await tryResolveModule('@parcel/watcher', [nuxt.options.rootDir, ...nuxt.options.modulesDir])
|
||||||
|
if (watcherPath) {
|
||||||
|
const { subscribe } = await import(pathToFileURL(watcherPath).href).then(interopDefault) as typeof import('@parcel/watcher')
|
||||||
|
for (const layer of nuxt.options._layers) {
|
||||||
|
if (!layer.config.srcDir) { continue }
|
||||||
|
const watcher = subscribe(layer.config.srcDir, (err, events) => {
|
||||||
|
if (err) { return }
|
||||||
|
for (const event of events) {
|
||||||
|
if (isIgnored(event.path)) { continue }
|
||||||
|
nuxt.callHook('builder:watch', watchEvents[event.type], normalize(event.path))
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
ignore: [
|
||||||
|
...nuxt.options.ignore,
|
||||||
|
'.nuxt',
|
||||||
|
'node_modules'
|
||||||
|
]
|
||||||
|
})
|
||||||
|
watcher.then((subscription) => {
|
||||||
|
console.timeEnd('[nuxt] builder:parcel:watch')
|
||||||
|
nuxt.hook('close', () => subscription.unsubscribe())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.warn('[nuxt] falling back to `chokidar` as `@parcel/watcher` cannot be resolved in your project.')
|
||||||
|
}
|
||||||
|
|
||||||
if (nuxt.options.debug) {
|
if (nuxt.options.debug) {
|
||||||
console.time('[nuxt] builder:chokidar:watch')
|
console.time('[nuxt] builder:chokidar:watch')
|
||||||
}
|
}
|
||||||
@ -65,7 +105,6 @@ function watch (nuxt: Nuxt) {
|
|||||||
|
|
||||||
watcher.on('all', (event, path) => nuxt.callHook('builder:watch', event, normalize(path)))
|
watcher.on('all', (event, path) => nuxt.callHook('builder:watch', event, normalize(path)))
|
||||||
nuxt.hook('close', () => watcher.close())
|
nuxt.hook('close', () => watcher.close())
|
||||||
return watcher
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function bundle (nuxt: Nuxt) {
|
async function bundle (nuxt: Nuxt) {
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import { existsSync } from 'node:fs'
|
import { existsSync } from 'node:fs'
|
||||||
import { mkdir, writeFile } from 'node:fs/promises'
|
import { mkdir, writeFile } from 'node:fs/promises'
|
||||||
|
import { pathToFileURL } from 'node:url'
|
||||||
import { dirname, resolve } from 'pathe'
|
import { dirname, resolve } from 'pathe'
|
||||||
import chokidar from 'chokidar'
|
import chokidar from 'chokidar'
|
||||||
|
import { interopDefault } from 'mlly'
|
||||||
import { defu } from 'defu'
|
import { defu } from 'defu'
|
||||||
import { debounce } from 'perfect-debounce'
|
import { debounce } from 'perfect-debounce'
|
||||||
import { createResolver, defineNuxtModule } from '@nuxt/kit'
|
import { createResolver, defineNuxtModule, tryResolveModule } from '@nuxt/kit'
|
||||||
import {
|
import {
|
||||||
generateTypes,
|
generateTypes,
|
||||||
resolveSchema as resolveUntypedSchema
|
resolveSchema as resolveUntypedSchema
|
||||||
@ -57,6 +59,26 @@ export default defineNuxtModule({
|
|||||||
|
|
||||||
// Watch for schema changes in development mode
|
// Watch for schema changes in development mode
|
||||||
if (nuxt.options.dev) {
|
if (nuxt.options.dev) {
|
||||||
|
const onChange = debounce(async () => {
|
||||||
|
schema = await resolveSchema()
|
||||||
|
await writeSchema(schema)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (nuxt.options.experimental.watcher === 'parcel') {
|
||||||
|
const watcherPath = await tryResolveModule('@parcel/watcher', [nuxt.options.rootDir, ...nuxt.options.modulesDir])
|
||||||
|
if (watcherPath) {
|
||||||
|
const { subscribe } = await import(pathToFileURL(watcherPath).href).then(interopDefault) as typeof import('@parcel/watcher')
|
||||||
|
for (const layer of nuxt.options._layers) {
|
||||||
|
const subscription = await subscribe(layer.config.rootDir, onChange, {
|
||||||
|
ignore: ['!nuxt.schema.*']
|
||||||
|
})
|
||||||
|
nuxt.hook('close', () => subscription.unsubscribe())
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.warn('[nuxt] falling back to `chokidar` as `@parcel/watcher` cannot be resolved in your project.')
|
||||||
|
}
|
||||||
|
|
||||||
const filesToWatch = await Promise.all(nuxt.options._layers.map(layer =>
|
const filesToWatch = await Promise.all(nuxt.options._layers.map(layer =>
|
||||||
resolver.resolve(layer.config.rootDir, 'nuxt.schema.*')
|
resolver.resolve(layer.config.rootDir, 'nuxt.schema.*')
|
||||||
))
|
))
|
||||||
@ -64,10 +86,6 @@ export default defineNuxtModule({
|
|||||||
...nuxt.options.watchers.chokidar,
|
...nuxt.options.watchers.chokidar,
|
||||||
ignoreInitial: true
|
ignoreInitial: true
|
||||||
})
|
})
|
||||||
const onChange = debounce(async () => {
|
|
||||||
schema = await resolveSchema()
|
|
||||||
await writeSchema(schema)
|
|
||||||
})
|
|
||||||
watcher.on('all', onChange)
|
watcher.on('all', onChange)
|
||||||
nuxt.hook('close', () => watcher.close())
|
nuxt.hook('close', () => watcher.close())
|
||||||
}
|
}
|
||||||
|
@ -345,6 +345,7 @@ export default defineUntypedSchema({
|
|||||||
'**/*.{spec,test}.{js,ts,jsx,tsx}', // ignore tests
|
'**/*.{spec,test}.{js,ts,jsx,tsx}', // ignore tests
|
||||||
'**/*.d.ts', // ignore type declarations
|
'**/*.d.ts', // ignore type declarations
|
||||||
'.output',
|
'.output',
|
||||||
|
'.git',
|
||||||
await get('ignorePrefix') && `**/${await get('ignorePrefix')}*.*`
|
await get('ignorePrefix') && `**/${await get('ignorePrefix')}*.*`
|
||||||
].concat(val).filter(Boolean)
|
].concat(val).filter(Boolean)
|
||||||
},
|
},
|
||||||
|
@ -161,5 +161,19 @@ export default defineUntypedSchema({
|
|||||||
|
|
||||||
/** Resolve `~`, `~~`, `@` and `@@` aliases located within layers with respect to their layer source and root directories. */
|
/** Resolve `~`, `~~`, `@` and `@@` aliases located within layers with respect to their layer source and root directories. */
|
||||||
localLayerAliases: true,
|
localLayerAliases: true,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set an alternative watcher that will be used as the watching service for Nuxt.
|
||||||
|
*
|
||||||
|
* Nuxt uses 'chokidar' by default, but by setting this to `parcel` it will use
|
||||||
|
* `@parcel/watcher` instead. This may improve performance in large projects or
|
||||||
|
* on Windows platforms.
|
||||||
|
*
|
||||||
|
* @see https://github.com/paulmillr/chokidar
|
||||||
|
* @see https://github.com/parcel-bundler/watcher
|
||||||
|
* @default chokidar
|
||||||
|
* @type {'chokidar' | 'parcel'}
|
||||||
|
*/
|
||||||
|
watcher: 'chokidar'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -687,6 +687,9 @@ importers:
|
|||||||
specifier: ^4.1.6
|
specifier: ^4.1.6
|
||||||
version: 4.1.6(vue@3.2.47)
|
version: 4.1.6(vue@3.2.47)
|
||||||
devDependencies:
|
devDependencies:
|
||||||
|
'@parcel/watcher':
|
||||||
|
specifier: ^2.1.0
|
||||||
|
version: 2.1.0
|
||||||
'@types/estree':
|
'@types/estree':
|
||||||
specifier: ^1.0.1
|
specifier: ^1.0.1
|
||||||
version: 1.0.1
|
version: 1.0.1
|
||||||
@ -2133,6 +2136,17 @@ packages:
|
|||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@parcel/watcher@2.1.0:
|
||||||
|
resolution: {integrity: sha512-8s8yYjd19pDSsBpbkOHnT6Z2+UJSuLQx61pCFM0s5wSRvKCEMDjd/cHY3/GI1szHIWbpXpsJdg3V6ISGGx9xDw==}
|
||||||
|
engines: {node: '>= 10.0.0'}
|
||||||
|
requiresBuild: true
|
||||||
|
dependencies:
|
||||||
|
is-glob: 4.0.3
|
||||||
|
micromatch: 4.0.5
|
||||||
|
node-addon-api: 3.2.1
|
||||||
|
node-gyp-build: 4.6.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@pkgr/utils@2.3.1:
|
/@pkgr/utils@2.3.1:
|
||||||
resolution: {integrity: sha512-wfzX8kc1PMyUILA+1Z/EqoE4UCXGy0iRGMhPwdfae1+f0OXlLqCk+By+aMzgJBzR9AzS4CDizioG6Ss1gvAFJw==}
|
resolution: {integrity: sha512-wfzX8kc1PMyUILA+1Z/EqoE4UCXGy0iRGMhPwdfae1+f0OXlLqCk+By+aMzgJBzR9AzS4CDizioG6Ss1gvAFJw==}
|
||||||
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
|
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
|
||||||
@ -7238,6 +7252,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==}
|
resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/node-addon-api@3.2.1:
|
||||||
|
resolution: {integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/node-domexception@1.0.0:
|
/node-domexception@1.0.0:
|
||||||
resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
|
resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
|
||||||
engines: {node: '>=10.5.0'}
|
engines: {node: '>=10.5.0'}
|
||||||
|
Loading…
Reference in New Issue
Block a user