Skip to content

Commit 70598b5

Browse files
committedMar 15, 2025·
feat(build): add packaging scripts for Chrome and Firefox extensions
1 parent 290dc9e commit 70598b5

File tree

6 files changed

+468
-72
lines changed

6 files changed

+468
-72
lines changed
 

‎.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,4 @@ dist-ssr
2424
*.sw?
2525
.env
2626
dev-dist
27+
packages

‎bun.lock

+362-53
Large diffs are not rendered by default.

‎package.json

+9-3
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,14 @@
66
"scripts": {
77
"dev": "vite dev",
88
"build": "vite build",
9-
"lint": "eslint .",
9+
"build:chrome": "vite build --mode chrome",
10+
"build:firefox": "vite build --mode firefox",
1011
"preview": "vite preview",
11-
"test": "npx tailwindcss init"
12+
"start:chrome": "npm run build:chrome && web-ext run --source-dir=dist --target=chromium",
13+
"start:firefox": "npm run build:firefox && web-ext run --source-dir=dist --target=firefox-desktop",
14+
"package": "node scripts/package-extension.js",
15+
"package:chrome": "node scripts/package-extension.js chrome",
16+
"package:firefox": "node scripts/package-extension.js firefox"
1217
},
1318
"dependencies": {
1419
"@tanstack/react-query": "5.66.0",
@@ -54,6 +59,7 @@
5459
"tailwindcss": "4.0.0",
5560
"typescript": "~5.6.3",
5661
"typescript-eslint": "8.18.2",
57-
"vite": "6.0.5"
62+
"vite": "6.0.5",
63+
"web-ext": "^8.4.0"
5864
}
5965
}

‎scripts/package-extension.js

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/usr/bin/env node
2+
import { execSync } from 'node:child_process';
3+
import fs from 'node:fs';
4+
import path from 'node:path';
5+
6+
7+
const browser = process.argv[2] || 'chrome';
8+
9+
10+
const packageJson = JSON.parse(fs.readFileSync('./src/manifest.json', 'utf8'));
11+
const version = packageJson.version;
12+
13+
14+
const zipFilename = `widgetify-${version}-${browser}.zip`;
15+
16+
17+
if (!fs.existsSync('./packages')) {
18+
fs.mkdirSync('./packages', { recursive: true });
19+
}
20+
21+
22+
console.log(`Building ${browser} extension...`);
23+
execSync(`npm run build:${browser}`, { stdio: 'inherit' });
24+
25+
26+
console.log(`Packaging ${browser} extension as ${zipFilename}...`);
27+
execSync(
28+
`web-ext build --source-dir=dist --artifacts-dir=packages --filename=${zipFilename} --overwrite-dest`,
29+
{ stdio: 'inherit' }
30+
);
31+
32+
console.log(`Successfully packaged ${zipFilename}`);

‎src/manifest.json

+12-4
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,23 @@
2121
"https://api.github.com/*",
2222
"https://api.widgetify.ir/*",
2323
"https://www.google.com/search*",
24-
"https://www.google-analytics.com/collect*"
24+
"https://www.google-analytics.com/collect*",
25+
"https://storage.c2.liara.space/*"
2526
],
2627
"options_ui": {
2728
"page": "src/index.html",
2829
"open_in_tab": true
2930
},
30-
"background": {
31-
"{{chrome}}.service_worker": "src/background.ts",
32-
"{{firefox}}.scripts": ["src/background.ts"]
31+
"{{chrome}}.background": {
32+
"service_worker": "src/background.ts"
33+
},
34+
"{{firefox}}.background": {
35+
"scripts": ["src/background.ts"]
36+
},
37+
"{{firefox}}.browser_specific_settings": {
38+
"gecko": {
39+
"id": "widgetify@widgetify-app.github.io"
40+
}
3341
},
3442
"content_security_policy": {
3543
"extension_pages": "script-src 'self'; object-src 'self'; style-src 'self' 'unsafe-inline';"

‎vite.config.ts

+52-12
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,65 @@ import react from '@vitejs/plugin-react'
33
import { defineConfig } from 'vite'
44
import webExtension, { readJsonFile } from 'vite-plugin-web-extension'
55

6-
function generateManifest() {
6+
function generateManifest(browser: any) {
77
const manifest = readJsonFile('src/manifest.json')
88
const pkg = readJsonFile('package.json')
9+
10+
const processedManifest = JSON.parse(
11+
JSON.stringify(manifest).replace(new RegExp(`{{${browser}}}\\.`, 'g'), ''),
12+
)
13+
14+
const otherBrowser = browser === 'firefox' ? 'chrome' : 'firefox'
15+
for (const key of Object.keys(processedManifest)) {
16+
if (key.startsWith(`{{${otherBrowser}}}.`)) {
17+
delete processedManifest[key]
18+
}
19+
}
20+
21+
const processNestedObjects = (obj: any) => {
22+
for (const key of Object.keys(obj)) {
23+
if (typeof obj[key] === 'object' && obj[key] !== null) {
24+
for (const nestedKey of Object.keys(obj[key])) {
25+
if (nestedKey.startsWith(`{{${otherBrowser}}}.`)) {
26+
delete obj[key][nestedKey]
27+
}
28+
if (nestedKey.startsWith(`{{${browser}}}.`)) {
29+
const newKey = nestedKey.replace(`{{${browser}}}.`, '')
30+
obj[key][newKey] = obj[key][nestedKey]
31+
delete obj[key][nestedKey]
32+
}
33+
}
34+
35+
processNestedObjects(obj[key])
36+
}
37+
}
38+
}
39+
40+
processNestedObjects(processedManifest)
41+
942
return {
1043
name: pkg.name,
1144
description: pkg.description,
1245
version: pkg.version,
13-
...manifest,
46+
...processedManifest,
1447
}
1548
}
1649

17-
// https://vite.dev/config/
18-
export default defineConfig({
19-
plugins: [
20-
react(),
21-
tailwindcss(),
22-
webExtension({
23-
manifest: generateManifest,
24-
browser: 'chrome',
25-
}),
26-
],
50+
export default defineConfig(({ mode }) => {
51+
const browser = mode === 'firefox' ? 'firefox' : 'chrome'
52+
53+
return {
54+
plugins: [
55+
react(),
56+
tailwindcss(),
57+
webExtension({
58+
manifest: () => generateManifest(browser),
59+
browser,
60+
}),
61+
],
62+
build: {
63+
outDir: 'dist',
64+
emptyOutDir: true,
65+
},
66+
}
2767
})

0 commit comments

Comments
 (0)
Please sign in to comment.