perf(scripts): share npm dependencies across plugin bundles

Bundled standalone, every plugin carried its own cheerio/htmlparser2/etc.:
loading 165 plugins took ~13 s and 1.2 GB (2.2 GB while building). With npm
packages external they share node_modules: 0.5 s / 104 MB (build 1.5 s).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
masi
2026-09-26 14:25:48 -03:00
parent 6916ed5c61
commit 0fd7b27d08
2 changed files with 8 additions and 6 deletions
+1
View File
@@ -19,3 +19,4 @@ broken-sites-report.json
.agents/
.claude/
.cursor/
.plugin-cache/
+7 -6
View File
@@ -1,7 +1,9 @@
// Load compiled plugin instances outside the app, for the novel CLI scripts.
// Bundling ~165 plugins takes ~15 s and each bundle carries its own libraries, so the
// bundle is built once per source revision and cached, with an id -> file index:
// fetching a novel then loads a single plugin instead of all of them.
// npm packages stay external, so all plugins share one copy of cheerio & co. from
// node_modules (bundled standalone, each plugin carried its own: ~1.2 GB for 165).
// The bundle is built once per source revision and cached with an id -> file index,
// so fetching a novel loads a single plugin. The cache lives inside the repo so the
// bundles resolve node_modules from it.
import * as esbuild from 'esbuild';
import { execFileSync } from 'child_process';
import { createHash } from 'crypto';
@@ -9,13 +11,11 @@ import { createRequire } from 'module';
import { fileURLToPath } from 'url';
import path, { dirname } from 'path';
import fs from 'fs';
import os from 'os';
const require = createRequire(import.meta.url);
export const ROOT = path.resolve(dirname(fileURLToPath(import.meta.url)), '..');
const CACHE =
process.env.NOVEL_PLUGIN_CACHE ||
path.join(os.homedir(), '.cache', 'novel-plugins');
process.env.NOVEL_PLUGIN_CACHE || path.join(ROOT, '.plugin-cache');
export const LANGS = ['english', 'multi'];
// The shared fetch helper logs every request with its headers (credentials
@@ -72,6 +72,7 @@ async function bundle(langs) {
format: 'cjs',
target: 'node22',
outExtension: { '.js': '.cjs' },
packages: 'external',
logLevel: 'silent',
alias: {
'@libs': path.join(ROOT, 'src/libs'),