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