diff --git a/src/lib/edge-functions/proxy.js b/src/lib/edge-functions/proxy.js index d3f95873581..ec0a6cd06dc 100644 --- a/src/lib/edge-functions/proxy.js +++ b/src/lib/edge-functions/proxy.js @@ -42,7 +42,16 @@ const handleProxyRequest = (req, proxyReq) => { }) } -const initializeProxy = async ({ config, configPath, geolocationMode, getUpdatedConfig, offline, settings, state }) => { +const initializeProxy = async ({ + config, + configPath, + geolocationMode, + getUpdatedConfig, + offline, + projectDir, + settings, + state, +}) => { const { functions: internalFunctions, importMap, path: internalFunctionsPath } = await getInternalFunctions() const { port: mainPort } = settings const userFunctionsPath = config.build.edge_functions @@ -60,6 +69,7 @@ const initializeProxy = async ({ config, configPath, geolocationMode, getUpdated importMaps: [importMap].filter(Boolean), internalFunctions, port: isolatePort, + projectDir, }) const hasEdgeFunctions = userFunctionsPath !== undefined || internalFunctions.length !== 0 @@ -125,6 +135,7 @@ const prepareServer = async ({ importMaps, internalFunctions, port, + projectDir, }) => { const bundler = await import('@netlify/edge-bundler') const distImportMapPath = getPathInProject([DIST_IMPORT_MAP_PATH]) @@ -148,6 +159,7 @@ const prepareServer = async ({ directories, getUpdatedConfig, internalFunctions, + projectDir, runIsolate, }) diff --git a/src/lib/edge-functions/registry.js b/src/lib/edge-functions/registry.js index 4b2e9e6ec35..f0dc4f79db0 100644 --- a/src/lib/edge-functions/registry.js +++ b/src/lib/edge-functions/registry.js @@ -1,4 +1,6 @@ // @ts-check +const { fileURLToPath } = require('url') + const { NETLIFYDEVERR, NETLIFYDEVLOG, chalk, log, warn, watchDebounced } = require('../../utils/command-helpers') /** @@ -24,9 +26,19 @@ class EdgeFunctionsRegistry { * @param {string[]} opts.directories * @param {() => Promise} opts.getUpdatedConfig * @param {EdgeFunction[]} opts.internalFunctions + * @param {string} opts.projectDir * @param {(functions: EdgeFunction[]) => Promise} opts.runIsolate */ - constructor({ bundler, config, configPath, directories, getUpdatedConfig, internalFunctions, runIsolate }) { + constructor({ + bundler, + config, + configPath, + directories, + getUpdatedConfig, + internalFunctions, + projectDir, + runIsolate, + }) { /** * @type {import('@netlify/edge-bundler')} */ @@ -87,7 +99,7 @@ class EdgeFunctionsRegistry { */ this.initialScan = this.scan(directories) - this.setupWatchers() + this.setupWatchers({ projectDir }) } /** @@ -283,7 +295,12 @@ class EdgeFunctionsRegistry { const dependencyPaths = new Map() graph.modules.forEach(({ dependencies = [], specifier }) => { - const functionMatch = functionPaths.get(specifier) + if (!specifier.startsWith('file://')) { + return + } + + const path = fileURLToPath(specifier) + const functionMatch = functionPaths.get(path) if (!functionMatch) { return @@ -301,9 +318,10 @@ class EdgeFunctionsRegistry { } const { specifier: dependencyURL } = dependency.code - const functions = dependencyPaths.get(dependencyURL) || [] + const dependencyPath = fileURLToPath(dependencyURL) + const functions = dependencyPaths.get(dependencyPath) || [] - dependencyPaths.set(dependencyURL, [...functions, functionMatch]) + dependencyPaths.set(dependencyPath, [...functions, functionMatch]) }) }) @@ -323,7 +341,7 @@ class EdgeFunctionsRegistry { return functions } - async setupWatchers() { + async setupWatchers({ projectDir }) { // Creating a watcher for the config file. When it changes, we update the // declarations and see if we need to register or unregister any functions. this.configWatcher = await watchDebounced(this.configPath, { @@ -336,8 +354,11 @@ class EdgeFunctionsRegistry { }, }) - // Creating a watcher for each source directory. - await Promise.all(this.directories.map((directory) => this.setupWatcherForDirectory(directory))) + // While functions are guaranteed to be inside one of the configured + // directories, they might be importing files that are located in + // parent directories. So we watch the entire project directory for + // changes. + await this.setupWatcherForDirectory(projectDir) } async setupWatcherForDirectory(directory) { diff --git a/src/utils/proxy.js b/src/utils/proxy.js index 3355335f3e1..c06cdde8ed9 100644 --- a/src/utils/proxy.js +++ b/src/utils/proxy.js @@ -479,6 +479,7 @@ const startProxy = async function ({ geolocationMode, getUpdatedConfig, offline, + projectDir, settings, state, })