diff --git a/node/formats/javascript.ts b/node/formats/javascript.ts index 8b0ce265..0e7ae209 100644 --- a/node/formats/javascript.ts +++ b/node/formats/javascript.ts @@ -1,4 +1,4 @@ -import { mkdir, rm, writeFile } from 'fs/promises' +import { mkdir, writeFile } from 'fs/promises' import { join } from 'path' import { pathToFileURL } from 'url' @@ -27,7 +27,6 @@ const generateStage2 = async ({ formatImportError, functions, }: GenerateStage2Options) => { - await rm(distDirectory, { force: true, recursive: true, maxRetries: 3 }) await mkdir(distDirectory, { recursive: true }) const entryPoint = getLocalEntryPoint(functions, { bootstrapURL, formatExportTypeError, formatImportError }) diff --git a/node/npm_dependencies.ts b/node/npm_dependencies.ts index ec204e8d..419b3389 100644 --- a/node/npm_dependencies.ts +++ b/node/npm_dependencies.ts @@ -326,5 +326,6 @@ export const vendorNPMSpecifiers = async ({ directory: temporaryDirectory.path, importMap: newImportMap, npmSpecifiersWithExtraneousFiles, + outputFiles: outputFiles.map((file) => file.path), } } diff --git a/node/server/server.ts b/node/server/server.ts index ff060679..b036037f 100644 --- a/node/server/server.ts +++ b/node/server/server.ts @@ -1,3 +1,6 @@ +import { readdir, unlink } from 'fs/promises' +import { join } from 'path' + import { DenoBridge, OnAfterDownloadHook, OnBeforeDownloadHook, ProcessRef } from '../bridge.js' import { getFunctionConfig, FunctionConfig } from '../config.js' import type { EdgeFunction } from '../edge_function.js' @@ -32,6 +35,17 @@ interface StartServerOptions { getFunctionsConfig?: boolean } +/** + * Cleans up a directory, except for the files specified in the `except` array. + * Both should be given as absolute paths. + * Assumes the directory doesn't contain any nested directories. + */ +const cleanDirectory = async (directory: string, except: string[]) => { + const files = await readdir(directory) + const toBeDeleted = files.filter((file) => !except.includes(join(directory, file))) + await Promise.all(toBeDeleted.map((file) => unlink(join(directory, file)))) +} + const prepareServer = ({ basePath, bootstrapURL, @@ -70,6 +84,9 @@ const prepareServer = ({ const importMap = baseImportMap.clone() const npmSpecifiersWithExtraneousFiles: string[] = [] + // we keep track of the files that are relevant to the user's code, so we can clean up leftovers from past executions later + const relevantFiles = [stage2Path] + const vendor = await vendorNPMSpecifiers({ basePath, directory: distDirectory, @@ -83,8 +100,11 @@ const prepareServer = ({ features.npmModules = true importMap.add(vendor.importMap) npmSpecifiersWithExtraneousFiles.push(...vendor.npmSpecifiersWithExtraneousFiles) + relevantFiles.push(...vendor.outputFiles) } + await cleanDirectory(distDirectory, relevantFiles) + try { // This command will print a JSON object with all the modules found in // the `stage2Path` file as well as all of their dependencies.