Files
diff-highlighter/scripts/build.mjs
Tilo Klarenbeek 314c34fe52 Initial commit: Diff Highlighter Chrome extension (MV3, TypeScript)
Highlights .diff/.patch files inline — additions green, deletions red,
hunk/file headers styled, with toggleable highlight.js syntax highlighting.

- MV3, content script gated on text/plain + URL ending in .diff/.patch
- Two-phase render: instant diff colors, then chunked idle-time syntax
- Popup switches + Alt+D shortcut, persisted in chrome.storage.sync, live re-render
- Light/dark via prefers-color-scheme; only the `storage` permission
- TypeScript + esbuild build; Forgejo Actions CI (typecheck + build)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 13:01:06 +02:00

58 lines
1.8 KiB
JavaScript

// Builds the extension into dist/: bundles the TypeScript entry points with
// esbuild and copies the static assets (manifest, popup HTML, CSS, icons).
// Run `node scripts/build.mjs` for a one-shot build, or with `--watch` for dev.
import * as esbuild from 'esbuild';
import { cp, mkdir, rm } from 'node:fs/promises';
import { existsSync } from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
const dist = path.join(root, 'dist');
const watch = process.argv.includes('--watch');
/** Copy a file or directory from a repo-relative path into dist/ (flattened). */
async function copy(from, to) {
const src = path.join(root, from);
if (!existsSync(src)) return;
await cp(src, path.join(dist, to), { recursive: true });
}
async function copyStatic() {
await copy('src/manifest.json', 'manifest.json');
await copy('src/popup/popup.html', 'popup.html');
await copy('src/styles/diff.css', 'diff.css');
await copy('src/styles/hljs-theme.css', 'hljs-theme.css');
await copy('src/styles/popup.css', 'popup.css');
await copy('icons', 'icons');
}
const options = {
entryPoints: {
content: path.join(root, 'src/content.ts'),
background: path.join(root, 'src/background.ts'),
popup: path.join(root, 'src/popup/popup.ts'),
},
outdir: dist,
entryNames: '[name]',
bundle: true,
format: 'iife',
target: ['chrome120'],
minify: !watch,
sourcemap: watch ? 'inline' : false,
logLevel: 'info',
};
await rm(dist, { recursive: true, force: true });
await mkdir(dist, { recursive: true });
await copyStatic();
if (watch) {
const ctx = await esbuild.context(options);
await ctx.watch();
console.log('watching for changes…');
} else {
await esbuild.build(options);
console.log('built ->', path.relative(root, dist));
}