diff --git a/package.json b/package.json index 809ba30f..efdff6b0 100644 --- a/package.json +++ b/package.json @@ -20,17 +20,15 @@ "@aklinker1/check": "^2.2.0", "@commitlint/config-conventional": "^20.4.3", "@commitlint/types": "^20.4.3", - "@types/fs-extra": "^11.0.4", "@types/semver": "^7.7.1", "@vitest/coverage-v8": "^4.0.18", "changelogen": "^0.6.2", "consola": "^3.4.2", "feed": "^5.2.0", - "fs-extra": "^11.3.4", - "nano-staged": "^0.8.0", "markdown-it-footnote": "^4.0.0", "markdownlint-cli": "^0.48.0", "nano-spawn": "^2.0.0", + "nano-staged": "^0.8.0", "p-map": "^7.0.4", "prettier": "^3.8.1", "prettier-plugin-jsdoc": "^1.8.0", diff --git a/packages/auto-icons/package.json b/packages/auto-icons/package.json index adc628f1..f5c2e657 100644 --- a/packages/auto-icons/package.json +++ b/packages/auto-icons/package.json @@ -48,7 +48,6 @@ }, "dependencies": { "defu": "^6.1.4", - "fs-extra": "^11.3.4", "sharp": "^0.34.5" }, "devDependencies": { diff --git a/packages/auto-icons/src/__test__/index.test.ts b/packages/auto-icons/src/__test__/index.test.ts index abe1732c..847bdc32 100644 --- a/packages/auto-icons/src/__test__/index.test.ts +++ b/packages/auto-icons/src/__test__/index.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect, vi, beforeEach, Mock } from 'vitest'; import { resolve } from 'node:path'; -import * as fsExtra from 'fs-extra'; +import * as fsPromises from 'node:fs/promises'; import sharp from 'sharp'; import type { Wxt, UserManifest } from 'wxt'; @@ -9,9 +9,9 @@ import autoIconsModule from '../index'; import type { AutoIconsOptions } from '../index'; // Mock dependencies -vi.mock('fs-extra', () => ({ - ensureDir: vi.fn(), - pathExists: vi.fn(), +vi.mock('node:fs/promises', () => ({ + mkdir: vi.fn(), + access: vi.fn(), })); vi.mock('sharp', () => ({ @@ -86,8 +86,8 @@ describe('auto-icons module', () => { vi.mocked(sharp).mockReturnValue( mockSharpInstance as unknown as sharp.Sharp, ); - vi.mocked(fsExtra.pathExists).mockResolvedValue(true as any); - vi.mocked(fsExtra.ensureDir).mockResolvedValue(undefined as any); + vi.mocked(fsPromises.access).mockResolvedValue(undefined); + vi.mocked(fsPromises.mkdir).mockResolvedValue(undefined as any); }); describe('module setup', () => { @@ -158,7 +158,7 @@ describe('auto-icons module', () => { }); it('should warn when base icon not found', async () => { - vi.mocked(fsExtra.pathExists).mockResolvedValue(false as any); + vi.mocked(fsPromises.access).mockRejectedValue(new Error('ENOENT')); const options: AutoIconsOptions = { enabled: true, @@ -293,8 +293,9 @@ describe('auto-icons module', () => { expect(mockSharpInstance.resize).toHaveBeenCalledWith(32); expect(mockSharpInstance.resize).toHaveBeenCalledWith(16); - expect(fsExtra.ensureDir).toHaveBeenCalledWith( + expect(fsPromises.mkdir).toHaveBeenCalledWith( resolve('/mock/dist', 'icons'), + { recursive: true }, ); expect(output.publicAssets).toEqual([ @@ -514,7 +515,7 @@ describe('auto-icons module', () => { }; // Make ensureDir throw an error - vi.mocked(fsExtra.ensureDir).mockRejectedValue( + vi.mocked(fsPromises.mkdir).mockRejectedValue( new Error('Directory creation failed'), ); @@ -530,7 +531,7 @@ describe('auto-icons module', () => { if (buildHook) { await buildHook(mockWxt as unknown as Wxt, output); // But ensureDir should have been called - expect(fsExtra.ensureDir).toHaveBeenCalled(); + expect(fsPromises.mkdir).toHaveBeenCalled(); } }); diff --git a/packages/auto-icons/src/index.ts b/packages/auto-icons/src/index.ts index ac461146..d66c65de 100644 --- a/packages/auto-icons/src/index.ts +++ b/packages/auto-icons/src/index.ts @@ -3,7 +3,7 @@ import { defineWxtModule } from 'wxt/modules'; import { resolve, relative } from 'node:path'; import defu from 'defu'; import sharp from 'sharp'; -import { ensureDir, pathExists } from 'fs-extra'; +import { access, mkdir } from 'node:fs/promises'; export default defineWxtModule({ name: '@wxt-dev/auto-icons', @@ -37,7 +37,11 @@ export default defineWxtModule({ if (!parsedOptions.enabled) return wxt.logger.warn(`\`[auto-icons]\` ${this.name} disabled`); - if (!(await pathExists(resolvedPath))) { + const iconExists = await access(resolvedPath).then( + () => true, + () => false, + ); + if (!iconExists) { return wxt.logger.warn( `\`[auto-icons]\` Skipping icon generation, no base icon found at ${relative(process.cwd(), resolvedPath)}`, ); @@ -91,7 +95,7 @@ export default defineWxtModule({ } } - ensureDir(resolve(outputFolder, 'icons')); + mkdir(resolve(outputFolder, 'icons'), { recursive: true }); await resizedImage.toFile(resolve(outputFolder, `icons/${size}.png`)); output.publicAssets.push({ diff --git a/packages/browser/package.json b/packages/browser/package.json index 387dacf5..5033e78c 100644 --- a/packages/browser/package.json +++ b/packages/browser/package.json @@ -24,7 +24,7 @@ ], "devDependencies": { "@types/chrome": "0.1.37", - "fs-extra": "^11.3.4", + "@types/node": "^20.0.0", "nano-spawn": "^2.0.0", "typescript": "^5.9.3", "vitest": "^4.0.18" diff --git a/packages/browser/scripts/generate.ts b/packages/browser/scripts/generate.ts index ddbf1d81..5ba1fedf 100644 --- a/packages/browser/scripts/generate.ts +++ b/packages/browser/scripts/generate.ts @@ -1,5 +1,5 @@ import spawn from 'nano-spawn'; -import fs from 'fs-extra'; +import { mkdir, readdir, readFile, writeFile } from 'node:fs/promises'; import { fileURLToPath } from 'node:url'; import { dirname, join, resolve, sep } from 'node:path'; import { sep as posixSep } from 'node:path/posix'; @@ -17,8 +17,8 @@ const pkgJsonPath = fileURLToPath( import.meta.resolve('@types/chrome/package.json'), ); const pkgDir = dirname(pkgJsonPath); -const pkgJson = await fs.readJson(pkgJsonPath); -const pkgJsonTemplate = await fs.readFile('templates/package.json', 'utf8'); +const pkgJson = JSON.parse(await readFile(pkgJsonPath, 'utf-8')); +const pkgJsonTemplate = await readFile('templates/package.json', 'utf8'); const newPkgJson = JSON.parse( pkgJsonTemplate.replaceAll('{{chromeTypesVersion}}', pkgJson.version), ); @@ -27,7 +27,7 @@ newPkgJson.peerDependencies = pkgJson.peerDependencies; newPkgJson.peerDependenciesMeta = pkgJson.peerDependenciesMeta; const outPkgJsonPath = resolve('package.json'); -await fs.writeJson(outPkgJsonPath, newPkgJson); +await writeFile(outPkgJsonPath, JSON.stringify(newPkgJson, null, 2)); await spawn('pnpm', ['-w', 'prettier', '--write', outPkgJsonPath]); // Generate declaration files @@ -35,7 +35,7 @@ await spawn('pnpm', ['-w', 'prettier', '--write', outPkgJsonPath]); console.log('Generating declaration files'); const outDir = resolve('src/gen'); const declarationFileMapping = ( - await fs.readdir(pkgDir, { + await readdir(pkgDir, { recursive: true, encoding: 'utf8', }) @@ -50,11 +50,11 @@ const declarationFileMapping = ( })); for (const { file, srcPath, destPath } of declarationFileMapping) { - const content = await fs.readFile(srcPath, 'utf8'); + const content = await readFile(srcPath, 'utf8'); const transformedContent = transformFile(file, content); const destDir = dirname(destPath); - await fs.mkdir(destDir, { recursive: true }); - await fs.writeFile(destPath, transformedContent); + await mkdir(destDir, { recursive: true }); + await writeFile(destPath, transformedContent); console.log(` \x1b[2m-\x1b[0m \x1b[36m${file}\x1b[0m`); } diff --git a/packages/browser/templates/package.json b/packages/browser/templates/package.json index f303799f..e51284d9 100644 --- a/packages/browser/templates/package.json +++ b/packages/browser/templates/package.json @@ -24,7 +24,7 @@ ], "devDependencies": { "@types/chrome": "{{chromeTypesVersion}}", - "fs-extra": "^11.3.4", + "@types/node": "^20.0.0", "nano-spawn": "^2.0.0", "typescript": "^5.9.3", "vitest": "^4.0.18" diff --git a/packages/wxt/e2e/tests/init.test.ts b/packages/wxt/e2e/tests/init.test.ts index d123b583..6fed800d 100644 --- a/packages/wxt/e2e/tests/init.test.ts +++ b/packages/wxt/e2e/tests/init.test.ts @@ -1,8 +1,8 @@ -import { describe, it, expect } from 'vitest'; -import { TestProject, WXT_PACKAGE_DIR } from '../utils'; import spawn from 'nano-spawn'; +import { mkdir, writeFile } from 'node:fs/promises'; import { glob } from 'tinyglobby'; -import { mkdir, writeJson } from 'fs-extra'; +import { describe, expect, it } from 'vitest'; +import { TestProject, WXT_PACKAGE_DIR } from '../utils'; describe('Init command', () => { it('should download and create a template', async () => { @@ -53,7 +53,7 @@ describe('Init command', () => { it('should throw an error if the directory is not empty', async () => { const project = new TestProject(); await mkdir(project.root, { recursive: true }); - await writeJson(project.resolvePath('package.json'), {}); + await writeFile(project.resolvePath('package.json'), JSON.stringify({})); await expect(() => spawn( diff --git a/packages/wxt/e2e/tests/modules.test.ts b/packages/wxt/e2e/tests/modules.test.ts index af3ee0cf..56ef0384 100644 --- a/packages/wxt/e2e/tests/modules.test.ts +++ b/packages/wxt/e2e/tests/modules.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect, vi } from 'vitest'; import { TestProject } from '../utils'; import type { InlineConfig, UnlistedScriptEntrypoint } from '../../src'; -import { readFile } from 'fs-extra'; +import { readFile } from 'node:fs/promises'; import { normalizePath } from '../../src'; describe('Module Helpers', () => { diff --git a/packages/wxt/e2e/tests/zip.test.ts b/packages/wxt/e2e/tests/zip.test.ts index 5a721e84..87e5416e 100644 --- a/packages/wxt/e2e/tests/zip.test.ts +++ b/packages/wxt/e2e/tests/zip.test.ts @@ -2,7 +2,7 @@ import { describe, expect, it } from 'vitest'; import { TestProject } from '../utils'; import extract from 'extract-zip'; import spawn from 'nano-spawn'; -import { readFile, writeFile } from 'fs-extra'; +import { readFile, writeFile } from 'node:fs/promises'; process.env.WXT_PNPM_IGNORE_WORKSPACE = 'true'; diff --git a/packages/wxt/e2e/utils.ts b/packages/wxt/e2e/utils.ts index 62803762..0a5f4bdc 100644 --- a/packages/wxt/e2e/utils.ts +++ b/packages/wxt/e2e/utils.ts @@ -1,8 +1,8 @@ -import { glob } from 'tinyglobby'; -import fs, { mkdir } from 'fs-extra'; import merge from 'lodash.merge'; import spawn from 'nano-spawn'; +import { mkdir, readFile, writeFile } from 'node:fs/promises'; import { dirname, relative, resolve } from 'path'; +import { glob } from 'tinyglobby'; import { InlineConfig, UserConfig, @@ -12,6 +12,7 @@ import { zip, } from '../src'; import { normalizePath } from '../src/core/utils'; +import { pathExists, readJson } from '../src/core/utils/fs'; // Run "pnpm wxt" to use the "wxt" dev script, not the "wxt" binary from the // wxt package. This uses the TS files instead of the compiled JS package @@ -119,8 +120,8 @@ export class TestProject { const [name, content] = file; const filePath = this.resolvePath(name); const fileDir = dirname(filePath); - await fs.ensureDir(fileDir); - await fs.writeFile(filePath, content ?? '', 'utf-8'); + await mkdir(fileDir, { recursive: true }); + await writeFile(filePath, content ?? '', 'utf-8'); } // Only install dependencies if the project has custom ones - otherwise the @@ -183,17 +184,19 @@ export class TestProject { const absolutePath = this.resolvePath(path); return [ normalizePath(relative(this.root, absolutePath)), - ignoreContents ? '' : await fs.readFile(absolutePath), + ignoreContents + ? '' + : await readFile(absolutePath, 'utf-8'), ].join(`\n${''.padEnd(40, '-')}\n`); } pathExists(...path: string[]): Promise { - return fs.pathExists(this.resolvePath(...path)); + return pathExists(this.resolvePath(...path)); } getOutputManifest( path: string = '.output/chrome-mv3/manifest.json', ): Promise { - return fs.readJson(this.resolvePath(path)); + return readJson(this.resolvePath(path)); } } diff --git a/packages/wxt/package.json b/packages/wxt/package.json index a6980347..df65f7cc 100644 --- a/packages/wxt/package.json +++ b/packages/wxt/package.json @@ -34,7 +34,6 @@ "dotenv-expand": "^12.0.3", "esbuild": "^0.27.1", "filesize": "^11.0.13", - "fs-extra": "^11.3.4", "get-port-please": "^3.2.0", "giget": "^1.2.3 || ^2.0.0 || ^3.0.0", "hookable": "^6.0.1", @@ -72,7 +71,6 @@ }, "devDependencies": { "@faker-js/faker": "^10.3.0", - "@types/fs-extra": "^11.0.4", "@types/lodash.merge": "^4.6.9", "@types/node": "^20.17.6", "@types/normalize-path": "^3.0.2", diff --git a/packages/wxt/src/core/builders/vite/index.ts b/packages/wxt/src/core/builders/vite/index.ts index aa06aebd..7853191a 100644 --- a/packages/wxt/src/core/builders/vite/index.ts +++ b/packages/wxt/src/core/builders/vite/index.ts @@ -26,7 +26,7 @@ import { ViteNodeRunner } from 'vite-node/client'; import { installSourcemapsSupport } from 'vite-node/source-map'; import { createExtensionEnvironment } from '../../utils/environments'; import { dirname, extname, join, relative } from 'node:path'; -import fs from 'fs-extra'; +import { mkdir, readdir, rename, rmdir, stat } from 'node:fs/promises'; import { normalizePath } from '../../utils'; export async function createViteBuilder( @@ -455,8 +455,8 @@ async function moveHtmlFiles( ); const oldAbsPath = join(config.outDir, oldBundlePath); const newAbsPath = join(config.outDir, newBundlePath); - await fs.ensureDir(dirname(newAbsPath)); - await fs.move(oldAbsPath, newAbsPath, { overwrite: true }); + await mkdir(dirname(newAbsPath), { recursive: true }); + await rename(oldAbsPath, newAbsPath); return { ...chunk, @@ -473,17 +473,17 @@ async function moveHtmlFiles( /** Recursively remove all directories that are empty/ */ export async function removeEmptyDirs(dir: string): Promise { - const files = await fs.readdir(dir); + const files = await readdir(dir); for (const file of files) { const filePath = join(dir, file); - const stats = await fs.stat(filePath); + const stats = await stat(filePath); if (stats.isDirectory()) { await removeEmptyDirs(filePath); } } try { - await fs.rmdir(dir); + await rmdir(dir); } catch { // noop on failure - this means the directory was not empty. } diff --git a/packages/wxt/src/core/builders/vite/plugins/resolveAppConfig.ts b/packages/wxt/src/core/builders/vite/plugins/resolveAppConfig.ts index abef26b3..919130d1 100644 --- a/packages/wxt/src/core/builders/vite/plugins/resolveAppConfig.ts +++ b/packages/wxt/src/core/builders/vite/plugins/resolveAppConfig.ts @@ -1,4 +1,4 @@ -import { pathExists } from 'fs-extra'; +import { pathExists } from '../../../utils/fs'; import { resolve } from 'node:path'; import type * as vite from 'vite'; import { ResolvedConfig } from '../../../../types'; diff --git a/packages/wxt/src/core/builders/vite/plugins/resolveVirtualModules.ts b/packages/wxt/src/core/builders/vite/plugins/resolveVirtualModules.ts index fa0d0692..12c2b9ce 100644 --- a/packages/wxt/src/core/builders/vite/plugins/resolveVirtualModules.ts +++ b/packages/wxt/src/core/builders/vite/plugins/resolveVirtualModules.ts @@ -1,3 +1,5 @@ +import { readFile } from 'node:fs/promises'; +import { resolve } from 'path'; import type { Plugin } from 'vite'; import { ResolvedConfig } from '../../../../types'; import { normalizePath } from '../../../utils'; @@ -5,8 +7,6 @@ import { VirtualModuleId, virtualModuleNames, } from '../../../utils/virtual-modules'; -import { resolve } from 'path'; -import fs from 'fs-extra'; /** * Resolve all the virtual modules to the `node_modules/wxt/dist/virtual` @@ -36,7 +36,7 @@ export function resolveVirtualModules(config: ResolvedConfig): Plugin[] { }, async handler(id) { const inputPath = id.replace(resolvedVirtualId, ''); - const template = await fs.readFile( + const template = await readFile( resolve(config.wxtModuleDir, `dist/virtual/${name}.mjs`), 'utf-8', ); diff --git a/packages/wxt/src/core/clean.ts b/packages/wxt/src/core/clean.ts index 1334a7b2..46cee527 100644 --- a/packages/wxt/src/core/clean.ts +++ b/packages/wxt/src/core/clean.ts @@ -1,7 +1,7 @@ +import { rm } from 'node:fs/promises'; import path from 'node:path'; -import { glob } from 'tinyglobby'; -import fs from 'fs-extra'; import pc from 'picocolors'; +import { glob } from 'tinyglobby'; import { InlineConfig } from '../types'; import { registerWxt, wxt } from './wxt'; @@ -60,7 +60,7 @@ export async function clean(config?: string | InlineConfig) { directories.map((dir) => pc.cyan(path.relative(root, dir))).join(', '), ); for (const directory of directories) { - await fs.rm(directory, { force: true, recursive: true }); + await rm(directory, { force: true, recursive: true }); wxt.logger.debug('Deleted ' + pc.cyan(path.relative(root, directory))); } } diff --git a/packages/wxt/src/core/generate-wxt-dir.ts b/packages/wxt/src/core/generate-wxt-dir.ts index aa82f339..267e75d7 100644 --- a/packages/wxt/src/core/generate-wxt-dir.ts +++ b/packages/wxt/src/core/generate-wxt-dir.ts @@ -1,12 +1,12 @@ import { Entrypoint, WxtDirEntry, WxtDirFileEntry } from '../types'; -import fs from 'fs-extra'; +import { mkdir, readFile } from 'node:fs/promises'; import { dirname, relative, resolve } from 'node:path'; import { getEntrypointBundlePath, isHtmlEntrypoint } from './utils/entrypoints'; import { getEntrypointGlobals, getGlobals } from './utils/globals'; import { normalizePath } from './utils'; import path from 'node:path'; import { Message, parseI18nMessages } from './utils/i18n'; -import { writeFileIfDifferent, getPublicFiles } from './utils/fs'; +import { pathExists, writeFileIfDifferent, getPublicFiles } from './utils/fs'; import { wxt } from './wxt'; /** @@ -14,7 +14,7 @@ import { wxt } from './wxt'; * directory. */ export async function generateWxtDir(entrypoints: Entrypoint[]): Promise { - await fs.ensureDir(wxt.config.typesDir); + await mkdir(wxt.config.typesDir, { recursive: true }); const entries: WxtDirEntry[] = [ // Hard-coded entries @@ -57,7 +57,7 @@ export async function generateWxtDir(entrypoints: Entrypoint[]): Promise { await Promise.all( absoluteFileEntries.map(async (file) => { - await fs.ensureDir(dirname(file.path)); + await mkdir(dirname(file.path), { recursive: true }); await writeFileIfDifferent(file.path, file.text); }), ); @@ -149,8 +149,8 @@ declare module "wxt/browser" { 'messages.json', ); let messages: Message[]; - if (await fs.pathExists(defaultLocalePath)) { - const content = JSON.parse(await fs.readFile(defaultLocalePath, 'utf-8')); + if (await pathExists(defaultLocalePath)) { + const content = JSON.parse(await readFile(defaultLocalePath, 'utf-8')); messages = parseI18nMessages(content); } else { messages = parseI18nMessages({}); diff --git a/packages/wxt/src/core/initialize.ts b/packages/wxt/src/core/initialize.ts index 1d69962b..f9a64efb 100644 --- a/packages/wxt/src/core/initialize.ts +++ b/packages/wxt/src/core/initialize.ts @@ -1,7 +1,8 @@ import prompts from 'prompts'; import { consola } from 'consola'; import { downloadTemplate } from 'giget'; -import fs from 'fs-extra'; +import { readdir, rename } from 'node:fs/promises'; +import { pathExists } from './utils/fs'; import path from 'node:path'; import pc from 'picocolors'; import { Formatter } from 'picocolors/types'; @@ -56,10 +57,10 @@ export async function initialize(options: { input.template ??= defaultTemplate; input.packageManager ??= options.packageManager; - const isExists = await fs.pathExists(input.directory); + const isExists = await pathExists(input.directory); if (isExists) { const isEmpty = - (await fs.readdir(input.directory)).filter((dir) => dir !== '.git') + (await readdir(input.directory)).filter((dir) => dir !== '.git') .length === 0; if (!isEmpty) { consola.error( @@ -167,14 +168,12 @@ async function cloneProject({ }); // 2. Move _gitignore -> .gitignore - await fs - .move( - path.join(directory, '_gitignore'), - path.join(directory, '.gitignore'), - ) - .catch((err) => - consola.warn('Failed to move _gitignore to .gitignore:', err), - ); + await rename( + path.join(directory, '_gitignore'), + path.join(directory, '.gitignore'), + ).catch((err) => + consola.warn('Failed to move _gitignore to .gitignore:', err), + ); spinner.success(); } catch (err) { diff --git a/packages/wxt/src/core/package-managers/__tests__/npm.test.ts b/packages/wxt/src/core/package-managers/__tests__/npm.test.ts index 6117d946..d0ceb3d5 100644 --- a/packages/wxt/src/core/package-managers/__tests__/npm.test.ts +++ b/packages/wxt/src/core/package-managers/__tests__/npm.test.ts @@ -2,7 +2,7 @@ import { beforeAll, describe, expect, it } from 'vitest'; import path from 'node:path'; import { npm } from '../npm'; import spawn from 'nano-spawn'; -import { pathExists } from 'fs-extra'; +import { pathExists } from '../../utils/fs'; describe('NPM Package Management Utils', () => { describe('listDependencies', () => { diff --git a/packages/wxt/src/core/package-managers/npm.ts b/packages/wxt/src/core/package-managers/npm.ts index 7ad5386f..c79d5645 100644 --- a/packages/wxt/src/core/package-managers/npm.ts +++ b/packages/wxt/src/core/package-managers/npm.ts @@ -1,13 +1,13 @@ import { Dependency } from '../../types'; import { WxtPackageManagerImpl } from './types'; import path from 'node:path'; -import { ensureDir } from 'fs-extra'; +import { mkdir } from 'node:fs/promises'; import spawn from 'nano-spawn'; export const npm: WxtPackageManagerImpl = { overridesKey: 'overrides', async downloadDependency(id, downloadDir) { - await ensureDir(downloadDir); + await mkdir(downloadDir, { recursive: true }); const res = await spawn('npm', ['pack', id, '--json'], { cwd: downloadDir, }); diff --git a/packages/wxt/src/core/resolve-config.ts b/packages/wxt/src/core/resolve-config.ts index 44c299bf..3ff0788d 100644 --- a/packages/wxt/src/core/resolve-config.ts +++ b/packages/wxt/src/core/resolve-config.ts @@ -20,7 +20,7 @@ import { createFsCache } from './utils/cache'; import consola, { LogLevels } from 'consola'; import defu from 'defu'; import { NullablyRequired } from './utils/types'; -import fs from 'fs-extra'; +import { pathExists } from './utils/fs'; import { normalizePath } from './utils'; import { glob } from 'tinyglobby'; import { builtinModules } from '../builtin-modules'; @@ -543,7 +543,7 @@ function resolveWxtModuleDir() { } async function isDirMissing(dir: string) { - return !(await fs.pathExists(dir)); + return !(await pathExists(dir)); } function logMissingDir(logger: Logger, name: string, expected: string) { diff --git a/packages/wxt/src/core/utils/building/__tests__/find-entrypoints.test.ts b/packages/wxt/src/core/utils/building/__tests__/find-entrypoints.test.ts index cf9cd30a..1343b5d1 100644 --- a/packages/wxt/src/core/utils/building/__tests__/find-entrypoints.test.ts +++ b/packages/wxt/src/core/utils/building/__tests__/find-entrypoints.test.ts @@ -1,4 +1,7 @@ -import { describe, it, expect, vi, beforeEach, Mock } from 'vitest'; +import { readFile } from 'node:fs/promises'; +import { resolve } from 'path'; +import { glob } from 'tinyglobby'; +import { beforeEach, describe, expect, it, Mock, vi } from 'vitest'; import { BackgroundEntrypoint, BackgroundEntrypointOptions, @@ -9,21 +12,16 @@ import { PopupEntrypoint, SidepanelEntrypoint, } from '../../../../types'; -import { resolve } from 'path'; -import { findEntrypoints } from '../find-entrypoints'; -import fs from 'fs-extra'; -import { glob } from 'tinyglobby'; -import { fakeResolvedConfig, setFakeWxt } from '../../testing/fake-objects'; -import { unnormalizePath } from '../../paths'; import { wxt } from '../../../wxt'; +import { unnormalizePath } from '../../paths'; +import { fakeResolvedConfig, setFakeWxt } from '../../testing/fake-objects'; +import { findEntrypoints } from '../find-entrypoints'; vi.mock('tinyglobby'); const globMock = vi.mocked(glob); -vi.mock('fs-extra'); -const readFileMock = vi.mocked( - fs.readFile as (path: string) => Promise, -); +vi.mock('node:fs/promises'); +const readFileMock = vi.mocked(readFile); describe('findEntrypoints', () => { const config = fakeResolvedConfig({ diff --git a/packages/wxt/src/core/utils/building/build-entrypoints.ts b/packages/wxt/src/core/utils/building/build-entrypoints.ts index dda83e31..5bc89840 100644 --- a/packages/wxt/src/core/utils/building/build-entrypoints.ts +++ b/packages/wxt/src/core/utils/building/build-entrypoints.ts @@ -5,7 +5,7 @@ import { ResolvedPublicFile, } from '../../../types'; import { getPublicFiles } from '../fs'; -import fs from 'fs-extra'; +import { copyFile, mkdir, writeFile } from 'node:fs/promises'; import { dirname, resolve } from 'path'; import type { Spinner } from 'nanospinner'; import pc from 'picocolors'; @@ -50,11 +50,11 @@ async function copyPublicDirectory(): Promise { for (const file of files) { const absoluteDest = resolve(wxt.config.outDir, file.relativeDest); - await fs.ensureDir(dirname(absoluteDest)); + await mkdir(dirname(absoluteDest), { recursive: true }); if ('absoluteSrc' in file) { - await fs.copyFile(file.absoluteSrc, absoluteDest); + await copyFile(file.absoluteSrc, absoluteDest); } else { - await fs.writeFile(absoluteDest, file.contents, 'utf8'); + await writeFile(absoluteDest, file.contents, 'utf8'); } publicAssets.push({ type: 'asset', diff --git a/packages/wxt/src/core/utils/building/find-entrypoints.ts b/packages/wxt/src/core/utils/building/find-entrypoints.ts index 6bd52c5d..a81e1704 100644 --- a/packages/wxt/src/core/utils/building/find-entrypoints.ts +++ b/packages/wxt/src/core/utils/building/find-entrypoints.ts @@ -12,7 +12,7 @@ import { IsolatedWorldContentScriptEntrypointOptions, UnlistedScriptEntrypoint, } from '../../../types'; -import fs from 'fs-extra'; +import { mkdir, readFile, writeFile } from 'node:fs/promises'; import { minimatch } from 'minimatch'; import { parseHTML } from 'linkedom'; import JSON5 from 'json5'; @@ -35,11 +35,11 @@ import { camelCase } from 'scule'; */ export async function findEntrypoints(): Promise { // Make sure required TSConfig file exists to load dependencies - await fs.mkdir(wxt.config.wxtDir, { recursive: true }); + await mkdir(wxt.config.wxtDir, { recursive: true }); try { - await fs.writeJson( + await writeFile( resolve(wxt.config.wxtDir, 'tsconfig.json'), - {}, + JSON.stringify({}), { flag: 'wx' }, ); } catch (err) { @@ -204,7 +204,7 @@ async function importEntrypoints(infos: EntrypointInfo[]) { async function importHtmlEntrypoint( info: EntrypointInfo, ): Promise> { - const content = await fs.readFile(info.inputPath, 'utf-8'); + const content = await readFile(info.inputPath, 'utf-8'); const { document } = parseHTML(content); const metaTags = document.querySelectorAll('meta'); diff --git a/packages/wxt/src/core/utils/building/internal-build.ts b/packages/wxt/src/core/utils/building/internal-build.ts index 137a1edf..20bc6616 100644 --- a/packages/wxt/src/core/utils/building/internal-build.ts +++ b/packages/wxt/src/core/utils/building/internal-build.ts @@ -1,7 +1,7 @@ import { findEntrypoints } from './find-entrypoints'; import { BuildOutput, Entrypoint } from '../../../types'; import pc from 'picocolors'; -import fs from 'fs-extra'; +import { mkdir, rm } from 'node:fs/promises'; import { groupEntrypoints } from './group-entrypoints'; import { formatDuration } from '../time'; import { printBuildSummary } from '../log'; @@ -43,8 +43,8 @@ export async function internalBuild(): Promise { const startTime = Date.now(); // Cleanup - await fs.rm(wxt.config.outDir, { recursive: true, force: true }); - await fs.ensureDir(wxt.config.outDir); + await rm(wxt.config.outDir, { recursive: true, force: true }); + await mkdir(wxt.config.outDir, { recursive: true }); const entrypoints = await findEntrypoints(); wxt.logger.debug('Detected entrypoints:', entrypoints); @@ -111,7 +111,9 @@ async function combineAnalysisStats(): Promise { }); if (!wxt.config.analysis.keepArtifacts) { - await Promise.all(absolutePaths.map((statsFile) => fs.remove(statsFile))); + await Promise.all( + absolutePaths.map((statsFile) => rm(statsFile, { force: true })), + ); } } diff --git a/packages/wxt/src/core/utils/building/rebuild.ts b/packages/wxt/src/core/utils/building/rebuild.ts index 76e9666d..f381fc71 100644 --- a/packages/wxt/src/core/utils/building/rebuild.ts +++ b/packages/wxt/src/core/utils/building/rebuild.ts @@ -1,10 +1,10 @@ -import { BuildOutput, Entrypoint, EntrypointGroup } from '../../../types'; -import { generateWxtDir } from '../../generate-wxt-dir'; -import { buildEntrypoints } from './build-entrypoints'; -import { generateManifest, writeManifest } from '../../utils/manifest'; -import { wxt } from '../../wxt'; import type { Browser } from '@wxt-dev/browser'; import { createSpinner } from 'nanospinner'; +import { BuildOutput, Entrypoint, EntrypointGroup } from '../../../types'; +import { generateWxtDir } from '../../generate-wxt-dir'; +import { generateManifest, writeManifest } from '../../utils/manifest'; +import { wxt } from '../../wxt'; +import { buildEntrypoints } from './build-entrypoints'; /** * Given a configuration, list of entrypoints, and an existing, partial output, @@ -22,7 +22,7 @@ import { createSpinner } from 'nanospinner'; * .wxt directory. * @param entrypointGroups The list of entrypoint groups to build. * @param existingOutput The previous output to combine the rebuild results - * into. An emptry array if this is the first build. + * into. An empty array if this is the first build. */ export async function rebuild( allEntrypoints: Entrypoint[], diff --git a/packages/wxt/src/core/utils/cache.ts b/packages/wxt/src/core/utils/cache.ts index 5d957eae..c6886564 100644 --- a/packages/wxt/src/core/utils/cache.ts +++ b/packages/wxt/src/core/utils/cache.ts @@ -1,4 +1,4 @@ -import fs, { ensureDir } from 'fs-extra'; +import { mkdir, readFile } from 'node:fs/promises'; import { FsCache } from '../../types'; import { dirname, resolve } from 'path'; import { writeFileIfDifferent } from './fs'; @@ -16,13 +16,13 @@ export function createFsCache(wxtDir: string): FsCache { return { async set(key: string, value: string): Promise { const path = getPath(key); - await ensureDir(dirname(path)); + await mkdir(dirname(path), { recursive: true }); await writeFileIfDifferent(path, value); }, async get(key: string): Promise { const path = getPath(key); try { - return await fs.readFile(path, 'utf-8'); + return await readFile(path, 'utf-8'); } catch { return undefined; } diff --git a/packages/wxt/src/core/utils/fs.ts b/packages/wxt/src/core/utils/fs.ts index 52020b92..8b27db1d 100644 --- a/packages/wxt/src/core/utils/fs.ts +++ b/packages/wxt/src/core/utils/fs.ts @@ -1,7 +1,20 @@ -import fs from 'fs-extra'; +import { access, readFile, writeFile } from 'node:fs/promises'; import { glob } from 'tinyglobby'; -import { unnormalizePath } from './paths'; import { wxt } from '../wxt'; +import { unnormalizePath } from './paths'; + +export async function pathExists(path: string): Promise { + try { + await access(path); + return true; + } catch { + return false; + } +} + +export async function readJson(path: string): Promise { + return JSON.parse(await readFile(path, 'utf-8')); +} /** * Only write the contents to a file if it results in a change. This prevents @@ -15,21 +28,15 @@ export async function writeFileIfDifferent( file: string, newContents: string, ): Promise { - const existingContents = await fs - .readFile(file, 'utf-8') - .catch(() => undefined); + const existingContents = await readFile(file, 'utf-8').catch(() => undefined); if (existingContents !== newContents) { - await fs.writeFile(file, newContents); + await writeFile(file, newContents); } } -/** - * Get all the files in the project's public directory. Returned paths are - * relative to the `config.publicDir`. - */ export async function getPublicFiles(): Promise { - if (!(await fs.pathExists(wxt.config.publicDir))) return []; + if (!(await pathExists(wxt.config.publicDir))) return []; const files = await glob('**/*', { cwd: wxt.config.publicDir, diff --git a/packages/wxt/src/core/utils/log/printFileList.ts b/packages/wxt/src/core/utils/log/printFileList.ts index 72ef70c5..8efa28f3 100644 --- a/packages/wxt/src/core/utils/log/printFileList.ts +++ b/packages/wxt/src/core/utils/log/printFileList.ts @@ -1,6 +1,6 @@ import path from 'node:path'; import pc from 'picocolors'; -import fs from 'fs-extra'; +import { lstat } from 'node:fs/promises'; import { filesize } from 'filesize'; import { printTable } from './printTable'; @@ -20,7 +20,7 @@ export async function printFileList( ]; const prefix = i === files.length - 1 ? ' └─' : ' ├─'; const color = getChunkColor(file); - const stats = await fs.lstat(file); + const stats = await lstat(file); totalSize += stats.size; const size = String(filesize(stats.size)); return [ diff --git a/packages/wxt/src/core/utils/manifest.ts b/packages/wxt/src/core/utils/manifest.ts index a8b51272..a0e3b059 100644 --- a/packages/wxt/src/core/utils/manifest.ts +++ b/packages/wxt/src/core/utils/manifest.ts @@ -7,7 +7,7 @@ import { PopupEntrypoint, SidepanelEntrypoint, } from '../../types'; -import fs from 'fs-extra'; +import { mkdir } from 'node:fs/promises'; import { resolve } from 'path'; import { getEntrypointBundlePath } from './entrypoints'; import { ContentSecurityPolicy } from './content-security-policy'; @@ -33,7 +33,7 @@ export async function writeManifest( ? JSON.stringify(manifest) : JSON.stringify(manifest, null, 2); - await fs.ensureDir(wxt.config.outDir); + await mkdir(wxt.config.outDir, { recursive: true }); await writeFileIfDifferent(resolve(wxt.config.outDir, 'manifest.json'), str); output.publicAssets.unshift({ diff --git a/packages/wxt/src/core/utils/package.ts b/packages/wxt/src/core/utils/package.ts index a1acfad4..ce0f8a6a 100644 --- a/packages/wxt/src/core/utils/package.ts +++ b/packages/wxt/src/core/utils/package.ts @@ -1,5 +1,5 @@ import { resolve } from 'node:path'; -import fs from 'fs-extra'; +import { readJson } from './fs'; import { wxt } from '../wxt'; /** @@ -12,7 +12,7 @@ export async function getPackageJson(): Promise< > { const file = resolve(wxt.config.root, 'package.json'); try { - return await fs.readJson(file); + return await readJson(file); } catch (err) { wxt.logger.debug( `Failed to read package.json at: ${file}. Returning undefined.`, diff --git a/packages/wxt/src/core/zip.ts b/packages/wxt/src/core/zip.ts index a722dcf0..71595f6b 100644 --- a/packages/wxt/src/core/zip.ts +++ b/packages/wxt/src/core/zip.ts @@ -1,6 +1,7 @@ import { InlineConfig } from '../types'; import path from 'node:path'; -import fs from 'fs-extra'; +import { mkdir, readFile } from 'node:fs/promises'; +import { createWriteStream } from 'node:fs'; import { safeFilename } from './utils/strings'; import { getPackageJson } from './utils/package'; import { formatDuration } from './utils/time'; @@ -43,7 +44,7 @@ export async function zip(config?: InlineConfig): Promise { .replaceAll('{{mode}}', wxt.config.mode) .replaceAll('{{manifestVersion}}', `mv${wxt.config.manifestVersion}`); - await fs.ensureDir(wxt.config.outBaseDir); + await mkdir(wxt.config.outBaseDir, { recursive: true }); // ZIP output directory await wxt.hooks.callHook('zip:extension:start', wxt); @@ -137,13 +138,13 @@ async function zipDir( for (const file of filesToZip) { const absolutePath = path.resolve(directory, file); if (file.endsWith('.json')) { - const content = await fs.readFile(absolutePath, 'utf-8'); + const content = await readFile(absolutePath, 'utf-8'); archive.file( file, (await options?.transform?.(absolutePath, file, content)) || content, ); } else { - const content = await fs.readFile(absolutePath); + const content = await readFile(absolutePath); archive.file(file, content); } } @@ -160,7 +161,7 @@ async function zipDir( compressionOptions: { level: wxt.config.zip.compressionLevel }, }), }) - .pipe(fs.createWriteStream(outputPath)) + .pipe(createWriteStream(outputPath)) .on('error', reject) .on('close', resolve), ); diff --git a/packages/wxt/vitest.globalSetup.ts b/packages/wxt/vitest.globalSetup.ts index 3182504d..f42fc7cd 100644 --- a/packages/wxt/vitest.globalSetup.ts +++ b/packages/wxt/vitest.globalSetup.ts @@ -1,4 +1,4 @@ -import { pathExists, rm } from 'fs-extra'; +import { access, rm } from 'node:fs/promises'; let setupHappened = false; @@ -12,7 +12,10 @@ export async function setup() { globalThis.__ENTRYPOINT__ = 'test'; const e2eDistPath = './e2e/dist/'; - if (await pathExists(e2eDistPath)) { + try { + await access(e2eDistPath); await rm(e2eDistPath, { recursive: true, force: true }); + } catch { + // Directory doesn't exist, nothing to clean up } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a03923c3..8500a43c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -25,9 +25,6 @@ importers: '@commitlint/types': specifier: ^20.4.3 version: 20.4.3 - '@types/fs-extra': - specifier: ^11.0.4 - version: 11.0.4 '@types/semver': specifier: ^7.7.1 version: 7.7.1 @@ -43,9 +40,6 @@ importers: feed: specifier: ^5.2.0 version: 5.2.0 - fs-extra: - specifier: ^11.3.4 - version: 11.3.4 markdown-it-footnote: specifier: ^4.0.0 version: 4.0.0(patch_hash=5b74a0001a771ff5df790dd36b6883c4794e1f666b231499edb2d65eae8f4930) @@ -149,9 +143,6 @@ importers: defu: specifier: ^6.1.4 version: 6.1.4 - fs-extra: - specifier: ^11.3.4 - version: 11.3.4 sharp: specifier: ^0.34.5 version: 0.34.5 @@ -184,9 +175,9 @@ importers: '@types/chrome': specifier: 0.1.37 version: 0.1.37 - fs-extra: - specifier: ^11.3.4 - version: 11.3.4 + '@types/node': + specifier: ^20.0.0 + version: 20.19.32 nano-spawn: specifier: ^2.0.0 version: 2.0.0 @@ -477,9 +468,6 @@ importers: filesize: specifier: ^11.0.13 version: 11.0.13 - fs-extra: - specifier: ^11.3.4 - version: 11.3.4 get-port-please: specifier: ^3.2.0 version: 3.2.0 @@ -562,9 +550,6 @@ importers: '@faker-js/faker': specifier: ^10.3.0 version: 10.3.0 - '@types/fs-extra': - specifier: ^11.0.4 - version: 11.0.4 '@types/lodash.merge': specifier: ^4.6.9 version: 4.6.9 @@ -2165,9 +2150,6 @@ packages: '@types/filewriter@0.0.33': resolution: {integrity: sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==} - '@types/fs-extra@11.0.4': - resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} - '@types/har-format@1.2.16': resolution: {integrity: sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A==} @@ -2180,9 +2162,6 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/jsonfile@6.1.4': - resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} - '@types/katex@0.16.8': resolution: {integrity: sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==} @@ -6279,11 +6258,6 @@ snapshots: '@types/filewriter@0.0.33': {} - '@types/fs-extra@11.0.4': - dependencies: - '@types/jsonfile': 6.1.4 - '@types/node': 20.19.32 - '@types/har-format@1.2.16': {} '@types/hast@3.0.4': @@ -6294,10 +6268,6 @@ snapshots: '@types/json-schema@7.0.15': {} - '@types/jsonfile@6.1.4': - dependencies: - '@types/node': 20.19.32 - '@types/katex@0.16.8': {} '@types/linkify-it@5.0.0': {} diff --git a/scripts/bump-package-version.ts b/scripts/bump-package-version.ts index 2d8971f1..ee9e9134 100644 --- a/scripts/bump-package-version.ts +++ b/scripts/bump-package-version.ts @@ -6,7 +6,7 @@ import { parseCommits, } from 'changelogen'; import { consola } from 'consola'; -import fs from 'fs-extra'; +import { readdir, readFile, writeFile } from 'node:fs/promises'; import spawn from 'nano-spawn'; import path from 'node:path'; import { getPkgTag, grabPackageDetails, listCommitsInDir } from './git'; @@ -41,7 +41,7 @@ if (currentVersion.startsWith('0.')) { await spawn('pnpm', ['version', bumpType], { cwd: pkgDir, }); -const updatedPkgJson = await fs.readJson(pkgJsonPath); +const updatedPkgJson = JSON.parse(await readFile(pkgJsonPath, 'utf-8')); const newVersion: string = updatedPkgJson.version; const newTag = getPkgTag(pkg, newVersion); consola.info('Bump:', { currentVersion, bumpType, newVersion }); @@ -63,8 +63,7 @@ if (originalBumpType === 'major') { `[⚠️ breaking changes](https://wxt.dev/guide/resources/upgrading.html) • [compare changes]`, ); } -const { releases: prevReleases } = await fs - .readFile(changelogPath, 'utf8') +const { releases: prevReleases } = await readFile(changelogPath, 'utf8') .then(parseChangelogMarkdown) .catch(() => ({ releases: [] })); const allReleases = [ @@ -80,29 +79,34 @@ const newChangelog = allReleases .map((release) => [`## v${release.version}`, release.body].join('\n\n')) .join('\n\n'); -await fs.writeFile(changelogPath, newChangelog, 'utf8'); +await writeFile(changelogPath, newChangelog, 'utf8'); consola.success('Updated changelog'); // Update WXT version in templates when releasing wxt package const templatePkgJsonPaths: string[] = []; if (pkg === 'wxt') { const templatesDir = 'templates'; - const templateDirs = await fs.readdir(templatesDir); + const templateDirs = await readdir(templatesDir); for (const templateDir of templateDirs) { const templatePkgJsonPath = path.join( templatesDir, templateDir, 'package.json', ); - if (await fs.pathExists(templatePkgJsonPath)) { - const templatePkgJson = await fs.readJson(templatePkgJsonPath); + try { + const templatePkgJson = JSON.parse( + await readFile(templatePkgJsonPath, 'utf-8'), + ); if (templatePkgJson.devDependencies?.wxt) { templatePkgJson.devDependencies.wxt = `^${newVersion}`; - await fs.writeJson(templatePkgJsonPath, templatePkgJson, { spaces: 2 }); + await writeFile( + templatePkgJsonPath, + JSON.stringify(templatePkgJson, null, 2), + ); templatePkgJsonPaths.push(templatePkgJsonPath); consola.success(`Updated wxt version in ${templatePkgJsonPath}`); } - } + } catch {} } } diff --git a/scripts/create-github-release.ts b/scripts/create-github-release.ts index f33cc4aa..42a2a160 100644 --- a/scripts/create-github-release.ts +++ b/scripts/create-github-release.ts @@ -4,7 +4,7 @@ import { loadChangelogConfig, parseChangelogMarkdown, } from 'changelogen'; -import fs from 'fs-extra'; +import { readFile } from 'node:fs/promises'; import { grabPackageDetails } from './git'; import consola from 'consola'; @@ -19,8 +19,7 @@ const { pkgName, prevTag, currentVersion, changelogPath } = await grabPackageDetails(pkg); consola.info('Creating release for:', { pkg, pkgName, prevTag }); -const { releases } = await fs - .readFile(changelogPath, 'utf8') +const { releases } = await readFile(changelogPath, 'utf8') .then(parseChangelogMarkdown) .catch(() => ({ releases: [] })); diff --git a/scripts/git.ts b/scripts/git.ts index d0829999..4ebe04c7 100644 --- a/scripts/git.ts +++ b/scripts/git.ts @@ -1,11 +1,11 @@ import { RawGitCommit, getGitDiff } from 'changelogen'; import { consola } from 'consola'; -import fs from 'fs-extra'; +import { readFile } from 'node:fs/promises'; export async function grabPackageDetails(pkg: string) { const pkgDir = `packages/${pkg}`; const pkgJsonPath = `${pkgDir}/package.json`; - const pkgJson = await fs.readJson(pkgJsonPath); + const pkgJson = JSON.parse(await readFile(pkgJsonPath, 'utf-8')); const currentVersion: string = pkgJson.version; return { pkgDir, diff --git a/scripts/sync-releases.ts b/scripts/sync-releases.ts index 793e6adc..c1db11b0 100644 --- a/scripts/sync-releases.ts +++ b/scripts/sync-releases.ts @@ -5,7 +5,7 @@ import { updateGithubRelease, } from 'changelogen'; import { getPkgTag, grabPackageDetails } from './git'; -import fs from 'fs-extra'; +import { readFile } from 'node:fs/promises'; import consola from 'consola'; const pkg = process.argv[2]; @@ -17,8 +17,7 @@ if (!pkg) { // Update const { changelogPath, pkgName } = await grabPackageDetails(pkg); -const { releases } = await fs - .readFile(changelogPath, 'utf8') +const { releases } = await readFile(changelogPath, 'utf8') .then(parseChangelogMarkdown) .catch(() => ({ releases: [] })); const config = await loadChangelogConfig(process.cwd()); diff --git a/scripts/upgrade-deps.ts b/scripts/upgrade-deps.ts index f72d93e6..d31a0061 100644 --- a/scripts/upgrade-deps.ts +++ b/scripts/upgrade-deps.ts @@ -1,10 +1,10 @@ -import { glob } from 'tinyglobby'; -import fs from 'fs-extra'; -import * as semver from 'semver'; -import { dirname } from 'node:path'; import consola from 'consola'; import spawn from 'nano-spawn'; +import { readFile, writeFile } from 'node:fs/promises'; +import { dirname } from 'node:path'; import pMap from 'p-map'; +import * as semver from 'semver'; +import { glob } from 'tinyglobby'; const HELP_MESSAGE = ` Upgrades dependencies throughout WXT using custom rules. @@ -101,7 +101,7 @@ async function getPackageJsonDependencies( ); const packageJsons: PackageJsonData[] = await Promise.all( packageJsonFiles.map(async (path) => ({ - content: await fs.readJson(path), + content: JSON.parse(await readFile(path, 'utf-8')), path, folder: dirname(path), })), @@ -341,7 +341,7 @@ async function writeUpgrades( upgrades: UpgradeDetails[], ) { for (const packageJsonFile of packageJsonFiles) { - const oldText = await fs.readFile(packageJsonFile, 'utf8'); + const oldText = await readFile(packageJsonFile, 'utf8'); let newText = oldText; for (const upgrade of upgrades) { const search = `"${upgrade.name}": "${upgrade.currentRange}"`; @@ -349,7 +349,7 @@ async function writeUpgrades( newText = newText.replaceAll(search, replace); } if (newText !== oldText) { - await fs.writeFile(packageJsonFile, newText, 'utf8'); + await writeFile(packageJsonFile, newText, 'utf8'); } } }