Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for including nodejs at runtime #248

Open
fgrehm opened this issue Sep 23, 2022 · 1 comment
Open

Add support for including nodejs at runtime #248

fgrehm opened this issue Sep 23, 2022 · 1 comment

Comments

@fgrehm
Copy link

fgrehm commented Sep 23, 2022

Slack thread

Describe the Enhancement

We'd like to be able to use nodejs at runtime by flipping an env var from our project.tomls

Possible Solution

I've implemented a very simple buildpack that enables nodejs at runtime by setting BP_INCLUDE_NODEJS_RUNTIME=true

detect.go click to see
package nodejsruntime

import (
	"fmt"
	"os"
	"path/filepath"

	"github.com/paketo-buildpacks/packit/v2"
	"github.com/paketo-buildpacks/packit/v2/fs"
	"github.com/paketo-buildpacks/packit/v2/scribe"
)

var nodeRequirement = packit.BuildPlanRequirement{
	Name: "node",
	Metadata: map[string]interface{}{
		"launch": true,
	},
}

var nodeModulesRequirement = packit.BuildPlanRequirement{
	Name: "node_modules",
	Metadata: map[string]interface{}{
		"launch": true,
	},
}

func Detect(logger scribe.Emitter) packit.DetectFunc {
	return func(context packit.DetectContext) (packit.DetectResult, error) {
		logger.Debug.Title("%s %s", context.BuildpackInfo.ID, context.BuildpackInfo.Version)
		if os.Getenv("BP_INCLUDE_NODEJS_RUNTIME") != "true" {
			return packit.DetectResult{}, packit.Fail.WithMessage("BP_INCLUDE_NODEJS_RUNTIME is not set to true")
		}
		logger.Debug.Process("NodeJS is wanted for runtime")

		buildPlan := packit.BuildPlan{
			Requires: []packit.BuildPlanRequirement{nodeRequirement},
		}

		hasPackageJSON, err := fs.Exists(filepath.Join(context.WorkingDir, "package.json"))
		if err != nil {
			return packit.DetectResult{}, fmt.Errorf("failed to check for package.json: %w", err)
		} else if hasPackageJSON {
			logger.Debug.Process("node_modules is wanted for runtime")
			buildPlan.Requires = []packit.BuildPlanRequirement{nodeRequirement, nodeModulesRequirement}
			buildPlan.Or = []packit.BuildPlan{{
				Requires: []packit.BuildPlanRequirement{nodeRequirement},
			}}
		}

		return packit.DetectResult{
			Plan: buildPlan,
		}, nil
	}
}
build.go click to see
package nodejsruntime

import (
	"os"

	"github.com/paketo-buildpacks/packit/v2"
	"github.com/paketo-buildpacks/packit/v2/scribe"
)

func Build(logger scribe.Emitter) packit.BuildFunc {
	return func(context packit.BuildContext) (packit.BuildResult, error) {
		if os.Getenv("BP_INCLUDE_NODEJS_RUNTIME") == "true" {
			logger.Title("%s %s", context.BuildpackInfo.ID, context.BuildpackInfo.Version)
			logger.Process("NodeJS was configured for execution at runtime")
		}
		return packit.BuildResult{}, nil
	}
}

Motivation

We have a Rails application that uses nodejs for both asset compilation and also at runtime. The use case is to interact with browserless.io with nodejs scripts / pkgs.

I haven't tested but right now the only way to get nodejs at runtime is probably to mix the full nodejs buildpack with the ruby one in a group and also do something to trigger one of the nodejs *-start buildpacks.

@josegonzalez
Copy link
Contributor

I ended up adding https://github.com/paketo-community/build-plan as a buildpack group to my project.toml and the following plan.toml in my source to get nodejs at runtime:

[[requires]]
    name = "node"
    version = "~16"

    [requires.metadata]
        launch = true

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants