in cmd/nodejs/yarn/main.go [228:283]
func yarn2InstallModules(ctx *gcp.Context, pjs *nodejs.PackageJSON) error {
if err := ar.GenerateYarnConfig(ctx); err != nil {
return fmt.Errorf("generating Artifact Registry credentials: %w", err)
}
cmd := []string{"yarn", "install", "--immutable"}
yarnCacheExists, err := ctx.FileExists(ctx.ApplicationRoot(), ".yarn", "cache")
if err != nil {
return err
}
// In Plug'n'Play mode (https://yarnpkg.com/features/pnp) all dependencies must be included in
// the Yarn cache. The --immutable-cache option will abort the install with an error if anything
// is missing or out of date.
if yarnCacheExists {
cmd = append(cmd, "--immutable-cache")
}
if _, err := ctx.Exec(cmd, gcp.WithUserAttribution); err != nil {
return err
}
if gcpBuild := nodejs.HasGCPBuild(pjs); gcpBuild {
if _, err := ctx.Exec([]string{"yarn", "run", "gcp-build"}, gcp.WithUserAttribution); err != nil {
return err
}
}
if appHostingBuildScript, ok := os.LookupEnv(nodejs.AppHostingBuildEnv); ok {
if _, err := ctx.Exec(strings.Split(appHostingBuildScript, " "), gcp.WithUserAttribution); err != nil {
return err
}
}
// If there are no devDependencies, there is nothing to prune. We are done.
if !nodejs.HasDevDependencies(pjs) {
return nil
}
nodeEnv := nodejs.NodeEnv()
if nodeEnv != nodejs.EnvProduction {
ctx.Logf("Retaining devDependencies because NODE_ENV=%q", nodeEnv)
return nil
}
hasWorkPlugin, err := nodejs.HasYarnWorkspacePlugin(ctx)
if err != nil {
return err
}
if !hasWorkPlugin {
ctx.Warnf("Keeping devDependencies because the Yarn workspace-tools plugin is not installed. You can add it to your project by running 'yarn plugin import workspace-tools'")
return nil
}
// For Yarn2, dependency pruning is via the workspaces plugin.
ctx.Logf("Pruning devDependencies")
if _, err := ctx.Exec([]string{"yarn", "workspaces", "focus", "--all", "--production"}, gcp.WithUserAttribution); err != nil {
return err
}
return nil
}