mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-21 13:15:12 +00:00
perf(kit,nuxt): use fdir
to speed up fs scanning
This commit is contained in:
parent
d9e55546d9
commit
d7718f4474
@ -68,7 +68,7 @@
|
||||
"eslint-plugin-perfectionist": "2.11.0",
|
||||
"eslint-typegen": "0.2.4",
|
||||
"execa": "9.2.0",
|
||||
"globby": "14.0.1",
|
||||
"fdir": "6.1.1",
|
||||
"h3": "1.12.0",
|
||||
"happy-dom": "14.12.3",
|
||||
"jiti": "1.21.6",
|
||||
@ -79,6 +79,7 @@
|
||||
"nuxt-content-twoslash": "0.0.10",
|
||||
"ofetch": "1.3.4",
|
||||
"pathe": "1.1.2",
|
||||
"picomatch": "^4.0.2",
|
||||
"playwright-core": "1.44.1",
|
||||
"rimraf": "5.0.7",
|
||||
"semver": "7.6.2",
|
||||
|
@ -31,13 +31,14 @@
|
||||
"consola": "^3.2.3",
|
||||
"defu": "^6.1.4",
|
||||
"destr": "^2.0.3",
|
||||
"globby": "^14.0.1",
|
||||
"fdir": "^6.1.1",
|
||||
"hash-sum": "^2.0.0",
|
||||
"ignore": "^5.3.1",
|
||||
"jiti": "^1.21.6",
|
||||
"klona": "^2.0.6",
|
||||
"mlly": "^1.7.1",
|
||||
"pathe": "^1.1.2",
|
||||
"picomatch": "^4.0.2",
|
||||
"pkg-types": "^1.1.1",
|
||||
"scule": "^1.3.0",
|
||||
"semver": "^7.6.2",
|
||||
@ -48,6 +49,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/hash-sum": "1.0.2",
|
||||
"@types/picomatch": "^2.3.3",
|
||||
"@types/semver": "7.5.8",
|
||||
"nitropack": "2.9.6",
|
||||
"unbuild": "latest",
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { existsSync, promises as fsp } from 'node:fs'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { basename, dirname, isAbsolute, join, normalize, resolve } from 'pathe'
|
||||
import { globby } from 'globby'
|
||||
import { fdir } from 'fdir'
|
||||
import { resolvePath as _resolvePath } from 'mlly'
|
||||
import { resolveAlias as _resolveAlias } from 'pathe/utils'
|
||||
import { tryUseNuxt } from './context'
|
||||
@ -210,7 +210,7 @@ function existsInVFS (path: string, nuxt = tryUseNuxt()) {
|
||||
|
||||
export async function resolveFiles (path: string, pattern: string | string[], opts: { followSymbolicLinks?: boolean } = {}) {
|
||||
const files: string[] = []
|
||||
for (const file of await globby(pattern, { cwd: path, followSymbolicLinks: opts.followSymbolicLinks ?? true })) {
|
||||
for (const file of await new fdir().withRelativePaths().globWithOptions(toArray(pattern), { dot: true }).crawl(path).withPromise()) {
|
||||
const p = resolve(path, file)
|
||||
if (!isIgnored(p)) {
|
||||
files.push(p)
|
||||
|
@ -79,7 +79,7 @@
|
||||
"esbuild": "^0.21.5",
|
||||
"escape-string-regexp": "^5.0.0",
|
||||
"estree-walker": "^3.0.3",
|
||||
"globby": "^14.0.1",
|
||||
"fdir": "^6.1.1",
|
||||
"h3": "^1.12.0",
|
||||
"hookable": "^5.5.3",
|
||||
"ignore": "^5.3.1",
|
||||
@ -95,6 +95,7 @@
|
||||
"ohash": "^1.1.3",
|
||||
"pathe": "^1.1.2",
|
||||
"perfect-debounce": "^1.0.0",
|
||||
"picomatch": "^4.0.2",
|
||||
"pkg-types": "^1.1.1",
|
||||
"radix3": "^1.1.2",
|
||||
"scule": "^1.3.0",
|
||||
@ -121,6 +122,7 @@
|
||||
"@nuxt/ui-templates": "1.3.4",
|
||||
"@parcel/watcher": "2.4.1",
|
||||
"@types/estree": "1.0.5",
|
||||
"@types/picomatch": "^2.3.3",
|
||||
"@vitejs/plugin-vue": "5.0.4",
|
||||
"@vue/compiler-sfc": "3.4.29",
|
||||
"unbuild": "latest",
|
||||
|
@ -1,12 +1,13 @@
|
||||
import { readdir } from 'node:fs/promises'
|
||||
import { basename, dirname, extname, join, relative } from 'pathe'
|
||||
import { globby } from 'globby'
|
||||
import { fdir } from 'fdir'
|
||||
import { kebabCase, pascalCase, splitByCase } from 'scule'
|
||||
import { isIgnored, logger, useNuxt } from '@nuxt/kit'
|
||||
import { withTrailingSlash } from 'ufo'
|
||||
import type { Component, ComponentsDir } from 'nuxt/schema'
|
||||
|
||||
import { resolveComponentNameSegments } from '../core/utils'
|
||||
import { toArray } from '../utils'
|
||||
|
||||
/**
|
||||
* Scan the components inside different components folders
|
||||
@ -32,7 +33,8 @@ export async function scanComponents (dirs: ComponentsDir[], srcDir: string): Pr
|
||||
// A map from resolved path to component name (used for making duplicate warning message)
|
||||
const resolvedNames = new Map<string, string>()
|
||||
|
||||
const files = (await globby(dir.pattern!, { cwd: dir.path, ignore: dir.ignore })).sort()
|
||||
const patterns = toArray(dir.pattern!)
|
||||
const files = (await new fdir().withRelativePaths().globWithOptions(patterns, { ignore: dir.ignore, dot: true }).crawl(dir.path).withPromise()).sort()
|
||||
|
||||
// Check if the directory exists (globby will otherwise read it case insensitively on MacOS)
|
||||
if (files.length) {
|
||||
|
@ -86,9 +86,9 @@ importers:
|
||||
execa:
|
||||
specifier: 9.2.0
|
||||
version: 9.2.0
|
||||
globby:
|
||||
specifier: 14.0.1
|
||||
version: 14.0.1
|
||||
fdir:
|
||||
specifier: 6.1.1
|
||||
version: 6.1.1(picomatch@4.0.2)
|
||||
h3:
|
||||
specifier: 1.12.0
|
||||
version: 1.12.0
|
||||
@ -119,6 +119,9 @@ importers:
|
||||
pathe:
|
||||
specifier: 1.1.2
|
||||
version: 1.1.2
|
||||
picomatch:
|
||||
specifier: ^4.0.2
|
||||
version: 4.0.2
|
||||
playwright-core:
|
||||
specifier: 1.44.1
|
||||
version: 1.44.1
|
||||
@ -170,9 +173,9 @@ importers:
|
||||
destr:
|
||||
specifier: ^2.0.3
|
||||
version: 2.0.3
|
||||
globby:
|
||||
specifier: ^14.0.1
|
||||
version: 14.0.1
|
||||
fdir:
|
||||
specifier: ^6.1.1
|
||||
version: 6.1.1(picomatch@4.0.2)
|
||||
hash-sum:
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0
|
||||
@ -191,6 +194,9 @@ importers:
|
||||
pathe:
|
||||
specifier: ^1.1.2
|
||||
version: 1.1.2
|
||||
picomatch:
|
||||
specifier: ^4.0.2
|
||||
version: 4.0.2
|
||||
pkg-types:
|
||||
specifier: ^1.1.1
|
||||
version: 1.1.1
|
||||
@ -216,6 +222,9 @@ importers:
|
||||
'@types/hash-sum':
|
||||
specifier: 1.0.2
|
||||
version: 1.0.2
|
||||
'@types/picomatch':
|
||||
specifier: ^2.3.3
|
||||
version: 2.3.3
|
||||
'@types/semver':
|
||||
specifier: 7.5.8
|
||||
version: 7.5.8
|
||||
@ -300,9 +309,9 @@ importers:
|
||||
estree-walker:
|
||||
specifier: ^3.0.3
|
||||
version: 3.0.3
|
||||
globby:
|
||||
specifier: ^14.0.1
|
||||
version: 14.0.1
|
||||
fdir:
|
||||
specifier: ^6.1.1
|
||||
version: 6.1.1(picomatch@4.0.2)
|
||||
h3:
|
||||
specifier: ^1.12.0
|
||||
version: 1.12.0
|
||||
@ -348,6 +357,9 @@ importers:
|
||||
perfect-debounce:
|
||||
specifier: ^1.0.0
|
||||
version: 1.0.0
|
||||
picomatch:
|
||||
specifier: ^4.0.2
|
||||
version: 4.0.2
|
||||
pkg-types:
|
||||
specifier: ^1.1.1
|
||||
version: 1.1.1
|
||||
@ -421,6 +433,9 @@ importers:
|
||||
'@types/estree':
|
||||
specifier: 1.0.5
|
||||
version: 1.0.5
|
||||
'@types/picomatch':
|
||||
specifier: ^2.3.3
|
||||
version: 2.3.3
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: 5.0.4
|
||||
version: 5.0.4(vite@5.3.1(@types/node@20.14.7)(sass@1.69.4)(terser@5.27.0))(vue@3.4.29(typescript@5.5.2))
|
||||
@ -572,9 +587,9 @@ importers:
|
||||
execa:
|
||||
specifier: 9.2.0
|
||||
version: 9.2.0
|
||||
globby:
|
||||
specifier: 14.0.1
|
||||
version: 14.0.1
|
||||
fdir:
|
||||
specifier: 6.1.1
|
||||
version: 6.1.1(picomatch@4.0.2)
|
||||
html-minifier:
|
||||
specifier: 4.0.0
|
||||
version: 4.0.0
|
||||
@ -587,6 +602,9 @@ importers:
|
||||
pathe:
|
||||
specifier: 1.1.2
|
||||
version: 1.1.2
|
||||
picomatch:
|
||||
specifier: 4.0.2
|
||||
version: 4.0.2
|
||||
prettier:
|
||||
specifier: 3.3.2
|
||||
version: 3.3.2
|
||||
@ -2520,6 +2538,9 @@ packages:
|
||||
'@types/normalize-package-data@2.4.4':
|
||||
resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==}
|
||||
|
||||
'@types/picomatch@2.3.3':
|
||||
resolution: {integrity: sha512-Yll76ZHikRFCyz/pffKGjrCwe/le2CDwOP5F210KQo27kpRE46U2rDnzikNlVn6/ezH3Mhn46bJMTfeVTtcYMg==}
|
||||
|
||||
'@types/pify@5.0.4':
|
||||
resolution: {integrity: sha512-gxKJ1Aw8LbyCsCQWIsip9bYKJCNsKHMoZoQMAe2IWH7U7hgp/l6TvJpbFvu8ZlGBimjZZNvEx2S1ZQlj02ayNQ==}
|
||||
|
||||
@ -4264,6 +4285,14 @@ packages:
|
||||
fastq@1.15.0:
|
||||
resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==}
|
||||
|
||||
fdir@6.1.1:
|
||||
resolution: {integrity: sha512-QfKBVg453Dyn3mr0Q0O+Tkr1r79lOTAKSi9f/Ot4+qVEwxWhav2Z+SudrG9vQjM2aYRMQQZ2/Q1zdA8ACM1pDg==}
|
||||
peerDependencies:
|
||||
picomatch: 3.x
|
||||
peerDependenciesMeta:
|
||||
picomatch:
|
||||
optional: true
|
||||
|
||||
figures@3.2.0:
|
||||
resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==}
|
||||
engines: {node: '>=8'}
|
||||
@ -9186,6 +9215,8 @@ snapshots:
|
||||
|
||||
'@types/normalize-package-data@2.4.4': {}
|
||||
|
||||
'@types/picomatch@2.3.3': {}
|
||||
|
||||
'@types/pify@5.0.4': {}
|
||||
|
||||
'@types/pug@2.0.10': {}
|
||||
@ -11518,6 +11549,10 @@ snapshots:
|
||||
dependencies:
|
||||
reusify: 1.0.4
|
||||
|
||||
fdir@6.1.1(picomatch@4.0.2):
|
||||
optionalDependencies:
|
||||
picomatch: 4.0.2
|
||||
|
||||
figures@3.2.0:
|
||||
dependencies:
|
||||
escape-string-regexp: 1.0.5
|
||||
|
@ -2,8 +2,8 @@ import { fileURLToPath } from 'node:url'
|
||||
import fsp from 'node:fs/promises'
|
||||
import { beforeAll, describe, expect, it } from 'vitest'
|
||||
import { execaCommand } from 'execa'
|
||||
import { globby } from 'globby'
|
||||
import { join } from 'pathe'
|
||||
import { fdir } from 'fdir'
|
||||
import { join, resolve } from 'pathe'
|
||||
|
||||
describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM_CI)('minimal nuxt application', () => {
|
||||
const rootDir = fileURLToPath(new URL('./fixtures/minimal', import.meta.url))
|
||||
@ -31,7 +31,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM
|
||||
it('default server bundle size', async () => {
|
||||
const serverDir = join(rootDir, '.output/server')
|
||||
|
||||
const serverStats = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir)
|
||||
const serverStats = await analyzeSizes('**/*.mjs', serverDir, { excludeNodeModules: true })
|
||||
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot(`"210k"`)
|
||||
|
||||
const modules = await analyzeSizes('node_modules/**/*', serverDir)
|
||||
@ -71,7 +71,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM
|
||||
it('default server bundle size (inlined vue modules)', async () => {
|
||||
const serverDir = join(rootDir, '.output-inline/server')
|
||||
|
||||
const serverStats = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir)
|
||||
const serverStats = await analyzeSizes('**/*.mjs', serverDir, { excludeNodeModules: true })
|
||||
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot(`"531k"`)
|
||||
|
||||
const modules = await analyzeSizes('node_modules/**/*', serverDir)
|
||||
@ -94,11 +94,16 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM
|
||||
})
|
||||
})
|
||||
|
||||
async function analyzeSizes (pattern: string | string[], rootDir: string) {
|
||||
const files: string[] = await globby(pattern, { cwd: rootDir })
|
||||
async function analyzeSizes (pattern: string | string[], rootDir: string, opts: { excludeNodeModules?: boolean } = {}) {
|
||||
const patterns = Array.isArray(pattern) ? pattern : [pattern]
|
||||
const files: string[] = new fdir({
|
||||
resolveSymlinks: true,
|
||||
exclude: p => opts.excludeNodeModules ? p.includes('node_modules') : false
|
||||
})
|
||||
.withRelativePaths().globWithOptions(patterns, { dot: true }).crawl(rootDir).sync()
|
||||
let totalBytes = 0
|
||||
for (const file of files) {
|
||||
const path = join(rootDir, file)
|
||||
const path = resolve(rootDir, file)
|
||||
const isSymlink = (await fsp.lstat(path).catch(() => null))?.isSymbolicLink()
|
||||
|
||||
if (!isSymlink) {
|
||||
|
Loading…
Reference in New Issue
Block a user