124 lines
3.5 KiB
JavaScript
124 lines
3.5 KiB
JavaScript
import * as esbuild from 'esbuild';
|
|
import { cpSync, rmSync, existsSync, mkdirSync, watch } from 'node:fs';
|
|
import { createRequire } from 'node:module';
|
|
import { execSync } from 'child_process';
|
|
|
|
const require = createRequire(import.meta.url);
|
|
const pkg = require('./package.json');
|
|
const isProd = process.env.NODE_ENV === 'production';
|
|
|
|
let _commitHash = null;
|
|
const getCommitHash = () => {
|
|
if (_commitHash) return _commitHash;
|
|
try {
|
|
_commitHash = execSync('git rev-parse --short HEAD').toString().trim();
|
|
} catch {
|
|
_commitHash = 'unknown';
|
|
}
|
|
return _commitHash;
|
|
};
|
|
|
|
const jsBanner = `/*!
|
|
* ${pkg.name} v${pkg.version}+${getCommitHash()}
|
|
* ${pkg.description}
|
|
* (c) ${new Date().getFullYear()} ${pkg.author}
|
|
* ${pkg.repository.url?.replace(/\.git$/, '')}
|
|
* Released under the ${pkg.license} License.
|
|
*/`;
|
|
|
|
const userscriptBanner = `// ==UserScript==
|
|
// @name Gemini NanoBanana Watermark Remover
|
|
// @name:zh-CN Gemini NanoBanana 图片水印移除
|
|
// @namespace https://github.com/journey-ad
|
|
// @version 0.1.5
|
|
// @description Automatically removes watermarks from Gemini AI generated images
|
|
// @description:zh-CN 自动移除 Gemini AI 生成图像中的水印
|
|
// @icon https://www.google.com/s2/favicons?domain=gemini.google.com
|
|
// @author journey-ad
|
|
// @license MIT
|
|
// @match https://gemini.google.com/*
|
|
// @grant GM_xmlhttpRequest
|
|
// @run-at document-end
|
|
// ==/UserScript==
|
|
`;
|
|
|
|
const copyAssetsPlugin = {
|
|
name: 'copy-assets',
|
|
setup(build) {
|
|
build.onEnd(() => {
|
|
console.log('📂 Syncing static assets...');
|
|
try {
|
|
if (!existsSync('dist/i18n')) mkdirSync('dist/i18n', { recursive: true });
|
|
cpSync('src/i18n', 'dist/i18n', { recursive: true });
|
|
cpSync('public', 'dist', { recursive: true });
|
|
} catch (err) {
|
|
console.error('❌ Asset copy failed:', err);
|
|
}
|
|
});
|
|
},
|
|
};
|
|
|
|
const commonConfig = {
|
|
bundle: true,
|
|
loader: { '.png': 'dataurl' },
|
|
minify: isProd,
|
|
logLevel: 'info',
|
|
};
|
|
|
|
// Build website - app.js
|
|
const websiteCtx = await esbuild.context({
|
|
...commonConfig,
|
|
entryPoints: ['src/app.js'],
|
|
outfile: 'dist/app.js',
|
|
platform: 'browser',
|
|
target: ['es2020'],
|
|
banner: { js: jsBanner },
|
|
sourcemap: !isProd,
|
|
plugins: [copyAssetsPlugin],
|
|
});
|
|
|
|
// Build userscript
|
|
const userscriptCtx = await esbuild.context({
|
|
...commonConfig,
|
|
entryPoints: ['src/userscript/index.js'],
|
|
format: 'iife',
|
|
outfile: 'dist/userscript/gemini-watermark-remover.user.js',
|
|
banner: { js: userscriptBanner },
|
|
minify: false
|
|
});
|
|
|
|
console.log(`🚀 Starting build process... [${isProd ? 'PRODUCTION' : 'DEVELOPMENT'}]`);
|
|
|
|
if (existsSync('dist')) rmSync('dist', { recursive: true });
|
|
mkdirSync('dist/userscript', { recursive: true });
|
|
|
|
if (isProd) {
|
|
await Promise.all([websiteCtx.rebuild(), userscriptCtx.rebuild()]);
|
|
console.log('✅ Build complete!');
|
|
process.exit(0);
|
|
} else {
|
|
await Promise.all([websiteCtx.watch(), userscriptCtx.watch()]);
|
|
|
|
const watchDir = (dir, dest) => {
|
|
let debounceTimer = null;
|
|
|
|
watch(dir, { recursive: true }, (eventType, filename) => {
|
|
if (!filename) return;
|
|
if (debounceTimer) clearTimeout(debounceTimer);
|
|
|
|
debounceTimer = setTimeout(() => {
|
|
console.log(`📂 Asset changed: ${filename}`);
|
|
try {
|
|
cpSync(dir, dest, { recursive: true });
|
|
} catch (e) {
|
|
console.error('Sync failed:', e);
|
|
}
|
|
}, 100);
|
|
});
|
|
};
|
|
watchDir('src/i18n', 'dist/i18n');
|
|
watchDir('public', 'dist');
|
|
|
|
console.log('👀 Watching for changes...');
|
|
}
|