You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat!: support package.json.exports field for npm dependencies used within Netlify Edge Functions (#6167)
The current edge-bundler attempts to import a dependency via it's package-name, for example if the edge-function was importing `@secret/magic/sdk/meow`, then the edge-bundler would attempt to import `@secret/magic` during it's bundling process. This hits an issue if the dependency being imported is using the packge.json.exports field and has not allowed the bare package-name to be imported. We can see this issue with package's such as `@modelcontextprotocol/sdk` which has an exports field defined like so: ``` "exports": { "./*": { "import": "./dist/esm/*", "require": "./dist/cjs/*" } }, ``` This patch reimplements the edge-bundler's logic so that it uses the same import as that used within the edge-function itself, going back to our previous example of importing `@secret/magic/sdk/meow` in the edge-function, the edge-bundler will now also import `@secret/magic/sdk/meow` during it's bundling process. This solves the issue mentioned about a package not exporting it's bare package-name. The patch has changed how edge-bundler parses edge-functions for their imports, it no longer uses vercel/nft as that package finds the files being used, but the files may not be directly importable due to a package.json.exports field definition. This has been replaced with `parse-imports`, which does a lexical scan of the files to find the import tokens. This approach is useful in that we can now detect all the different types of imports, such as if they are static or dynamic imports. For dynamic imports we can also detect if the import-specifier is a constant or not - this is useful because if it is a constant then we are able to bundle it, if it is not a constant, we could decide to report that the import may not work. The previous approach using vercel/nft did have the ability to find paths which are used but not imported, such as paths used within `fs.readFile` etc, vercel/nft would mark those as "assets". edge-bundler would keep track of the dependencies which had "assets" and mark them as containing 'extraneous files'. The CLI, if invoked with the `dev` command would then print out a note like this: >The following npm modules, which are directly or indirectly imported by an edge function, >may not be supported: dictionary. For more information, visit https://ntl.fyi/edge-functions-npm. This note was only shown for the `dev` command and not for `build` or `deploy`, a build and a deployment were still possible to take place. This patch has not implemented this note for the `dev` command, I don't think this is an issue.
Command failed with exit code 1: deno run --allow-all --no-config --import-map=packages/edge-bundler/deno/vendor/import_map.json --quiet packages/edge-bundler/deno/bundle.ts {"basePath":"packages/build/tests/monitor/fixtures/edge_function_error","destPath":"packages/build/tests/monitor/fixtures/edge_function_error/.netlify/edge-functions-dist/HEXADECIMAL_ID.eszip","externals":[],"functions":[{"name":"trouble","path":"packages/build/tests/monitor/fixtures/edge_function_error/netlify/edge-functions/trouble.ts"}],"importMapData":"{/"imports/":{/"builtins/":/"node:builtins/",/"@netlify/edge-functions/":/"https://edge.netlify.com/v1.0.0/index.ts/",/"netlify:edge/":/"https://edge.netlify.com/v1.0.0/index.ts?v=legacy/"},/"scopes/":{}}","vendorDirectory":"/external/path"}␊
1591
+
Command failed with exit code 1: deno run --allow-all --no-config --import-map=packages/edge-bundler/deno/vendor/import_map.json --quiet packages/edge-bundler/deno/bundle.ts {"basePath":"packages/build/tests/monitor/fixtures/edge_function_error","destPath":"packages/build/tests/monitor/fixtures/edge_function_error/.netlify/edge-functions-dist/HEXADECIMAL_ID.eszip","externals":[],"functions":[{"name":"trouble","path":"packages/build/tests/monitor/fixtures/edge_function_error/netlify/edge-functions/trouble.ts"}],"importMapData":"{/"imports/":{/"@netlify/edge-functions/":/"https://edge.netlify.com/v1.0.0/index.ts/",/"netlify:edge/":/"https://edge.netlify.com/v1.0.0/index.ts?v=legacy/"},/"scopes/":{}}"}␊
1592
1592
error: Uncaught (in promise) Error: Error: Could not find file: packages/build/tests/monitor/fixtures/edge_function_error/netlify/edge-functions/file.ts␊
1593
1593
const ret = new Error(getStringFromWasm0(arg0, arg1));␊
1594
1594
^␊
@@ -1606,9 +1606,9 @@ Generated by [AVA](https://avajs.dev).
1606
1606
Error monitoring payload:␊
1607
1607
{␊
1608
1608
"errorClass": "functionsBundling",␊
1609
-
"errorMessage": "Command failed with exit code 1: deno run --allow-all --no-config --import-map=packages/edge-bundler/deno/vendor/import_map.json --quiet packages/edge-bundler/deno/bundle.ts {/"basePath/":/"packages/build/tests/monitor/fixtures/edge_function_error",/"destPath/":/"packages/build/tests/monitor/fixtures/edge_function_error/.netlify/edge-functions-dist/HEXADECIMAL_ID.eszip",/"externals/":[],/"functions/":[{/"name/":/"trouble/",/"path/":/"packages/build/tests/monitor/fixtures/edge_function_error/netlify/edge-functions/trouble.ts"}],/"importMapData/":/"{//"imports//":{//"builtins//"://"node:builtins//",//"@netlify/edge-functions//"://"https://edge.netlify.com/v1.0.0/index.ts//",//"netlify:edge//"://"https://edge.netlify.com/v1.0.0/index.ts?v=legacy//"},//"scopes//":{}}/",/"vendorDirectory/":/"/external/path"}/nerror: Uncaught (in promise) Error: Error: Could not find file: packages/build/tests/monitor/fixtures/edge_function_error/netlify/edge-functions/file.ts/n const ret = new Error(getStringFromWasm0(arg0, arg1));/n ^/n at __wbg_new_HEXADECIMAL_ID (packages/edge-bundler/deno/vendor/deno.land/x/eszip@v1.0.0/eszip_wasm.generated.js:80:80)/n at <anonymous> (wasm://wasm/HEXADECIMAL_ID:1:80)/n at <anonymous> (wasm://wasm/HEXADECIMAL_ID:1:80)/n at <anonymous> (wasm://wasm/HEXADECIMAL_ID:1:80)/n at __wbg_adapter_40 (packages/edge-bundler/deno/vendor/deno.land/x/eszip@v1.0.0/eszip_wasm.generated.js:80:8)/n at real (packages/edge-bundler/deno/vendor/deno.land/x/eszip@v1.0.0/eszip_wasm.generated.js:80:80)/n at eventLoopTick (ext:core/01_core.js:80:7)",␊
1609
+
"errorMessage": "Command failed with exit code 1: deno run --allow-all --no-config --import-map=packages/edge-bundler/deno/vendor/import_map.json --quiet packages/edge-bundler/deno/bundle.ts {/"basePath/":/"packages/build/tests/monitor/fixtures/edge_function_error",/"destPath/":/"packages/build/tests/monitor/fixtures/edge_function_error/.netlify/edge-functions-dist/HEXADECIMAL_ID.eszip",/"externals/":[],/"functions/":[{/"name/":/"trouble/",/"path/":/"packages/build/tests/monitor/fixtures/edge_function_error/netlify/edge-functions/trouble.ts"}],/"importMapData/":/"{//"imports//":{//"@netlify/edge-functions//"://"https://edge.netlify.com/v1.0.0/index.ts//",//"netlify:edge//"://"https://edge.netlify.com/v1.0.0/index.ts?v=legacy//"},//"scopes//":{}}/"}/nerror: Uncaught (in promise) Error: Error: Could not find file: packages/build/tests/monitor/fixtures/edge_function_error/netlify/edge-functions/file.ts/n const ret = new Error(getStringFromWasm0(arg0, arg1));/n ^/n at __wbg_new_HEXADECIMAL_ID (packages/edge-bundler/deno/vendor/deno.land/x/eszip@v1.0.0/eszip_wasm.generated.js:80:80)/n at <anonymous> (wasm://wasm/HEXADECIMAL_ID:1:80)/n at <anonymous> (wasm://wasm/HEXADECIMAL_ID:1:80)/n at <anonymous> (wasm://wasm/HEXADECIMAL_ID:1:80)/n at __wbg_adapter_40 (packages/edge-bundler/deno/vendor/deno.land/x/eszip@v1.0.0/eszip_wasm.generated.js:80:8)/n at real (packages/edge-bundler/deno/vendor/deno.land/x/eszip@v1.0.0/eszip_wasm.generated.js:80:80)/n at eventLoopTick (ext:core/01_core.js:80:7)",␊
1610
1610
"context": "Bundling of edge function failed",␊
1611
-
"groupingHash": "Bundling of edge function failed/nCommand failed with exit code 0: deno run --allow-all --no-config /external/path --quiet /external/path {/"/":/"/",/"/":/"/",/"/":[],/"/":[{/"/":/"/",/"/":/"/"}],/"/":/"/"/external/path"/"/external/path"/"/external/path"/"/external/path"/"/external/path"/"/external/path"/"/external/path"/"/external/path"/",/"/":/"/"}/nerror: Uncaught (in promise) Error: Error: Could not find file: /external/path const ret = new Error(getStringFromWasm0(arg0, arg0));/n ^/n at __wbg_new_hex /external/path at <anonymous> /external/path at <anonymous> /external/path at <anonymous> /external/path at __wbg_adapter_0 /external/path at real /external/path at eventLoopTick /external/path",␊
1611
+
"groupingHash": "Bundling of edge function failed/nCommand failed with exit code 0: deno run --allow-all --no-config /external/path --quiet /external/path {/"/":/"/",/"/":/"/",/"/":[],/"/":[{/"/":/"/",/"/":/"/"}],/"/":/"/"/external/path"/"/external/path"/"/external/path"/"/external/path"/"/external/path"/"/external/path"/"}/nerror: Uncaught (in promise) Error: Error: Could not find file: /external/path const ret = new Error(getStringFromWasm0(arg0, arg0));/n ^/n at __wbg_new_hex /external/path at <anonymous> /external/path at <anonymous> /external/path at <anonymous> /external/path at __wbg_adapter_0 /external/path at real /external/path at eventLoopTick /external/path",␊
1612
1612
"severity": "info",␊
1613
1613
"unhandled": false,␊
1614
1614
"location": {␊
@@ -1619,7 +1619,7 @@ Generated by [AVA](https://avajs.dev).
1619
1619
"pluginPackageJson": false,␊
1620
1620
"BUILD_ID": "0",␊
1621
1621
"other": {␊
1622
-
"groupingHash": "Bundling of edge function failed/nCommand failed with exit code 0: deno run --allow-all --no-config /external/path --quiet /external/path {/"/":/"/",/"/":/"/",/"/":[],/"/":[{/"/":/"/",/"/":/"/"}],/"/":/"/"/external/path"/"/external/path"/"/external/path"/"/external/path"/"/external/path"/"/external/path"/"/external/path"/"/external/path"/",/"/":/"/"}/nerror: Uncaught (in promise) Error: Error: Could not find file: /external/path const ret = new Error(getStringFromWasm0(arg0, arg0));/n ^/n at __wbg_new_hex /external/path at <anonymous> /external/path at <anonymous> /external/path at <anonymous> /external/path at __wbg_adapter_0 /external/path at real /external/path at eventLoopTick /external/path"␊
1622
+
"groupingHash": "Bundling of edge function failed/nCommand failed with exit code 0: deno run --allow-all --no-config /external/path --quiet /external/path {/"/":/"/",/"/":/"/",/"/":[],/"/":[{/"/":/"/",/"/":/"/"}],/"/":/"/"/external/path"/"/external/path"/"/external/path"/"/external/path"/"/external/path"/"/external/path"/"}/nerror: Uncaught (in promise) Error: Error: Could not find file: /external/path const ret = new Error(getStringFromWasm0(arg0, arg0));/n ^/n at __wbg_new_hex /external/path at <anonymous> /external/path at <anonymous> /external/path at <anonymous> /external/path at __wbg_adapter_0 /external/path at real /external/path at eventLoopTick /external/path"␊
0 commit comments