Skip to content

Commit df03f31

Browse files
committed
Firefox ready build script
1 parent 18697b0 commit df03f31

File tree

10 files changed

+653
-499
lines changed

10 files changed

+653
-499
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ We welcome contributions from the community! Whether fixing bugs, adding feature
3838

3939
```bash
4040
npm install
41-
node build.js
41+
npm build.js
4242
```
4343

4444
---

build.js

Lines changed: 0 additions & 92 deletions
This file was deleted.

buildScripts/build-chrome.js

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
import { build } from "esbuild";
2+
import {
3+
rmSync,
4+
mkdirSync,
5+
cpSync,
6+
writeFileSync,
7+
createWriteStream,
8+
} from "fs";
9+
import { join } from "path";
10+
import process from "process";
11+
import archiver from "archiver";
12+
13+
const args = process.argv.slice(2);
14+
const isProduction = args.includes("--production");
15+
const browserFlag = args.find((arg) => arg.startsWith("--browser="));
16+
const browser = browserFlag ? browserFlag.split("=")[1] : "chrome";
17+
18+
const outdir = `build/${browser}`;
19+
rmSync(outdir, { recursive: true, force: true });
20+
mkdirSync(outdir, { recursive: true });
21+
22+
const staticDirs = [
23+
"assets",
24+
"dashboard",
25+
"editor",
26+
"offscreen",
27+
"popup",
28+
"GM",
29+
"utils",
30+
];
31+
for (const dir of staticDirs) {
32+
cpSync(`src/${dir}`, join(outdir, dir), { recursive: true });
33+
}
34+
35+
const manifest = {
36+
manifest_version: 3,
37+
name: "CodeTweak",
38+
version: "1.0.0",
39+
description:
40+
"Inject custom JavaScript code into specific websites based on user-defined settings",
41+
permissions: [
42+
"storage",
43+
"tabs",
44+
"scripting",
45+
"webNavigation",
46+
"contextMenus",
47+
"notifications",
48+
"offscreen",
49+
"clipboardWrite",
50+
"downloads",
51+
],
52+
host_permissions: ["http://*/*", "https://*/*"],
53+
background: {
54+
service_worker: "background/background.js",
55+
type: "module",
56+
},
57+
action: {
58+
default_popup: "popup/popup.html",
59+
default_icon: {
60+
16: "assets/icons/icon16.png",
61+
48: "assets/icons/icon48.png",
62+
128: "assets/icons/icon128.png",
63+
},
64+
},
65+
icons: {
66+
16: "assets/icons/icon16.png",
67+
48: "assets/icons/icon48.png",
68+
128: "assets/icons/icon128.png",
69+
},
70+
content_scripts: [
71+
{
72+
matches: ["http://*/*", "https://*/*"],
73+
js: ["utils/elementSelector.js"],
74+
css: ["assets/styles/elementSelector.css"],
75+
run_at: "document_start",
76+
},
77+
{
78+
matches: ["http://*/*", "https://*/*"],
79+
js: ["utils/content_bridge.js"],
80+
run_at: "document_start",
81+
world: "ISOLATED",
82+
},
83+
{
84+
matches: ["https://greasyfork.org/*"],
85+
js: ["utils/greasyfork_interceptor.js"],
86+
run_at: "document_start",
87+
},
88+
],
89+
web_accessible_resources: [
90+
{
91+
resources: ["utils/*", "GM/*"],
92+
matches: ["<all_urls>"],
93+
},
94+
],
95+
};
96+
97+
writeFileSync(join(outdir, "manifest.json"), JSON.stringify(manifest, null, 2));
98+
await build({
99+
entryPoints: [
100+
"src/background/background.js",
101+
"src/utils/content_bridge.js",
102+
"src/utils/elementSelector.js",
103+
"src/GM/gm_core.js",
104+
"src/utils/greasyfork_interceptor.js",
105+
"src/utils/inject.js",
106+
"src/utils/urls.js",
107+
"src/popup/popup.js",
108+
"src/editor/editor.js",
109+
"src/dashboard/dashboard.js",
110+
],
111+
bundle: true,
112+
outdir,
113+
logLevel: "info",
114+
platform: "browser",
115+
define: {
116+
"process.env.BROWSER": JSON.stringify(browser),
117+
},
118+
});
119+
if (isProduction) {
120+
const archiveName = `codetweak-${browser}.zip`;
121+
const output = createWriteStream(join("build", archiveName));
122+
const archive = archiver("zip", { zlib: { level: 9 } });
123+
124+
output.on("close", () => {
125+
console.log(
126+
`Successfully created ${archiveName} (${archive.pointer()} bytes)`
127+
);
128+
});
129+
130+
archive.on("error", (err) => {
131+
throw err;
132+
});
133+
134+
archive.pipe(output);
135+
archive.directory(outdir, false);
136+
await archive.finalize();
137+
}

