Lean build: always ship core (manifest-less) frontends

This commit is contained in:
2026-07-19 12:10:45 -04:00
parent 384b8f7668
commit da28ee9f33
2 changed files with 20 additions and 4 deletions

View File

@@ -5,7 +5,9 @@
// plugins' frontend dirs into frontend/src/.plugins-staged/<name>/ and codegens
// frontend/src/router/routes.gen.js, which the router imports. A per-site build
// selects plugins via the SITE_PLUGINS env (comma-separated); with none set,
// every plugin that has a frontend/ is staged (the default full build).
// every plugin that has a frontend/ is staged (the default full build). A
// frontend dir with no manifest.json is a CORE feature and is ALWAYS staged
// regardless of SITE_PLUGINS.
//
// Both outputs are generated (gitignored). Run by npm predev/prebuild.
@@ -26,9 +28,18 @@ const withFrontend = readdirSync(pluginsDir, { withFileTypes: true })
&& existsSync(join(pluginsDir, entry.name, 'frontend', 'routes.js')))
.map(entry => entry.name)
const chosen = requested.length
? withFrontend.filter(name => requested.includes(name))
: withFrontend
// A frontend dir with no manifest.json is a CORE feature (e.g. applications),
// not a per-site plugin - it MUST always ship, or a lean build loses a core
// page (its nav is advertised by the core, so the route would 404 to a blank
// screen). SITE_PLUGINS selection applies only to real plugins (those with a
// manifest).
const isPlugin = name => existsSync(join(pluginsDir, name, 'manifest.json'))
const coreFrontend = withFrontend.filter(name => !isPlugin(name))
const pluginFrontend = withFrontend.filter(isPlugin)
const chosenPlugins = requested.length
? pluginFrontend.filter(name => requested.includes(name))
: pluginFrontend
const chosen = [...coreFrontend, ...chosenPlugins]
// Copy each chosen plugin's frontend dir into the staging area (clean first so
// a removed plugin does not linger).