Compare commits

..

10 Commits

Author SHA1 Message Date
github-actions[bot] e4598a5e37 chore(release): @wxt-dev/module-react v1.2.2
📼 VHS / Create VHS (push) Cancelled after 0s
2026-03-14 23:48:01 +00:00
github-actions[bot] db5c22809c chore(release): wxt v0.20.19
📼 VHS / Create VHS (push) Cancelled after 0s
2026-03-14 23:43:04 +00:00
Aaron c61fa8f858 fix: Add @vitejs/plugin-react v6 support 2026-03-14 18:38:33 -05:00
Florian Metz 5fe4681620 chore: replace fs-extra with node:fs/promises (#2174)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2026-03-06 09:29:49 -06:00
Aaron 80d384361b chore: Update nano-staged precommit command 2026-03-06 09:17:22 -06:00
dagangtj a1e72c0749 chore: replace lint-staged with nano-staged (#2179)
Co-authored-by: Dean <dagangtj@gmail.com>
2026-03-06 15:13:41 +00:00
Aaron e3a80b8247 ci: Re-enable react template validation 2026-03-06 08:54:08 -06:00
github-actions[bot] c0013acadc chore(release): @wxt-dev/module-react v1.2.1
📼 VHS / Create VHS (push) Cancelled after 0s
2026-03-06 14:51:43 +00:00
Aaron f472c53da7 ci: Temporarily disable react template validation 2026-03-06 08:47:58 -06:00
Aaron 032f7931e8 chore: Add prepack script to all packages 2026-03-06 08:43:51 -06:00
56 changed files with 280 additions and 262 deletions
+3 -5
View File
@@ -20,17 +20,15 @@
"@aklinker1/check": "^2.2.0", "@aklinker1/check": "^2.2.0",
"@commitlint/config-conventional": "^20.4.3", "@commitlint/config-conventional": "^20.4.3",
"@commitlint/types": "^20.4.3", "@commitlint/types": "^20.4.3",
"@types/fs-extra": "^11.0.4",
"@types/semver": "^7.7.1", "@types/semver": "^7.7.1",
"@vitest/coverage-v8": "^4.0.18", "@vitest/coverage-v8": "^4.0.18",
"changelogen": "^0.6.2", "changelogen": "^0.6.2",
"consola": "^3.4.2", "consola": "^3.4.2",
"feed": "^5.2.0", "feed": "^5.2.0",
"fs-extra": "^11.3.4",
"lint-staged": "^16.3.2",
"markdown-it-footnote": "^4.0.0", "markdown-it-footnote": "^4.0.0",
"markdownlint-cli": "^0.48.0", "markdownlint-cli": "^0.48.0",
"nano-spawn": "^2.0.0", "nano-spawn": "^2.0.0",
"nano-staged": "^0.8.0",
"p-map": "^7.0.4", "p-map": "^7.0.4",
"prettier": "^3.8.1", "prettier": "^3.8.1",
"prettier-plugin-jsdoc": "^1.8.0", "prettier-plugin-jsdoc": "^1.8.0",
@@ -53,9 +51,9 @@
"wxt": "workspace:*" "wxt": "workspace:*"
}, },
"simple-git-hooks": { "simple-git-hooks": {
"pre-commit": "pnpm lint-staged" "pre-commit": "./node_modules/.bin/nano-staged"
}, },
"lint-staged": { "nano-staged": {
"*": "prettier --ignore-unknown --write" "*": "prettier --ignore-unknown --write"
} }
} }
+1 -1
View File
@@ -8,7 +8,7 @@
"dev:build": "buildc --deps-only -- wxt build", "dev:build": "buildc --deps-only -- wxt build",
"check": "pnpm build && check", "check": "pnpm build && check",
"build": "buildc -- tsdown", "build": "buildc -- tsdown",
"prepack": "pnpm -s build", "prepack": "pnpm build",
"prepare": "buildc --deps-only -- wxt prepare" "prepare": "buildc --deps-only -- wxt prepare"
}, },
"dependencies": { "dependencies": {
+2 -2
View File
@@ -40,14 +40,14 @@
"scripts": { "scripts": {
"build": "buildc -- tsdown", "build": "buildc -- tsdown",
"check": "pnpm build && check", "check": "pnpm build && check",
"test": "buildc --deps-only -- vitest" "test": "buildc --deps-only -- vitest",
"prepack": "pnpm build"
}, },
"peerDependencies": { "peerDependencies": {
"wxt": ">=0.19.0" "wxt": ">=0.19.0"
}, },
"dependencies": { "dependencies": {
"defu": "^6.1.4", "defu": "^6.1.4",
"fs-extra": "^11.3.4",
"sharp": "^0.34.5" "sharp": "^0.34.5"
}, },
"devDependencies": { "devDependencies": {
+11 -10
View File
@@ -1,6 +1,6 @@
import { describe, it, expect, vi, beforeEach, Mock } from 'vitest'; import { describe, it, expect, vi, beforeEach, Mock } from 'vitest';
import { resolve } from 'node:path'; import { resolve } from 'node:path';
import * as fsExtra from 'fs-extra'; import * as fsPromises from 'node:fs/promises';
import sharp from 'sharp'; import sharp from 'sharp';
import type { Wxt, UserManifest } from 'wxt'; import type { Wxt, UserManifest } from 'wxt';
@@ -9,9 +9,9 @@ import autoIconsModule from '../index';
import type { AutoIconsOptions } from '../index'; import type { AutoIconsOptions } from '../index';
// Mock dependencies // Mock dependencies
vi.mock('fs-extra', () => ({ vi.mock('node:fs/promises', () => ({
ensureDir: vi.fn(), mkdir: vi.fn(),
pathExists: vi.fn(), access: vi.fn(),
})); }));
vi.mock('sharp', () => ({ vi.mock('sharp', () => ({
@@ -86,8 +86,8 @@ describe('auto-icons module', () => {
vi.mocked(sharp).mockReturnValue( vi.mocked(sharp).mockReturnValue(
mockSharpInstance as unknown as sharp.Sharp, mockSharpInstance as unknown as sharp.Sharp,
); );
vi.mocked(fsExtra.pathExists).mockResolvedValue(true as any); vi.mocked(fsPromises.access).mockResolvedValue(undefined);
vi.mocked(fsExtra.ensureDir).mockResolvedValue(undefined as any); vi.mocked(fsPromises.mkdir).mockResolvedValue(undefined as any);
}); });
describe('module setup', () => { describe('module setup', () => {
@@ -158,7 +158,7 @@ describe('auto-icons module', () => {
}); });
it('should warn when base icon not found', async () => { 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 = { const options: AutoIconsOptions = {
enabled: true, enabled: true,
@@ -293,8 +293,9 @@ describe('auto-icons module', () => {
expect(mockSharpInstance.resize).toHaveBeenCalledWith(32); expect(mockSharpInstance.resize).toHaveBeenCalledWith(32);
expect(mockSharpInstance.resize).toHaveBeenCalledWith(16); expect(mockSharpInstance.resize).toHaveBeenCalledWith(16);
expect(fsExtra.ensureDir).toHaveBeenCalledWith( expect(fsPromises.mkdir).toHaveBeenCalledWith(
resolve('/mock/dist', 'icons'), resolve('/mock/dist', 'icons'),
{ recursive: true },
); );
expect(output.publicAssets).toEqual([ expect(output.publicAssets).toEqual([
@@ -514,7 +515,7 @@ describe('auto-icons module', () => {
}; };
// Make ensureDir throw an error // Make ensureDir throw an error
vi.mocked(fsExtra.ensureDir).mockRejectedValue( vi.mocked(fsPromises.mkdir).mockRejectedValue(
new Error('Directory creation failed'), new Error('Directory creation failed'),
); );
@@ -530,7 +531,7 @@ describe('auto-icons module', () => {
if (buildHook) { if (buildHook) {
await buildHook(mockWxt as unknown as Wxt, output); await buildHook(mockWxt as unknown as Wxt, output);
// But ensureDir should have been called // But ensureDir should have been called
expect(fsExtra.ensureDir).toHaveBeenCalled(); expect(fsPromises.mkdir).toHaveBeenCalled();
} }
}); });
+7 -3
View File
@@ -3,7 +3,7 @@ import { defineWxtModule } from 'wxt/modules';
import { resolve, relative } from 'node:path'; import { resolve, relative } from 'node:path';
import defu from 'defu'; import defu from 'defu';
import sharp from 'sharp'; import sharp from 'sharp';
import { ensureDir, pathExists } from 'fs-extra'; import { access, mkdir } from 'node:fs/promises';
export default defineWxtModule<AutoIconsOptions>({ export default defineWxtModule<AutoIconsOptions>({
name: '@wxt-dev/auto-icons', name: '@wxt-dev/auto-icons',
@@ -37,7 +37,11 @@ export default defineWxtModule<AutoIconsOptions>({
if (!parsedOptions.enabled) if (!parsedOptions.enabled)
return wxt.logger.warn(`\`[auto-icons]\` ${this.name} disabled`); 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( return wxt.logger.warn(
`\`[auto-icons]\` Skipping icon generation, no base icon found at ${relative(process.cwd(), resolvedPath)}`, `\`[auto-icons]\` Skipping icon generation, no base icon found at ${relative(process.cwd(), resolvedPath)}`,
); );
@@ -91,7 +95,7 @@ export default defineWxtModule<AutoIconsOptions>({
} }
} }
ensureDir(resolve(outputFolder, 'icons')); mkdir(resolve(outputFolder, 'icons'), { recursive: true });
await resizedImage.toFile(resolve(outputFolder, `icons/${size}.png`)); await resizedImage.toFile(resolve(outputFolder, `icons/${size}.png`));
output.publicAssets.push({ output.publicAssets.push({
+1 -1
View File
@@ -24,7 +24,7 @@
], ],
"devDependencies": { "devDependencies": {
"@types/chrome": "0.1.37", "@types/chrome": "0.1.37",
"fs-extra": "^11.3.4", "@types/node": "^20.0.0",
"nano-spawn": "^2.0.0", "nano-spawn": "^2.0.0",
"typescript": "^5.9.3", "typescript": "^5.9.3",
"vitest": "^4.0.18" "vitest": "^4.0.18"
+8 -8
View File
@@ -1,5 +1,5 @@
import spawn from 'nano-spawn'; 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 { fileURLToPath } from 'node:url';
import { dirname, join, resolve, sep } from 'node:path'; import { dirname, join, resolve, sep } from 'node:path';
import { sep as posixSep } from 'node:path/posix'; import { sep as posixSep } from 'node:path/posix';
@@ -17,8 +17,8 @@ const pkgJsonPath = fileURLToPath(
import.meta.resolve('@types/chrome/package.json'), import.meta.resolve('@types/chrome/package.json'),
); );
const pkgDir = dirname(pkgJsonPath); const pkgDir = dirname(pkgJsonPath);
const pkgJson = await fs.readJson(pkgJsonPath); const pkgJson = JSON.parse(await readFile(pkgJsonPath, 'utf-8'));
const pkgJsonTemplate = await fs.readFile('templates/package.json', 'utf8'); const pkgJsonTemplate = await readFile('templates/package.json', 'utf8');
const newPkgJson = JSON.parse( const newPkgJson = JSON.parse(
pkgJsonTemplate.replaceAll('{{chromeTypesVersion}}', pkgJson.version), pkgJsonTemplate.replaceAll('{{chromeTypesVersion}}', pkgJson.version),
); );
@@ -27,7 +27,7 @@ newPkgJson.peerDependencies = pkgJson.peerDependencies;
newPkgJson.peerDependenciesMeta = pkgJson.peerDependenciesMeta; newPkgJson.peerDependenciesMeta = pkgJson.peerDependenciesMeta;
const outPkgJsonPath = resolve('package.json'); 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]); await spawn('pnpm', ['-w', 'prettier', '--write', outPkgJsonPath]);
// Generate declaration files // Generate declaration files
@@ -35,7 +35,7 @@ await spawn('pnpm', ['-w', 'prettier', '--write', outPkgJsonPath]);
console.log('Generating declaration files'); console.log('Generating declaration files');
const outDir = resolve('src/gen'); const outDir = resolve('src/gen');
const declarationFileMapping = ( const declarationFileMapping = (
await fs.readdir(pkgDir, { await readdir(pkgDir, {
recursive: true, recursive: true,
encoding: 'utf8', encoding: 'utf8',
}) })
@@ -50,11 +50,11 @@ const declarationFileMapping = (
})); }));
for (const { file, srcPath, destPath } of 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 transformedContent = transformFile(file, content);
const destDir = dirname(destPath); const destDir = dirname(destPath);
await fs.mkdir(destDir, { recursive: true }); await mkdir(destDir, { recursive: true });
await fs.writeFile(destPath, transformedContent); await writeFile(destPath, transformedContent);
console.log(` \x1b[2m-\x1b[0m \x1b[36m${file}\x1b[0m`); console.log(` \x1b[2m-\x1b[0m \x1b[36m${file}\x1b[0m`);
} }
+1 -1
View File
@@ -24,7 +24,7 @@
], ],
"devDependencies": { "devDependencies": {
"@types/chrome": "{{chromeTypesVersion}}", "@types/chrome": "{{chromeTypesVersion}}",
"fs-extra": "^11.3.4", "@types/node": "^20.0.0",
"nano-spawn": "^2.0.0", "nano-spawn": "^2.0.0",
"typescript": "^5.9.3", "typescript": "^5.9.3",
"vitest": "^4.0.18" "vitest": "^4.0.18"
+2 -1
View File
@@ -23,7 +23,8 @@
"scripts": { "scripts": {
"build": "buildc -- tsdown", "build": "buildc -- tsdown",
"check": "buildc --deps-only -- check", "check": "buildc --deps-only -- check",
"test": "buildc --deps-only -- vitest" "test": "buildc --deps-only -- vitest",
"prepack": "pnpm build"
}, },
"dependencies": { "dependencies": {
"@wxt-dev/browser": "workspace:^", "@wxt-dev/browser": "workspace:^",
+24
View File
@@ -1,5 +1,29 @@
# Changelog # Changelog
## v1.2.2
[compare changes](https://github.com/wxt-dev/wxt/compare/module-react-v1.2.1...module-react-v1.2.2)
### 🩹 Fixes
- Add `@vitejs/plugin-react` v6 support ([c61fa8f8](https://github.com/wxt-dev/wxt/commit/c61fa8f8))
### ❤️ Contributors
- Aaron ([@aklinker1](https://github.com/aklinker1))
## v1.2.1
[compare changes](https://github.com/wxt-dev/wxt/compare/module-react-v1.2.0...module-react-v1.2.1)
### 🏡 Chore
- Add prepack script to all packages ([032f7931](https://github.com/wxt-dev/wxt/commit/032f7931))
### ❤️ Contributors
- Aaron ([@aklinker1](https://github.com/aklinker1))
## v1.2.0 ## v1.2.0
[compare changes](https://github.com/wxt-dev/wxt/compare/module-react-v1.1.5...module-react-v1.2.0) [compare changes](https://github.com/wxt-dev/wxt/compare/module-react-v1.1.5...module-react-v1.2.0)
+4 -3
View File
@@ -18,7 +18,7 @@
}, },
"license": "MIT", "license": "MIT",
"funding": "https://github.com/sponsors/wxt-dev", "funding": "https://github.com/sponsors/wxt-dev",
"version": "1.2.0", "version": "1.2.2",
"type": "module", "type": "module",
"main": "./dist/index.cjs", "main": "./dist/index.cjs",
"module": "./dist/index.mjs", "module": "./dist/index.mjs",
@@ -42,14 +42,15 @@
"dev": "wxt", "dev": "wxt",
"check": "pnpm build && check", "check": "pnpm build && check",
"build": "buildc -- tsdown", "build": "buildc -- tsdown",
"prepare": "buildc --deps-only -- wxt prepare" "prepare": "buildc --deps-only -- wxt prepare",
"prepack": "pnpm build"
}, },
"peerDependencies": { "peerDependencies": {
"vite": "^5.4.19 || ^6.3.4 || ^7.0.0 || ^8.0.0-0", "vite": "^5.4.19 || ^6.3.4 || ^7.0.0 || ^8.0.0-0",
"wxt": ">=0.19.16" "wxt": ">=0.19.16"
}, },
"dependencies": { "dependencies": {
"@vitejs/plugin-react": "^4.4.1 || ^5.0.0" "@vitejs/plugin-react": "^4.4.1 || ^5.0.0 || ^6.0.0"
}, },
"devDependencies": { "devDependencies": {
"@types/react": "^19.2.14", "@types/react": "^19.2.14",
+2 -1
View File
@@ -42,7 +42,8 @@
"dev": "wxt", "dev": "wxt",
"check": "pnpm build && check", "check": "pnpm build && check",
"build": "buildc -- tsdown", "build": "buildc -- tsdown",
"prepare": "buildc --deps-only -- wxt prepare" "prepare": "buildc --deps-only -- wxt prepare",
"prepack": "pnpm build"
}, },
"peerDependencies": { "peerDependencies": {
"wxt": ">=0.19.16" "wxt": ">=0.19.16"
+2 -1
View File
@@ -40,7 +40,8 @@
], ],
"scripts": { "scripts": {
"build": "buildc -- tsdown", "build": "buildc -- tsdown",
"check": "pnpm build && check" "check": "pnpm build && check",
"prepack": "pnpm build"
}, },
"peerDependencies": { "peerDependencies": {
"wxt": ">=0.18.6", "wxt": ">=0.18.6",
+2 -1
View File
@@ -40,7 +40,8 @@
], ],
"scripts": { "scripts": {
"build": "buildc -- tsdown", "build": "buildc -- tsdown",
"check": "pnpm build && check" "check": "pnpm build && check",
"prepack": "pnpm build"
}, },
"peerDependencies": { "peerDependencies": {
"wxt": ">=0.19.16" "wxt": ">=0.19.16"
+1 -1
View File
@@ -25,7 +25,7 @@
"test": "buildc --deps-only -- vitest", "test": "buildc --deps-only -- vitest",
"dev": "tsx --trace-warnings dev.ts", "dev": "tsx --trace-warnings dev.ts",
"build": "buildc -- tsdown", "build": "buildc -- tsdown",
"prepublishOnly": "pnpm build" "prepack": "pnpm build"
}, },
"devDependencies": { "devDependencies": {
"oxlint": "^1.51.0", "oxlint": "^1.51.0",
+2 -1
View File
@@ -27,7 +27,8 @@
"scripts": { "scripts": {
"build": "buildc -- tsdown", "build": "buildc -- tsdown",
"check": "buildc --deps-only -- check", "check": "buildc --deps-only -- check",
"test": "buildc --deps-only -- vitest" "test": "buildc --deps-only -- vitest",
"prepack": "pnpm build"
}, },
"dependencies": { "dependencies": {
"@wxt-dev/browser": "workspace:^", "@wxt-dev/browser": "workspace:^",
+2 -1
View File
@@ -33,7 +33,8 @@
], ],
"scripts": { "scripts": {
"build": "buildc -- tsdown", "build": "buildc -- tsdown",
"check": "buildc --deps-only -- check" "check": "buildc --deps-only -- check",
"prepack": "pnpm build"
}, },
"peerDependencies": { "peerDependencies": {
"unocss": ">=0.60.0", "unocss": ">=0.60.0",
+2 -1
View File
@@ -38,7 +38,8 @@
"dev": "wxt", "dev": "wxt",
"check": "pnpm build && check", "check": "pnpm build && check",
"build": "buildc -- tsdown", "build": "buildc -- tsdown",
"prepare": "buildc --deps-only -- wxt prepare" "prepare": "buildc --deps-only -- wxt prepare",
"prepack": "pnpm build"
}, },
"peerDependencies": { "peerDependencies": {
"webextension-polyfill": "*", "webextension-polyfill": "*",
+36
View File
@@ -1,5 +1,41 @@
# Changelog # Changelog
## v0.20.19
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.20.18...wxt-v0.20.19)
### 🚀 Enhancements
- Vite 8 support ([bfd4af5d](https://github.com/wxt-dev/wxt/commit/bfd4af5d))
### 🔥 Performance
- Use filter to improve plugin performance with rolldown ([#1787](https://github.com/wxt-dev/wxt/pull/1787))
### 🩹 Fixes
- List eslint 10 as supported ([55dc263d](https://github.com/wxt-dev/wxt/commit/55dc263d))
### 📖 Documentation
- Added "Scrape Similar" to the homepage ([#2158](https://github.com/wxt-dev/wxt/pull/2158))
- Added "isTrust" to the homepage ([#2161](https://github.com/wxt-dev/wxt/pull/2161))
### 🏡 Chore
- Add `prettier-plugin-jsdoc` to project ([#2171](https://github.com/wxt-dev/wxt/pull/2171))
- Replace fast-glob and ora with lighter alternatives ([#2173](https://github.com/wxt-dev/wxt/pull/2173))
- **deps:** Upgrade deps ([#2175](https://github.com/wxt-dev/wxt/pull/2175))
- Replace `fs-extra` with `node:fs/promises` ([#2174](https://github.com/wxt-dev/wxt/pull/2174))
### ❤️ Contributors
- Florian Metz ([@Timeraa](https://github.com/Timeraa))
- Aaron ([@aklinker1](https://github.com/aklinker1))
- Patryk Kuniczak ([@PatrykKuniczak](https://github.com/PatrykKuniczak))
- Etoome ([@etoome](https://github.com/etoome))
- Kuba ([@zizzfizzix](https://github.com/zizzfizzix))
## v0.20.18 ## v0.20.18
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.20.17...wxt-v0.20.18) [compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.20.17...wxt-v0.20.18)
+4 -4
View File
@@ -1,8 +1,8 @@
import { describe, it, expect } from 'vitest';
import { TestProject, WXT_PACKAGE_DIR } from '../utils';
import spawn from 'nano-spawn'; import spawn from 'nano-spawn';
import { mkdir, writeFile } from 'node:fs/promises';
import { glob } from 'tinyglobby'; 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', () => { describe('Init command', () => {
it('should download and create a template', async () => { 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 () => { it('should throw an error if the directory is not empty', async () => {
const project = new TestProject(); const project = new TestProject();
await mkdir(project.root, { recursive: true }); await mkdir(project.root, { recursive: true });
await writeJson(project.resolvePath('package.json'), {}); await writeFile(project.resolvePath('package.json'), JSON.stringify({}));
await expect(() => await expect(() =>
spawn( spawn(
+1 -1
View File
@@ -1,7 +1,7 @@
import { describe, it, expect, vi } from 'vitest'; import { describe, it, expect, vi } from 'vitest';
import { TestProject } from '../utils'; import { TestProject } from '../utils';
import type { InlineConfig, UnlistedScriptEntrypoint } from '../../src'; import type { InlineConfig, UnlistedScriptEntrypoint } from '../../src';
import { readFile } from 'fs-extra'; import { readFile } from 'node:fs/promises';
import { normalizePath } from '../../src'; import { normalizePath } from '../../src';
describe('Module Helpers', () => { describe('Module Helpers', () => {
+1 -1
View File
@@ -2,7 +2,7 @@ import { describe, expect, it } from 'vitest';
import { TestProject } from '../utils'; import { TestProject } from '../utils';
import extract from 'extract-zip'; import extract from 'extract-zip';
import spawn from 'nano-spawn'; 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'; process.env.WXT_PNPM_IGNORE_WORKSPACE = 'true';
+10 -7
View File
@@ -1,8 +1,8 @@
import { glob } from 'tinyglobby';
import fs, { mkdir } from 'fs-extra';
import merge from 'lodash.merge'; import merge from 'lodash.merge';
import spawn from 'nano-spawn'; import spawn from 'nano-spawn';
import { mkdir, readFile, writeFile } from 'node:fs/promises';
import { dirname, relative, resolve } from 'path'; import { dirname, relative, resolve } from 'path';
import { glob } from 'tinyglobby';
import { import {
InlineConfig, InlineConfig,
UserConfig, UserConfig,
@@ -12,6 +12,7 @@ import {
zip, zip,
} from '../src'; } from '../src';
import { normalizePath } from '../src/core/utils'; 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 // 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 // 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 [name, content] = file;
const filePath = this.resolvePath(name); const filePath = this.resolvePath(name);
const fileDir = dirname(filePath); const fileDir = dirname(filePath);
await fs.ensureDir(fileDir); await mkdir(fileDir, { recursive: true });
await fs.writeFile(filePath, content ?? '', 'utf-8'); await writeFile(filePath, content ?? '', 'utf-8');
} }
// Only install dependencies if the project has custom ones - otherwise the // Only install dependencies if the project has custom ones - otherwise the
@@ -183,17 +184,19 @@ export class TestProject {
const absolutePath = this.resolvePath(path); const absolutePath = this.resolvePath(path);
return [ return [
normalizePath(relative(this.root, absolutePath)), normalizePath(relative(this.root, absolutePath)),
ignoreContents ? '<contents-ignored>' : await fs.readFile(absolutePath), ignoreContents
? '<contents-ignored>'
: await readFile(absolutePath, 'utf-8'),
].join(`\n${''.padEnd(40, '-')}\n`); ].join(`\n${''.padEnd(40, '-')}\n`);
} }
pathExists(...path: string[]): Promise<boolean> { pathExists(...path: string[]): Promise<boolean> {
return fs.pathExists(this.resolvePath(...path)); return pathExists(this.resolvePath(...path));
} }
getOutputManifest( getOutputManifest(
path: string = '.output/chrome-mv3/manifest.json', path: string = '.output/chrome-mv3/manifest.json',
): Promise<any> { ): Promise<any> {
return fs.readJson(this.resolvePath(path)); return readJson(this.resolvePath(path));
} }
} }
+1 -3
View File
@@ -1,7 +1,7 @@
{ {
"name": "wxt", "name": "wxt",
"type": "module", "type": "module",
"version": "0.20.18", "version": "0.20.19",
"description": "⚡ Next-gen Web Extension Framework", "description": "⚡ Next-gen Web Extension Framework",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
@@ -34,7 +34,6 @@
"dotenv-expand": "^12.0.3", "dotenv-expand": "^12.0.3",
"esbuild": "^0.27.1", "esbuild": "^0.27.1",
"filesize": "^11.0.13", "filesize": "^11.0.13",
"fs-extra": "^11.3.4",
"get-port-please": "^3.2.0", "get-port-please": "^3.2.0",
"giget": "^1.2.3 || ^2.0.0 || ^3.0.0", "giget": "^1.2.3 || ^2.0.0 || ^3.0.0",
"hookable": "^6.0.1", "hookable": "^6.0.1",
@@ -72,7 +71,6 @@
}, },
"devDependencies": { "devDependencies": {
"@faker-js/faker": "^10.3.0", "@faker-js/faker": "^10.3.0",
"@types/fs-extra": "^11.0.4",
"@types/lodash.merge": "^4.6.9", "@types/lodash.merge": "^4.6.9",
"@types/node": "^20.17.6", "@types/node": "^20.17.6",
"@types/normalize-path": "^3.0.2", "@types/normalize-path": "^3.0.2",
+6 -6
View File
@@ -26,7 +26,7 @@ import { ViteNodeRunner } from 'vite-node/client';
import { installSourcemapsSupport } from 'vite-node/source-map'; import { installSourcemapsSupport } from 'vite-node/source-map';
import { createExtensionEnvironment } from '../../utils/environments'; import { createExtensionEnvironment } from '../../utils/environments';
import { dirname, extname, join, relative } from 'node:path'; 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'; import { normalizePath } from '../../utils';
export async function createViteBuilder( export async function createViteBuilder(
@@ -455,8 +455,8 @@ async function moveHtmlFiles(
); );
const oldAbsPath = join(config.outDir, oldBundlePath); const oldAbsPath = join(config.outDir, oldBundlePath);
const newAbsPath = join(config.outDir, newBundlePath); const newAbsPath = join(config.outDir, newBundlePath);
await fs.ensureDir(dirname(newAbsPath)); await mkdir(dirname(newAbsPath), { recursive: true });
await fs.move(oldAbsPath, newAbsPath, { overwrite: true }); await rename(oldAbsPath, newAbsPath);
return { return {
...chunk, ...chunk,
@@ -473,17 +473,17 @@ async function moveHtmlFiles(
/** Recursively remove all directories that are empty/ */ /** Recursively remove all directories that are empty/ */
export async function removeEmptyDirs(dir: string): Promise<void> { export async function removeEmptyDirs(dir: string): Promise<void> {
const files = await fs.readdir(dir); const files = await readdir(dir);
for (const file of files) { for (const file of files) {
const filePath = join(dir, file); const filePath = join(dir, file);
const stats = await fs.stat(filePath); const stats = await stat(filePath);
if (stats.isDirectory()) { if (stats.isDirectory()) {
await removeEmptyDirs(filePath); await removeEmptyDirs(filePath);
} }
} }
try { try {
await fs.rmdir(dir); await rmdir(dir);
} catch { } catch {
// noop on failure - this means the directory was not empty. // noop on failure - this means the directory was not empty.
} }
@@ -1,4 +1,4 @@
import { pathExists } from 'fs-extra'; import { pathExists } from '../../../utils/fs';
import { resolve } from 'node:path'; import { resolve } from 'node:path';
import type * as vite from 'vite'; import type * as vite from 'vite';
import { ResolvedConfig } from '../../../../types'; import { ResolvedConfig } from '../../../../types';
@@ -1,3 +1,5 @@
import { readFile } from 'node:fs/promises';
import { resolve } from 'path';
import type { Plugin } from 'vite'; import type { Plugin } from 'vite';
import { ResolvedConfig } from '../../../../types'; import { ResolvedConfig } from '../../../../types';
import { normalizePath } from '../../../utils'; import { normalizePath } from '../../../utils';
@@ -5,8 +7,6 @@ import {
VirtualModuleId, VirtualModuleId,
virtualModuleNames, virtualModuleNames,
} from '../../../utils/virtual-modules'; } 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` * 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) { async handler(id) {
const inputPath = id.replace(resolvedVirtualId, ''); const inputPath = id.replace(resolvedVirtualId, '');
const template = await fs.readFile( const template = await readFile(
resolve(config.wxtModuleDir, `dist/virtual/${name}.mjs`), resolve(config.wxtModuleDir, `dist/virtual/${name}.mjs`),
'utf-8', 'utf-8',
); );
+3 -3
View File
@@ -1,7 +1,7 @@
import { rm } from 'node:fs/promises';
import path from 'node:path'; import path from 'node:path';
import { glob } from 'tinyglobby';
import fs from 'fs-extra';
import pc from 'picocolors'; import pc from 'picocolors';
import { glob } from 'tinyglobby';
import { InlineConfig } from '../types'; import { InlineConfig } from '../types';
import { registerWxt, wxt } from './wxt'; 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(', '), directories.map((dir) => pc.cyan(path.relative(root, dir))).join(', '),
); );
for (const directory of directories) { 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))); wxt.logger.debug('Deleted ' + pc.cyan(path.relative(root, directory)));
} }
} }
+6 -6
View File
@@ -1,12 +1,12 @@
import { Entrypoint, WxtDirEntry, WxtDirFileEntry } from '../types'; 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 { dirname, relative, resolve } from 'node:path';
import { getEntrypointBundlePath, isHtmlEntrypoint } from './utils/entrypoints'; import { getEntrypointBundlePath, isHtmlEntrypoint } from './utils/entrypoints';
import { getEntrypointGlobals, getGlobals } from './utils/globals'; import { getEntrypointGlobals, getGlobals } from './utils/globals';
import { normalizePath } from './utils'; import { normalizePath } from './utils';
import path from 'node:path'; import path from 'node:path';
import { Message, parseI18nMessages } from './utils/i18n'; import { Message, parseI18nMessages } from './utils/i18n';
import { writeFileIfDifferent, getPublicFiles } from './utils/fs'; import { pathExists, writeFileIfDifferent, getPublicFiles } from './utils/fs';
import { wxt } from './wxt'; import { wxt } from './wxt';
/** /**
@@ -14,7 +14,7 @@ import { wxt } from './wxt';
* directory. * directory.
*/ */
export async function generateWxtDir(entrypoints: Entrypoint[]): Promise<void> { export async function generateWxtDir(entrypoints: Entrypoint[]): Promise<void> {
await fs.ensureDir(wxt.config.typesDir); await mkdir(wxt.config.typesDir, { recursive: true });
const entries: WxtDirEntry[] = [ const entries: WxtDirEntry[] = [
// Hard-coded entries // Hard-coded entries
@@ -57,7 +57,7 @@ export async function generateWxtDir(entrypoints: Entrypoint[]): Promise<void> {
await Promise.all( await Promise.all(
absoluteFileEntries.map(async (file) => { absoluteFileEntries.map(async (file) => {
await fs.ensureDir(dirname(file.path)); await mkdir(dirname(file.path), { recursive: true });
await writeFileIfDifferent(file.path, file.text); await writeFileIfDifferent(file.path, file.text);
}), }),
); );
@@ -149,8 +149,8 @@ declare module "wxt/browser" {
'messages.json', 'messages.json',
); );
let messages: Message[]; let messages: Message[];
if (await fs.pathExists(defaultLocalePath)) { if (await pathExists(defaultLocalePath)) {
const content = JSON.parse(await fs.readFile(defaultLocalePath, 'utf-8')); const content = JSON.parse(await readFile(defaultLocalePath, 'utf-8'));
messages = parseI18nMessages(content); messages = parseI18nMessages(content);
} else { } else {
messages = parseI18nMessages({}); messages = parseI18nMessages({});
+6 -7
View File
@@ -1,7 +1,8 @@
import prompts from 'prompts'; import prompts from 'prompts';
import { consola } from 'consola'; import { consola } from 'consola';
import { downloadTemplate } from 'giget'; 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 path from 'node:path';
import pc from 'picocolors'; import pc from 'picocolors';
import { Formatter } from 'picocolors/types'; import { Formatter } from 'picocolors/types';
@@ -56,10 +57,10 @@ export async function initialize(options: {
input.template ??= defaultTemplate; input.template ??= defaultTemplate;
input.packageManager ??= options.packageManager; input.packageManager ??= options.packageManager;
const isExists = await fs.pathExists(input.directory); const isExists = await pathExists(input.directory);
if (isExists) { if (isExists) {
const isEmpty = const isEmpty =
(await fs.readdir(input.directory)).filter((dir) => dir !== '.git') (await readdir(input.directory)).filter((dir) => dir !== '.git')
.length === 0; .length === 0;
if (!isEmpty) { if (!isEmpty) {
consola.error( consola.error(
@@ -167,12 +168,10 @@ async function cloneProject({
}); });
// 2. Move _gitignore -> .gitignore // 2. Move _gitignore -> .gitignore
await fs await rename(
.move(
path.join(directory, '_gitignore'), path.join(directory, '_gitignore'),
path.join(directory, '.gitignore'), path.join(directory, '.gitignore'),
) ).catch((err) =>
.catch((err) =>
consola.warn('Failed to move _gitignore to .gitignore:', err), consola.warn('Failed to move _gitignore to .gitignore:', err),
); );
@@ -2,7 +2,7 @@ import { beforeAll, describe, expect, it } from 'vitest';
import path from 'node:path'; import path from 'node:path';
import { npm } from '../npm'; import { npm } from '../npm';
import spawn from 'nano-spawn'; import spawn from 'nano-spawn';
import { pathExists } from 'fs-extra'; import { pathExists } from '../../utils/fs';
describe('NPM Package Management Utils', () => { describe('NPM Package Management Utils', () => {
describe('listDependencies', () => { describe('listDependencies', () => {
@@ -1,13 +1,13 @@
import { Dependency } from '../../types'; import { Dependency } from '../../types';
import { WxtPackageManagerImpl } from './types'; import { WxtPackageManagerImpl } from './types';
import path from 'node:path'; import path from 'node:path';
import { ensureDir } from 'fs-extra'; import { mkdir } from 'node:fs/promises';
import spawn from 'nano-spawn'; import spawn from 'nano-spawn';
export const npm: WxtPackageManagerImpl = { export const npm: WxtPackageManagerImpl = {
overridesKey: 'overrides', overridesKey: 'overrides',
async downloadDependency(id, downloadDir) { async downloadDependency(id, downloadDir) {
await ensureDir(downloadDir); await mkdir(downloadDir, { recursive: true });
const res = await spawn('npm', ['pack', id, '--json'], { const res = await spawn('npm', ['pack', id, '--json'], {
cwd: downloadDir, cwd: downloadDir,
}); });
+2 -2
View File
@@ -20,7 +20,7 @@ import { createFsCache } from './utils/cache';
import consola, { LogLevels } from 'consola'; import consola, { LogLevels } from 'consola';
import defu from 'defu'; import defu from 'defu';
import { NullablyRequired } from './utils/types'; import { NullablyRequired } from './utils/types';
import fs from 'fs-extra'; import { pathExists } from './utils/fs';
import { normalizePath } from './utils'; import { normalizePath } from './utils';
import { glob } from 'tinyglobby'; import { glob } from 'tinyglobby';
import { builtinModules } from '../builtin-modules'; import { builtinModules } from '../builtin-modules';
@@ -543,7 +543,7 @@ function resolveWxtModuleDir() {
} }
async function isDirMissing(dir: string) { async function isDirMissing(dir: string) {
return !(await fs.pathExists(dir)); return !(await pathExists(dir));
} }
function logMissingDir(logger: Logger, name: string, expected: string) { function logMissingDir(logger: Logger, name: string, expected: string) {
@@ -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 { import {
BackgroundEntrypoint, BackgroundEntrypoint,
BackgroundEntrypointOptions, BackgroundEntrypointOptions,
@@ -9,21 +12,16 @@ import {
PopupEntrypoint, PopupEntrypoint,
SidepanelEntrypoint, SidepanelEntrypoint,
} from '../../../../types'; } 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 { wxt } from '../../../wxt';
import { unnormalizePath } from '../../paths';
import { fakeResolvedConfig, setFakeWxt } from '../../testing/fake-objects';
import { findEntrypoints } from '../find-entrypoints';
vi.mock('tinyglobby'); vi.mock('tinyglobby');
const globMock = vi.mocked(glob); const globMock = vi.mocked(glob);
vi.mock('fs-extra'); vi.mock('node:fs/promises');
const readFileMock = vi.mocked( const readFileMock = vi.mocked(readFile);
fs.readFile as (path: string) => Promise<string>,
);
describe('findEntrypoints', () => { describe('findEntrypoints', () => {
const config = fakeResolvedConfig({ const config = fakeResolvedConfig({
@@ -5,7 +5,7 @@ import {
ResolvedPublicFile, ResolvedPublicFile,
} from '../../../types'; } from '../../../types';
import { getPublicFiles } from '../fs'; import { getPublicFiles } from '../fs';
import fs from 'fs-extra'; import { copyFile, mkdir, writeFile } from 'node:fs/promises';
import { dirname, resolve } from 'path'; import { dirname, resolve } from 'path';
import type { Spinner } from 'nanospinner'; import type { Spinner } from 'nanospinner';
import pc from 'picocolors'; import pc from 'picocolors';
@@ -50,11 +50,11 @@ async function copyPublicDirectory(): Promise<BuildOutput['publicAssets']> {
for (const file of files) { for (const file of files) {
const absoluteDest = resolve(wxt.config.outDir, file.relativeDest); const absoluteDest = resolve(wxt.config.outDir, file.relativeDest);
await fs.ensureDir(dirname(absoluteDest)); await mkdir(dirname(absoluteDest), { recursive: true });
if ('absoluteSrc' in file) { if ('absoluteSrc' in file) {
await fs.copyFile(file.absoluteSrc, absoluteDest); await copyFile(file.absoluteSrc, absoluteDest);
} else { } else {
await fs.writeFile(absoluteDest, file.contents, 'utf8'); await writeFile(absoluteDest, file.contents, 'utf8');
} }
publicAssets.push({ publicAssets.push({
type: 'asset', type: 'asset',
@@ -12,7 +12,7 @@ import {
IsolatedWorldContentScriptEntrypointOptions, IsolatedWorldContentScriptEntrypointOptions,
UnlistedScriptEntrypoint, UnlistedScriptEntrypoint,
} from '../../../types'; } from '../../../types';
import fs from 'fs-extra'; import { mkdir, readFile, writeFile } from 'node:fs/promises';
import { minimatch } from 'minimatch'; import { minimatch } from 'minimatch';
import { parseHTML } from 'linkedom'; import { parseHTML } from 'linkedom';
import JSON5 from 'json5'; import JSON5 from 'json5';
@@ -35,11 +35,11 @@ import { camelCase } from 'scule';
*/ */
export async function findEntrypoints(): Promise<Entrypoint[]> { export async function findEntrypoints(): Promise<Entrypoint[]> {
// Make sure required TSConfig file exists to load dependencies // 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 { try {
await fs.writeJson( await writeFile(
resolve(wxt.config.wxtDir, 'tsconfig.json'), resolve(wxt.config.wxtDir, 'tsconfig.json'),
{}, JSON.stringify({}),
{ flag: 'wx' }, { flag: 'wx' },
); );
} catch (err) { } catch (err) {
@@ -204,7 +204,7 @@ async function importEntrypoints(infos: EntrypointInfo[]) {
async function importHtmlEntrypoint( async function importHtmlEntrypoint(
info: EntrypointInfo, info: EntrypointInfo,
): Promise<Record<string, any>> { ): Promise<Record<string, any>> {
const content = await fs.readFile(info.inputPath, 'utf-8'); const content = await readFile(info.inputPath, 'utf-8');
const { document } = parseHTML(content); const { document } = parseHTML(content);
const metaTags = document.querySelectorAll('meta'); const metaTags = document.querySelectorAll('meta');
@@ -1,7 +1,7 @@
import { findEntrypoints } from './find-entrypoints'; import { findEntrypoints } from './find-entrypoints';
import { BuildOutput, Entrypoint } from '../../../types'; import { BuildOutput, Entrypoint } from '../../../types';
import pc from 'picocolors'; import pc from 'picocolors';
import fs from 'fs-extra'; import { mkdir, rm } from 'node:fs/promises';
import { groupEntrypoints } from './group-entrypoints'; import { groupEntrypoints } from './group-entrypoints';
import { formatDuration } from '../time'; import { formatDuration } from '../time';
import { printBuildSummary } from '../log'; import { printBuildSummary } from '../log';
@@ -43,8 +43,8 @@ export async function internalBuild(): Promise<BuildOutput> {
const startTime = Date.now(); const startTime = Date.now();
// Cleanup // Cleanup
await fs.rm(wxt.config.outDir, { recursive: true, force: true }); await rm(wxt.config.outDir, { recursive: true, force: true });
await fs.ensureDir(wxt.config.outDir); await mkdir(wxt.config.outDir, { recursive: true });
const entrypoints = await findEntrypoints(); const entrypoints = await findEntrypoints();
wxt.logger.debug('Detected entrypoints:', entrypoints); wxt.logger.debug('Detected entrypoints:', entrypoints);
@@ -111,7 +111,9 @@ async function combineAnalysisStats(): Promise<void> {
}); });
if (!wxt.config.analysis.keepArtifacts) { if (!wxt.config.analysis.keepArtifacts) {
await Promise.all(absolutePaths.map((statsFile) => fs.remove(statsFile))); await Promise.all(
absolutePaths.map((statsFile) => rm(statsFile, { force: true })),
);
} }
} }
@@ -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 type { Browser } from '@wxt-dev/browser';
import { createSpinner } from 'nanospinner'; 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, * Given a configuration, list of entrypoints, and an existing, partial output,
@@ -22,7 +22,7 @@ import { createSpinner } from 'nanospinner';
* .wxt directory. * .wxt directory.
* @param entrypointGroups The list of entrypoint groups to build. * @param entrypointGroups The list of entrypoint groups to build.
* @param existingOutput The previous output to combine the rebuild results * @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( export async function rebuild(
allEntrypoints: Entrypoint[], allEntrypoints: Entrypoint[],
+3 -3
View File
@@ -1,4 +1,4 @@
import fs, { ensureDir } from 'fs-extra'; import { mkdir, readFile } from 'node:fs/promises';
import { FsCache } from '../../types'; import { FsCache } from '../../types';
import { dirname, resolve } from 'path'; import { dirname, resolve } from 'path';
import { writeFileIfDifferent } from './fs'; import { writeFileIfDifferent } from './fs';
@@ -16,13 +16,13 @@ export function createFsCache(wxtDir: string): FsCache {
return { return {
async set(key: string, value: string): Promise<void> { async set(key: string, value: string): Promise<void> {
const path = getPath(key); const path = getPath(key);
await ensureDir(dirname(path)); await mkdir(dirname(path), { recursive: true });
await writeFileIfDifferent(path, value); await writeFileIfDifferent(path, value);
}, },
async get(key: string): Promise<string | undefined> { async get(key: string): Promise<string | undefined> {
const path = getPath(key); const path = getPath(key);
try { try {
return await fs.readFile(path, 'utf-8'); return await readFile(path, 'utf-8');
} catch { } catch {
return undefined; return undefined;
} }
+18 -11
View File
@@ -1,7 +1,20 @@
import fs from 'fs-extra'; import { access, readFile, writeFile } from 'node:fs/promises';
import { glob } from 'tinyglobby'; import { glob } from 'tinyglobby';
import { unnormalizePath } from './paths';
import { wxt } from '../wxt'; import { wxt } from '../wxt';
import { unnormalizePath } from './paths';
export async function pathExists(path: string): Promise<boolean> {
try {
await access(path);
return true;
} catch {
return false;
}
}
export async function readJson<T = any>(path: string): Promise<T> {
return JSON.parse(await readFile(path, 'utf-8'));
}
/** /**
* Only write the contents to a file if it results in a change. This prevents * 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, file: string,
newContents: string, newContents: string,
): Promise<void> { ): Promise<void> {
const existingContents = await fs const existingContents = await readFile(file, 'utf-8').catch(() => undefined);
.readFile(file, 'utf-8')
.catch(() => undefined);
if (existingContents !== newContents) { 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<string[]> { export async function getPublicFiles(): Promise<string[]> {
if (!(await fs.pathExists(wxt.config.publicDir))) return []; if (!(await pathExists(wxt.config.publicDir))) return [];
const files = await glob('**/*', { const files = await glob('**/*', {
cwd: wxt.config.publicDir, cwd: wxt.config.publicDir,
@@ -1,6 +1,6 @@
import path from 'node:path'; import path from 'node:path';
import pc from 'picocolors'; import pc from 'picocolors';
import fs from 'fs-extra'; import { lstat } from 'node:fs/promises';
import { filesize } from 'filesize'; import { filesize } from 'filesize';
import { printTable } from './printTable'; import { printTable } from './printTable';
@@ -20,7 +20,7 @@ export async function printFileList(
]; ];
const prefix = i === files.length - 1 ? ' └─' : ' ├─'; const prefix = i === files.length - 1 ? ' └─' : ' ├─';
const color = getChunkColor(file); const color = getChunkColor(file);
const stats = await fs.lstat(file); const stats = await lstat(file);
totalSize += stats.size; totalSize += stats.size;
const size = String(filesize(stats.size)); const size = String(filesize(stats.size));
return [ return [
+2 -2
View File
@@ -7,7 +7,7 @@ import {
PopupEntrypoint, PopupEntrypoint,
SidepanelEntrypoint, SidepanelEntrypoint,
} from '../../types'; } from '../../types';
import fs from 'fs-extra'; import { mkdir } from 'node:fs/promises';
import { resolve } from 'path'; import { resolve } from 'path';
import { getEntrypointBundlePath } from './entrypoints'; import { getEntrypointBundlePath } from './entrypoints';
import { ContentSecurityPolicy } from './content-security-policy'; import { ContentSecurityPolicy } from './content-security-policy';
@@ -33,7 +33,7 @@ export async function writeManifest(
? JSON.stringify(manifest) ? JSON.stringify(manifest)
: JSON.stringify(manifest, null, 2); : 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); await writeFileIfDifferent(resolve(wxt.config.outDir, 'manifest.json'), str);
output.publicAssets.unshift({ output.publicAssets.unshift({
+2 -2
View File
@@ -1,5 +1,5 @@
import { resolve } from 'node:path'; import { resolve } from 'node:path';
import fs from 'fs-extra'; import { readJson } from './fs';
import { wxt } from '../wxt'; import { wxt } from '../wxt';
/** /**
@@ -12,7 +12,7 @@ export async function getPackageJson(): Promise<
> { > {
const file = resolve(wxt.config.root, 'package.json'); const file = resolve(wxt.config.root, 'package.json');
try { try {
return await fs.readJson(file); return await readJson(file);
} catch (err) { } catch (err) {
wxt.logger.debug( wxt.logger.debug(
`Failed to read package.json at: ${file}. Returning undefined.`, `Failed to read package.json at: ${file}. Returning undefined.`,
+6 -5
View File
@@ -1,6 +1,7 @@
import { InlineConfig } from '../types'; import { InlineConfig } from '../types';
import path from 'node:path'; 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 { safeFilename } from './utils/strings';
import { getPackageJson } from './utils/package'; import { getPackageJson } from './utils/package';
import { formatDuration } from './utils/time'; import { formatDuration } from './utils/time';
@@ -43,7 +44,7 @@ export async function zip(config?: InlineConfig): Promise<string[]> {
.replaceAll('{{mode}}', wxt.config.mode) .replaceAll('{{mode}}', wxt.config.mode)
.replaceAll('{{manifestVersion}}', `mv${wxt.config.manifestVersion}`); .replaceAll('{{manifestVersion}}', `mv${wxt.config.manifestVersion}`);
await fs.ensureDir(wxt.config.outBaseDir); await mkdir(wxt.config.outBaseDir, { recursive: true });
// ZIP output directory // ZIP output directory
await wxt.hooks.callHook('zip:extension:start', wxt); await wxt.hooks.callHook('zip:extension:start', wxt);
@@ -137,13 +138,13 @@ async function zipDir(
for (const file of filesToZip) { for (const file of filesToZip) {
const absolutePath = path.resolve(directory, file); const absolutePath = path.resolve(directory, file);
if (file.endsWith('.json')) { if (file.endsWith('.json')) {
const content = await fs.readFile(absolutePath, 'utf-8'); const content = await readFile(absolutePath, 'utf-8');
archive.file( archive.file(
file, file,
(await options?.transform?.(absolutePath, file, content)) || content, (await options?.transform?.(absolutePath, file, content)) || content,
); );
} else { } else {
const content = await fs.readFile(absolutePath); const content = await readFile(absolutePath);
archive.file(file, content); archive.file(file, content);
} }
} }
@@ -160,7 +161,7 @@ async function zipDir(
compressionOptions: { level: wxt.config.zip.compressionLevel }, compressionOptions: { level: wxt.config.zip.compressionLevel },
}), }),
}) })
.pipe(fs.createWriteStream(outputPath)) .pipe(createWriteStream(outputPath))
.on('error', reject) .on('error', reject)
.on('close', resolve), .on('close', resolve),
); );
+5 -2
View File
@@ -1,4 +1,4 @@
import { pathExists, rm } from 'fs-extra'; import { access, rm } from 'node:fs/promises';
let setupHappened = false; let setupHappened = false;
@@ -12,7 +12,10 @@ export async function setup() {
globalThis.__ENTRYPOINT__ = 'test'; globalThis.__ENTRYPOINT__ = 'test';
const e2eDistPath = './e2e/dist/'; const e2eDistPath = './e2e/dist/';
if (await pathExists(e2eDistPath)) { try {
await access(e2eDistPath);
await rm(e2eDistPath, { recursive: true, force: true }); await rm(e2eDistPath, { recursive: true, force: true });
} catch {
// Directory doesn't exist, nothing to clean up
} }
} }
+16 -82
View File
@@ -25,9 +25,6 @@ importers:
'@commitlint/types': '@commitlint/types':
specifier: ^20.4.3 specifier: ^20.4.3
version: 20.4.3 version: 20.4.3
'@types/fs-extra':
specifier: ^11.0.4
version: 11.0.4
'@types/semver': '@types/semver':
specifier: ^7.7.1 specifier: ^7.7.1
version: 7.7.1 version: 7.7.1
@@ -43,12 +40,6 @@ importers:
feed: feed:
specifier: ^5.2.0 specifier: ^5.2.0
version: 5.2.0 version: 5.2.0
fs-extra:
specifier: ^11.3.4
version: 11.3.4
lint-staged:
specifier: ^16.3.2
version: 16.3.2
markdown-it-footnote: markdown-it-footnote:
specifier: ^4.0.0 specifier: ^4.0.0
version: 4.0.0(patch_hash=5b74a0001a771ff5df790dd36b6883c4794e1f666b231499edb2d65eae8f4930) version: 4.0.0(patch_hash=5b74a0001a771ff5df790dd36b6883c4794e1f666b231499edb2d65eae8f4930)
@@ -58,6 +49,9 @@ importers:
nano-spawn: nano-spawn:
specifier: ^2.0.0 specifier: ^2.0.0
version: 2.0.0 version: 2.0.0
nano-staged:
specifier: ^0.8.0
version: 0.8.0
p-map: p-map:
specifier: ^7.0.4 specifier: ^7.0.4
version: 7.0.4 version: 7.0.4
@@ -149,9 +143,6 @@ importers:
defu: defu:
specifier: ^6.1.4 specifier: ^6.1.4
version: 6.1.4 version: 6.1.4
fs-extra:
specifier: ^11.3.4
version: 11.3.4
sharp: sharp:
specifier: ^0.34.5 specifier: ^0.34.5
version: 0.34.5 version: 0.34.5
@@ -184,9 +175,9 @@ importers:
'@types/chrome': '@types/chrome':
specifier: 0.1.37 specifier: 0.1.37
version: 0.1.37 version: 0.1.37
fs-extra: '@types/node':
specifier: ^11.3.4 specifier: ^20.0.0
version: 11.3.4 version: 20.19.32
nano-spawn: nano-spawn:
specifier: ^2.0.0 specifier: ^2.0.0
version: 2.0.0 version: 2.0.0
@@ -256,7 +247,7 @@ importers:
packages/module-react: packages/module-react:
dependencies: dependencies:
'@vitejs/plugin-react': '@vitejs/plugin-react':
specifier: ^4.4.1 || ^5.0.0 specifier: ^4.4.1 || ^5.0.0 || ^6.0.0
version: 5.1.4(vite@7.3.1(@types/node@20.19.32)(jiti@2.6.1)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2)) version: 5.1.4(vite@7.3.1(@types/node@20.19.32)(jiti@2.6.1)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2))
devDependencies: devDependencies:
'@types/react': '@types/react':
@@ -477,9 +468,6 @@ importers:
filesize: filesize:
specifier: ^11.0.13 specifier: ^11.0.13
version: 11.0.13 version: 11.0.13
fs-extra:
specifier: ^11.3.4
version: 11.3.4
get-port-please: get-port-please:
specifier: ^3.2.0 specifier: ^3.2.0
version: 3.2.0 version: 3.2.0
@@ -562,9 +550,6 @@ importers:
'@faker-js/faker': '@faker-js/faker':
specifier: ^10.3.0 specifier: ^10.3.0
version: 10.3.0 version: 10.3.0
'@types/fs-extra':
specifier: ^11.0.4
version: 11.0.4
'@types/lodash.merge': '@types/lodash.merge':
specifier: ^4.6.9 specifier: ^4.6.9
version: 4.6.9 version: 4.6.9
@@ -2165,9 +2150,6 @@ packages:
'@types/filewriter@0.0.33': '@types/filewriter@0.0.33':
resolution: {integrity: sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==} resolution: {integrity: sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==}
'@types/fs-extra@11.0.4':
resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==}
'@types/har-format@1.2.16': '@types/har-format@1.2.16':
resolution: {integrity: sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A==} resolution: {integrity: sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A==}
@@ -2180,9 +2162,6 @@ packages:
'@types/json-schema@7.0.15': '@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
'@types/jsonfile@6.1.4':
resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==}
'@types/katex@0.16.8': '@types/katex@0.16.8':
resolution: {integrity: sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==} resolution: {integrity: sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==}
@@ -3630,19 +3609,10 @@ packages:
linkify-it@5.0.0: linkify-it@5.0.0:
resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==}
lint-staged@16.3.2:
resolution: {integrity: sha512-xKqhC2AeXLwiAHXguxBjuChoTTWFC6Pees0SHPwOpwlvI3BH7ZADFPddAdN3pgo3aiKgPUx/bxE78JfUnxQnlg==}
engines: {node: '>=20.17'}
hasBin: true
listr2@10.1.0: listr2@10.1.0:
resolution: {integrity: sha512-/6t2KgDYIcCjhELwvrRxi1gaJ4xCGLTjNvh6mSjYenBkrZxggek8EwCbwBU33GMUCpyyrOzz2TzylrO5mTiI1w==} resolution: {integrity: sha512-/6t2KgDYIcCjhELwvrRxi1gaJ4xCGLTjNvh6mSjYenBkrZxggek8EwCbwBU33GMUCpyyrOzz2TzylrO5mTiI1w==}
engines: {node: '>=22.0.0'} engines: {node: '>=22.0.0'}
listr2@9.0.5:
resolution: {integrity: sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==}
engines: {node: '>=20.0.0'}
local-pkg@1.1.2: local-pkg@1.1.2:
resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==} resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==}
engines: {node: '>=14'} engines: {node: '>=14'}
@@ -3675,10 +3645,6 @@ packages:
lodash.once@4.1.1: lodash.once@4.1.1:
resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==}
log-update@6.1.0:
resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==}
engines: {node: '>=18'}
log-update@7.1.0: log-update@7.1.0:
resolution: {integrity: sha512-y9pi/ZOQQVvTgfRDEHV1Cj4zQUkJZPipEUNOxhn1R6KgmdMs7LKvXWCd9eMVPGJgvYzFLCenecWr0Ps8ChVv2A==} resolution: {integrity: sha512-y9pi/ZOQQVvTgfRDEHV1Cj4zQUkJZPipEUNOxhn1R6KgmdMs7LKvXWCd9eMVPGJgvYzFLCenecWr0Ps8ChVv2A==}
engines: {node: '>=20'} engines: {node: '>=20'}
@@ -3924,6 +3890,11 @@ packages:
resolution: {integrity: sha512-tacvGzUY5o2D8CBh2rrwxyNojUsZNU2zjNTzKQrkgGJQTbGAfArVWXSKMBokBeeg6C7OLRGUEyoFlYbfeWQIqw==} resolution: {integrity: sha512-tacvGzUY5o2D8CBh2rrwxyNojUsZNU2zjNTzKQrkgGJQTbGAfArVWXSKMBokBeeg6C7OLRGUEyoFlYbfeWQIqw==}
engines: {node: '>=20.17'} engines: {node: '>=20.17'}
nano-staged@0.8.0:
resolution: {integrity: sha512-QSEqPGTCJbkHU2yLvfY6huqYPjdBrOaTMKatO1F8nCSrkQGXeKwtCiCnsdxnuMhbg3DTVywKaeWLGCE5oJpq0g==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
hasBin: true
nanoid@3.3.11: nanoid@3.3.11:
resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@@ -4501,10 +4472,6 @@ packages:
std-env@3.10.0: std-env@3.10.0:
resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==}
string-argv@0.3.2:
resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==}
engines: {node: '>=0.6.19'}
string-width@4.2.3: string-width@4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'} engines: {node: '>=8'}
@@ -6291,11 +6258,6 @@ snapshots:
'@types/filewriter@0.0.33': {} '@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/har-format@1.2.16': {}
'@types/hast@3.0.4': '@types/hast@3.0.4':
@@ -6306,10 +6268,6 @@ snapshots:
'@types/json-schema@7.0.15': {} '@types/json-schema@7.0.15': {}
'@types/jsonfile@6.1.4':
dependencies:
'@types/node': 20.19.32
'@types/katex@0.16.8': {} '@types/katex@0.16.8': {}
'@types/linkify-it@5.0.0': {} '@types/linkify-it@5.0.0': {}
@@ -7803,15 +7761,6 @@ snapshots:
dependencies: dependencies:
uc.micro: 2.1.0 uc.micro: 2.1.0
lint-staged@16.3.2:
dependencies:
commander: 14.0.3
listr2: 9.0.5
micromatch: 4.0.8
string-argv: 0.3.2
tinyexec: 1.0.2
yaml: 2.8.2
listr2@10.1.0: listr2@10.1.0:
dependencies: dependencies:
cli-truncate: 5.1.1 cli-truncate: 5.1.1
@@ -7821,15 +7770,6 @@ snapshots:
rfdc: 1.4.1 rfdc: 1.4.1
wrap-ansi: 9.0.2 wrap-ansi: 9.0.2
listr2@9.0.5:
dependencies:
cli-truncate: 5.1.1
colorette: 2.0.20
eventemitter3: 5.0.4
log-update: 6.1.0
rfdc: 1.4.1
wrap-ansi: 9.0.2
local-pkg@1.1.2: local-pkg@1.1.2:
dependencies: dependencies:
mlly: 1.8.1 mlly: 1.8.1
@@ -7856,14 +7796,6 @@ snapshots:
lodash.once@4.1.1: {} lodash.once@4.1.1: {}
log-update@6.1.0:
dependencies:
ansi-escapes: 7.3.0
cli-cursor: 5.0.0
slice-ansi: 7.1.2
strip-ansi: 7.1.2
wrap-ansi: 9.0.2
log-update@7.1.0: log-update@7.1.0:
dependencies: dependencies:
ansi-escapes: 7.3.0 ansi-escapes: 7.3.0
@@ -8288,6 +8220,10 @@ snapshots:
nano-spawn@2.0.0: {} nano-spawn@2.0.0: {}
nano-staged@0.8.0:
dependencies:
picocolors: 1.1.1
nanoid@3.3.11: {} nanoid@3.3.11: {}
nanospinner@1.2.2: nanospinner@1.2.2:
@@ -8997,8 +8933,6 @@ snapshots:
std-env@3.10.0: {} std-env@3.10.0: {}
string-argv@0.3.2: {}
string-width@4.2.3: string-width@4.2.3:
dependencies: dependencies:
emoji-regex: 8.0.0 emoji-regex: 8.0.0
+14 -10
View File
@@ -6,7 +6,7 @@ import {
parseCommits, parseCommits,
} from 'changelogen'; } from 'changelogen';
import { consola } from 'consola'; import { consola } from 'consola';
import fs from 'fs-extra'; import { readdir, readFile, writeFile } from 'node:fs/promises';
import spawn from 'nano-spawn'; import spawn from 'nano-spawn';
import path from 'node:path'; import path from 'node:path';
import { getPkgTag, grabPackageDetails, listCommitsInDir } from './git'; import { getPkgTag, grabPackageDetails, listCommitsInDir } from './git';
@@ -41,7 +41,7 @@ if (currentVersion.startsWith('0.')) {
await spawn('pnpm', ['version', bumpType], { await spawn('pnpm', ['version', bumpType], {
cwd: pkgDir, cwd: pkgDir,
}); });
const updatedPkgJson = await fs.readJson(pkgJsonPath); const updatedPkgJson = JSON.parse(await readFile(pkgJsonPath, 'utf-8'));
const newVersion: string = updatedPkgJson.version; const newVersion: string = updatedPkgJson.version;
const newTag = getPkgTag(pkg, newVersion); const newTag = getPkgTag(pkg, newVersion);
consola.info('Bump:', { currentVersion, bumpType, newVersion }); consola.info('Bump:', { currentVersion, bumpType, newVersion });
@@ -63,8 +63,7 @@ if (originalBumpType === 'major') {
`[⚠️ breaking changes](https://wxt.dev/guide/resources/upgrading.html) &bull; [compare changes]`, `[⚠️ breaking changes](https://wxt.dev/guide/resources/upgrading.html) &bull; [compare changes]`,
); );
} }
const { releases: prevReleases } = await fs const { releases: prevReleases } = await readFile(changelogPath, 'utf8')
.readFile(changelogPath, 'utf8')
.then(parseChangelogMarkdown) .then(parseChangelogMarkdown)
.catch(() => ({ releases: [] })); .catch(() => ({ releases: [] }));
const allReleases = [ const allReleases = [
@@ -80,29 +79,34 @@ const newChangelog =
allReleases allReleases
.map((release) => [`## v${release.version}`, release.body].join('\n\n')) .map((release) => [`## v${release.version}`, release.body].join('\n\n'))
.join('\n\n'); .join('\n\n');
await fs.writeFile(changelogPath, newChangelog, 'utf8'); await writeFile(changelogPath, newChangelog, 'utf8');
consola.success('Updated changelog'); consola.success('Updated changelog');
// Update WXT version in templates when releasing wxt package // Update WXT version in templates when releasing wxt package
const templatePkgJsonPaths: string[] = []; const templatePkgJsonPaths: string[] = [];
if (pkg === 'wxt') { if (pkg === 'wxt') {
const templatesDir = 'templates'; const templatesDir = 'templates';
const templateDirs = await fs.readdir(templatesDir); const templateDirs = await readdir(templatesDir);
for (const templateDir of templateDirs) { for (const templateDir of templateDirs) {
const templatePkgJsonPath = path.join( const templatePkgJsonPath = path.join(
templatesDir, templatesDir,
templateDir, templateDir,
'package.json', 'package.json',
); );
if (await fs.pathExists(templatePkgJsonPath)) { try {
const templatePkgJson = await fs.readJson(templatePkgJsonPath); const templatePkgJson = JSON.parse(
await readFile(templatePkgJsonPath, 'utf-8'),
);
if (templatePkgJson.devDependencies?.wxt) { if (templatePkgJson.devDependencies?.wxt) {
templatePkgJson.devDependencies.wxt = `^${newVersion}`; templatePkgJson.devDependencies.wxt = `^${newVersion}`;
await fs.writeJson(templatePkgJsonPath, templatePkgJson, { spaces: 2 }); await writeFile(
templatePkgJsonPath,
JSON.stringify(templatePkgJson, null, 2),
);
templatePkgJsonPaths.push(templatePkgJsonPath); templatePkgJsonPaths.push(templatePkgJsonPath);
consola.success(`Updated wxt version in ${templatePkgJsonPath}`); consola.success(`Updated wxt version in ${templatePkgJsonPath}`);
} }
} } catch {}
} }
} }
+2 -3
View File
@@ -4,7 +4,7 @@ import {
loadChangelogConfig, loadChangelogConfig,
parseChangelogMarkdown, parseChangelogMarkdown,
} from 'changelogen'; } from 'changelogen';
import fs from 'fs-extra'; import { readFile } from 'node:fs/promises';
import { grabPackageDetails } from './git'; import { grabPackageDetails } from './git';
import consola from 'consola'; import consola from 'consola';
@@ -19,8 +19,7 @@ const { pkgName, prevTag, currentVersion, changelogPath } =
await grabPackageDetails(pkg); await grabPackageDetails(pkg);
consola.info('Creating release for:', { pkg, pkgName, prevTag }); consola.info('Creating release for:', { pkg, pkgName, prevTag });
const { releases } = await fs const { releases } = await readFile(changelogPath, 'utf8')
.readFile(changelogPath, 'utf8')
.then(parseChangelogMarkdown) .then(parseChangelogMarkdown)
.catch(() => ({ releases: [] })); .catch(() => ({ releases: [] }));
+2 -2
View File
@@ -1,11 +1,11 @@
import { RawGitCommit, getGitDiff } from 'changelogen'; import { RawGitCommit, getGitDiff } from 'changelogen';
import { consola } from 'consola'; import { consola } from 'consola';
import fs from 'fs-extra'; import { readFile } from 'node:fs/promises';
export async function grabPackageDetails(pkg: string) { export async function grabPackageDetails(pkg: string) {
const pkgDir = `packages/${pkg}`; const pkgDir = `packages/${pkg}`;
const pkgJsonPath = `${pkgDir}/package.json`; 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; const currentVersion: string = pkgJson.version;
return { return {
pkgDir, pkgDir,
+2 -3
View File
@@ -5,7 +5,7 @@ import {
updateGithubRelease, updateGithubRelease,
} from 'changelogen'; } from 'changelogen';
import { getPkgTag, grabPackageDetails } from './git'; import { getPkgTag, grabPackageDetails } from './git';
import fs from 'fs-extra'; import { readFile } from 'node:fs/promises';
import consola from 'consola'; import consola from 'consola';
const pkg = process.argv[2]; const pkg = process.argv[2];
@@ -17,8 +17,7 @@ if (!pkg) {
// Update // Update
const { changelogPath, pkgName } = await grabPackageDetails(pkg); const { changelogPath, pkgName } = await grabPackageDetails(pkg);
const { releases } = await fs const { releases } = await readFile(changelogPath, 'utf8')
.readFile(changelogPath, 'utf8')
.then(parseChangelogMarkdown) .then(parseChangelogMarkdown)
.catch(() => ({ releases: [] })); .catch(() => ({ releases: [] }));
const config = await loadChangelogConfig(process.cwd()); const config = await loadChangelogConfig(process.cwd());
+7 -7
View File
@@ -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 consola from 'consola';
import spawn from 'nano-spawn'; import spawn from 'nano-spawn';
import { readFile, writeFile } from 'node:fs/promises';
import { dirname } from 'node:path';
import pMap from 'p-map'; import pMap from 'p-map';
import * as semver from 'semver';
import { glob } from 'tinyglobby';
const HELP_MESSAGE = ` const HELP_MESSAGE = `
Upgrades dependencies throughout WXT using custom rules. Upgrades dependencies throughout WXT using custom rules.
@@ -101,7 +101,7 @@ async function getPackageJsonDependencies(
); );
const packageJsons: PackageJsonData[] = await Promise.all( const packageJsons: PackageJsonData[] = await Promise.all(
packageJsonFiles.map(async (path) => ({ packageJsonFiles.map(async (path) => ({
content: await fs.readJson(path), content: JSON.parse(await readFile(path, 'utf-8')),
path, path,
folder: dirname(path), folder: dirname(path),
})), })),
@@ -341,7 +341,7 @@ async function writeUpgrades(
upgrades: UpgradeDetails[], upgrades: UpgradeDetails[],
) { ) {
for (const packageJsonFile of packageJsonFiles) { for (const packageJsonFile of packageJsonFiles) {
const oldText = await fs.readFile(packageJsonFile, 'utf8'); const oldText = await readFile(packageJsonFile, 'utf8');
let newText = oldText; let newText = oldText;
for (const upgrade of upgrades) { for (const upgrade of upgrades) {
const search = `"${upgrade.name}": "${upgrade.currentRange}"`; const search = `"${upgrade.name}": "${upgrade.currentRange}"`;
@@ -349,7 +349,7 @@ async function writeUpgrades(
newText = newText.replaceAll(search, replace); newText = newText.replaceAll(search, replace);
} }
if (newText !== oldText) { if (newText !== oldText) {
await fs.writeFile(packageJsonFile, newText, 'utf8'); await writeFile(packageJsonFile, newText, 'utf8');
} }
} }
} }
+1 -1
View File
@@ -23,6 +23,6 @@
"@types/react-dom": "^19.2.3", "@types/react-dom": "^19.2.3",
"@wxt-dev/module-react": "^1.1.5", "@wxt-dev/module-react": "^1.1.5",
"typescript": "^5.9.3", "typescript": "^5.9.3",
"wxt": "^0.20.18" "wxt": "^0.20.19"
} }
} }
+1 -1
View File
@@ -20,6 +20,6 @@
"devDependencies": { "devDependencies": {
"@wxt-dev/module-solid": "^1.1.4", "@wxt-dev/module-solid": "^1.1.4",
"typescript": "^5.9.3", "typescript": "^5.9.3",
"wxt": "^0.20.18" "wxt": "^0.20.19"
} }
} }
+1 -1
View File
@@ -21,6 +21,6 @@
"svelte-check": "^4.4.4", "svelte-check": "^4.4.4",
"tslib": "^2.8.1", "tslib": "^2.8.1",
"typescript": "^5.9.3", "typescript": "^5.9.3",
"wxt": "^0.20.18" "wxt": "^0.20.19"
} }
} }
+1 -1
View File
@@ -16,6 +16,6 @@
}, },
"devDependencies": { "devDependencies": {
"typescript": "^5.9.3", "typescript": "^5.9.3",
"wxt": "^0.20.18" "wxt": "^0.20.19"
} }
} }
+1 -1
View File
@@ -21,6 +21,6 @@
"@wxt-dev/module-vue": "^1.0.3", "@wxt-dev/module-vue": "^1.0.3",
"typescript": "^5.9.3", "typescript": "^5.9.3",
"vue-tsc": "^3.2.5", "vue-tsc": "^3.2.5",
"wxt": "^0.20.18" "wxt": "^0.20.19"
} }
} }