diff --git a/internal/functions/deploy/bundle.go b/internal/functions/deploy/bundle.go index 13b9a6360..99412d493 100644 --- a/internal/functions/deploy/bundle.go +++ b/internal/functions/deploy/bundle.go @@ -25,7 +25,7 @@ func NewDockerBundler(fsys afero.Fs) function.EszipBundler { return &dockerBundler{fsys: fsys} } -func (b *dockerBundler) Bundle(ctx context.Context, slug, entrypoint, importMap string, staticFiles []string, output io.Writer) (function.FunctionDeployMetadata, error) { +func (b *dockerBundler) Bundle(ctx context.Context, slug, entrypoint, importMap string, staticFiles []string, usePackageJson bool, output io.Writer) (function.FunctionDeployMetadata, error) { meta := function.NewMetadata(slug, entrypoint, importMap, staticFiles) fmt.Fprintln(os.Stderr, "Bundling Function:", utils.Bold(slug)) cwd, err := os.Getwd() @@ -62,9 +62,18 @@ func (b *dockerBundler) Bundle(ctx context.Context, slug, entrypoint, importMap cmd = append(cmd, function.BundleFlags...) env := []string{} + denoNoPackageJsonValue := "1" + if usePackageJson { + denoNoPackageJsonValue = "0" + } if custom_registry := os.Getenv("NPM_CONFIG_REGISTRY"); custom_registry != "" { env = append(env, "NPM_CONFIG_REGISTRY="+custom_registry) } + if deno_no_package_json := os.Getenv("DENO_NO_PACKAGE_JSON"); deno_no_package_json != "" { + env = append(env, "DENO_NO_PACKAGE_JSON="+deno_no_package_json) + } else { + env = append(env, "DENO_NO_PACKAGE_JSON="+denoNoPackageJsonValue) + } // Run bundle if err := utils.DockerRunOnceWithConfig( ctx, diff --git a/internal/functions/deploy/bundle_test.go b/internal/functions/deploy/bundle_test.go index 5933e77dc..de2343f2b 100644 --- a/internal/functions/deploy/bundle_test.go +++ b/internal/functions/deploy/bundle_test.go @@ -59,6 +59,7 @@ func TestDockerBundle(t *testing.T) { filepath.Join("hello", "index.ts"), filepath.Join("hello", "deno.json"), []string{filepath.Join("hello", "data.pdf")}, + false, &body, ) // Check error @@ -86,6 +87,7 @@ func TestDockerBundle(t *testing.T) { "hello/index.ts", "", nil, + false, nil, ) // Check error diff --git a/internal/functions/deploy/deploy.go b/internal/functions/deploy/deploy.go index bcee53c55..051ea0b5a 100644 --- a/internal/functions/deploy/deploy.go +++ b/internal/functions/deploy/deploy.go @@ -136,6 +136,12 @@ func GetFunctionConfig(slugs []string, importMapPath string, noVerifyJWT *bool, functionsUsingDeprecatedGlobalFallback = append(functionsUsingDeprecatedGlobalFallback, name) } } + packageJsonPath := filepath.Join(functionDir, "package.json") + packageJsonExists := false + if _, err := fsys.Stat(packageJsonPath); err == nil { + packageJsonExists = true + } + function.UsePackageJson = len(function.ImportMap) == 0 && packageJsonExists if noVerifyJWT != nil { function.VerifyJWT = !*noVerifyJWT } diff --git a/internal/functions/serve/templates/main.ts b/internal/functions/serve/templates/main.ts index 568c547f8..67a80567a 100644 --- a/internal/functions/serve/templates/main.ts +++ b/internal/functions/serve/templates/main.ts @@ -116,6 +116,17 @@ async function verifyJWT(jwt: string): Promise { return true; } +async function shouldUsePackageJsonDiscovery(absDir: string): Promise { + const [a, b, c, d] = (await Promise.allSettled([ + Deno.stat(posix.join(absDir, "deno.json")), + Deno.stat(posix.join(absDir, "deno.jsonc")), + Deno.stat(posix.join(absDir, "import_map.json")), + Deno.stat(posix.join(absDir, "package.json")), + ])).map(v => v.status === "fulfilled"); + + return !a && !b && !c && d; +} + Deno.serve({ handler: async (req: Request) => { const url = new URL(req.url); @@ -178,6 +189,7 @@ Deno.serve({ const absEntrypoint = posix.join(Deno.cwd(), functionsConfig[functionName].entrypointPath); const maybeEntrypoint = posix.toFileUrl(absEntrypoint).href; + const usePackageJsonDiscovery = await shouldUsePackageJsonDiscovery(posix.dirname(absEntrypoint)); const staticPatterns = functionsConfig[functionName].staticFiles; @@ -187,6 +199,7 @@ Deno.serve({ memoryLimitMb, workerTimeoutMs, noModuleCache, + noNpm: !usePackageJsonDiscovery, importMapPath: functionsConfig[functionName].importMapPath, envVars, forceCreate, diff --git a/pkg/config/config.go b/pkg/config/config.go index 531bc3dea..9fce2772c 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -200,11 +200,12 @@ type ( FunctionConfig map[string]function function struct { - Enabled bool `toml:"enabled" json:"-"` - VerifyJWT bool `toml:"verify_jwt" json:"verifyJWT"` - ImportMap string `toml:"import_map" json:"importMapPath,omitempty"` - Entrypoint string `toml:"entrypoint" json:"entrypointPath,omitempty"` - StaticFiles Glob `toml:"static_files" json:"staticFiles,omitempty"` + Enabled bool `toml:"enabled" json:"-"` + UsePackageJson bool `toml:"-" json:"-"` + VerifyJWT bool `toml:"verify_jwt" json:"verifyJWT"` + ImportMap string `toml:"import_map" json:"importMapPath,omitempty"` + Entrypoint string `toml:"entrypoint" json:"entrypointPath,omitempty"` + StaticFiles Glob `toml:"static_files" json:"staticFiles,omitempty"` } analytics struct { diff --git a/pkg/function/api.go b/pkg/function/api.go index df4443240..8663a419c 100644 --- a/pkg/function/api.go +++ b/pkg/function/api.go @@ -24,7 +24,7 @@ type FunctionDeployMetadata struct { } type EszipBundler interface { - Bundle(ctx context.Context, slug, entrypoint, importMap string, staticFiles []string, output io.Writer) (FunctionDeployMetadata, error) + Bundle(ctx context.Context, slug, entrypoint, importMap string, staticFiles []string, usePackageJson bool, output io.Writer) (FunctionDeployMetadata, error) } func NewEdgeRuntimeAPI(project string, client api.ClientWithResponses, opts ...withOption) EdgeRuntimeAPI { diff --git a/pkg/function/batch.go b/pkg/function/batch.go index fad409853..e4ab8cdda 100644 --- a/pkg/function/batch.go +++ b/pkg/function/batch.go @@ -60,7 +60,7 @@ OUTER: } } var body bytes.Buffer - meta, err := s.eszip.Bundle(ctx, slug, function.Entrypoint, function.ImportMap, function.StaticFiles, &body) + meta, err := s.eszip.Bundle(ctx, slug, function.Entrypoint, function.ImportMap, function.StaticFiles, function.UsePackageJson, &body) if errors.Is(err, ErrNoDeploy) { fmt.Fprintln(os.Stderr, "Skipping undeployable Function:", slug) continue diff --git a/pkg/function/batch_test.go b/pkg/function/batch_test.go index d47b28be4..8015bea82 100644 --- a/pkg/function/batch_test.go +++ b/pkg/function/batch_test.go @@ -18,7 +18,7 @@ import ( type MockBundler struct { } -func (b *MockBundler) Bundle(ctx context.Context, slug, entrypoint, importMap string, staticFiles []string, output io.Writer) (FunctionDeployMetadata, error) { +func (b *MockBundler) Bundle(ctx context.Context, slug, entrypoint, importMap string, staticFiles []string, usePackageJson bool, output io.Writer) (FunctionDeployMetadata, error) { if staticFiles == nil { staticFiles = []string{} } diff --git a/pkg/function/bundle.go b/pkg/function/bundle.go index fb13ae64c..817478a03 100644 --- a/pkg/function/bundle.go +++ b/pkg/function/bundle.go @@ -48,7 +48,7 @@ var ( } ) -func (b *nativeBundler) Bundle(ctx context.Context, slug, entrypoint, importMap string, staticFiles []string, output io.Writer) (FunctionDeployMetadata, error) { +func (b *nativeBundler) Bundle(ctx context.Context, slug, entrypoint, importMap string, staticFiles []string, usePackageJson bool, output io.Writer) (FunctionDeployMetadata, error) { meta := NewMetadata(slug, entrypoint, importMap, staticFiles) outputPath := filepath.Join(b.tempDir, slug+".eszip") // TODO: make edge runtime write to stdout @@ -65,9 +65,17 @@ func (b *nativeBundler) Bundle(ctx context.Context, slug, entrypoint, importMap defer cancel() // release resources if command exits before timeout ctx = timeoutCtx } + denoNoPackageJsonValue := "1" + if usePackageJson { + denoNoPackageJsonValue = "0" + } + cmd := exec.CommandContext(ctx, edgeRuntimeBin, args...) cmd.Stderr = os.Stderr cmd.Stdout = os.Stdout + if deno_no_package_json := os.Getenv("DENO_NO_PACKAGE_JSON"); deno_no_package_json != "" { + cmd.Env = append(os.Environ(), "DENO_NO_PACKAGE_JSON="+denoNoPackageJsonValue) + } if err := cmd.Run(); err != nil { return meta, errors.Errorf("failed to bundle function: %w", err) } diff --git a/pkg/function/bundle_test.go b/pkg/function/bundle_test.go index 1f16b87f4..d84e4c76d 100644 --- a/pkg/function/bundle_test.go +++ b/pkg/function/bundle_test.go @@ -48,6 +48,7 @@ func TestBundleFunction(t *testing.T) { "hello/index.ts", "hello/deno.json", []string{"hello/data.pdf"}, + true, &body, ) // Check error @@ -78,6 +79,7 @@ func TestBundleFunction(t *testing.T) { "hello/index.ts", "", nil, + true, &body, ) // Check error