buildScripts/build-firefox.js

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// Build mv3 for Firefox
2+
3+
import { build } from "esbuild";
4+
import {
5+
rmSync,
6+
mkdirSync,
7+
cpSync,
8+
readFileSync,
9+
writeFileSync,
10+
createWriteStream,
11+
} from "fs";
12+
import { join } from "path";
13+
import process from "process";
14+
import archiver from "archiver";
15+
16+
const args = process.argv.slice(2);
17+
const isProduction = args.includes("--production");
18+
const browser = "firefox";
19+
const outdir = `build/${browser}`;
20+
21+
rmSync(outdir, { recursive: true, force: true });
22+
mkdirSync(outdir, { recursive: true });
23+
24+
const copyDirs = [
25+
"assets",
26+
"dashboard",
27+
"editor",
28+
"offscreen",
29+
"popup",
30+
"GM",
31+
"utils",
32+
];
33+
for (const dir of copyDirs) {
34+
cpSync(`src/${dir}`, join(outdir, dir), { recursive: true });
35+
}
36+
37+
const chromeManifest = JSON.parse(readFileSync("src/manifest.json", "utf8"));
38+
const firefoxManifest = { ...chromeManifest };
39+
40+
// Firefox MV3 uses background.scripts instead of background.service_worker
41+
if (firefoxManifest.background?.service_worker) {
42+
firefoxManifest.background = {
43+
scripts: [firefoxManifest.background.service_worker],
44+
type: "module",
45+
};
46+
}
47+
48+
// Remove Chrome-specific permissions
49+
firefoxManifest.permissions = (firefoxManifest.permissions || []).filter(
50+
(p) => p !== "offscreen"
51+
);
52+
53+
// Remove the 'world' property from content_scripts (not supported in Firefox)
54+
if (firefoxManifest.content_scripts) {
55+
firefoxManifest.content_scripts = firefoxManifest.content_scripts.map(
56+
(cs) => {
57+
const { world, ...rest } = cs;
58+
return rest;
59+
}
60+
);
61+
}
62+
63+
firefoxManifest.browser_specific_settings = {
64+
gecko: {
65+
id: "codetweak@MrBlankCoding",
66+
strict_min_version: "128.0",
67+
data_collection_permissions: {
68+
required: ["none"],
69+
},
70+
},
71+
};
72+
73+
writeFileSync(
74+
join(outdir, "manifest.json"),
75+
JSON.stringify(firefoxManifest, null, 2)
76+
);
77+
78+
await build({
79+
entryPoints: [
80+
"src/background/background.js",
81+
"src/utils/content_bridge.js",
82+
"src/utils/elementSelector.js",
83+
"src/GM/gm_core.js",
84+
"src/utils/greasyfork_interceptor.js",
85+
"src/utils/inject.js",
86+
"src/utils/urls.js",
87+
"src/popup/popup.js",
88+
"src/editor/editor.js",
89+
"src/dashboard/dashboard.js",
90+
],
91+
bundle: true,
92+
outdir,
93+
logLevel: "info",
94+
platform: "browser",
95+
define: {
96+
"process.env.BROWSER": JSON.stringify(browser),
97+
},
98+
});
99+
100+
// --- ZIP IN PRODUCTION --- //
101+
if (isProduction) {
102+
const archiveName = `codetweak-firefox.zip`;
103+
const output = createWriteStream(join("build", archiveName));
104+
const archive = archiver("zip", { zlib: { level: 9 } });
105+
106+
output.on("close", () => {
107+
console.log(
108+
`Successfully created ${archiveName} (${archive.pointer()} bytes)`
109+
);
110+
});
111+
112+
archive.on("error", (err) => {
113+
throw err;
114+
});
115+
116+
archive.pipe(output);
117+
archive.directory(outdir, false);
118+
await archive.finalize();
119+
}

0 commit comments

Comments
 (0)