Skip to content

First-class install flags so install.command isn't the only lever #1979

Description

@heskew

Summary

There is no way to adjust a component install short of replacing the entire invocation. Common, routine adjustments — most obviously "don't install devDependencies" — require setting install.command, which discards --ignore-scripts, the devEngines.packageManager resolution, and applications_packageManagerPrefix along with it.

So the escape hatch is the only lever, and every small adjustment forces a large, control-bypassing one.

Evidence the flags are already wanted

The deprecated install_node_modules operation already passes --omit=dev (utility/npmUtilities.ts:45):

const args = ['install', '--force', '--omit=dev', '--json'];

…while the actual deploy path (components/Application.ts:424) does not:

const npmInstallArgs = application.install?.allowInstallScripts
    ? ['install', '--force']
    : ['install', '--force', '--ignore-scripts'];

The flag is desired; it's just applied in a deprecated code path and not the live one. A component deployed normally gets its devDependencies installed.

Proposal

Structured options for the common flags — omit, preferOffline, noAudit, noFund — plus an extraArgs: string[] pressure valve. The important property is that these compose with --ignore-scripts, the package-manager resolution, and the prefix, rather than replacing them the way install.command does.

Boundary rule, stated up front because this is the proposal most exposed to scope creep: expose only flags that are (a) meaningful across npm/yarn/pnpm, since all three are reachable via devEngines.packageManager, and (b) about what gets installed or how it is fetched. Anything else keeps using install.command. extraArgs covers the tail without turning this into an arbitrary passthrough surface.

The creep matters in both directions: if this doesn't cover real use cases, install.command stays mandatory and hardening it stays unpalatable.

Open question

Should --omit=dev be the default for component installs? Shipping devDependencies to a deployed component is rarely intended, and it's what the deprecated operation already does. But it's a behavior change — a component that currently resolves a devDependency at runtime would start failing. Probably wants a minor version and a release note rather than a patch.

Also worth deciding: whether these are operator-level (global config) or component-author-level (per-app install block), or both. The existing install block is component-author-settable and already carries allowInstallScripts, so there's a precedent for author control — but "what gets installed on my host" has an operator flavor too.

Related: #1974 — note that any lifecycle option added here won't take effect for payload-deployed components until they're redeployed, since those never re-enter the install path.


🤖 Filed by Claude on behalf of @heskew

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:componentsComponents / applications subsystemenhancementNew feature or request

    Fields

    Priority

    P2

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions