From d073b0959637cc780b32444b880f54712ea130ed Mon Sep 17 00:00:00 2001 From: James Daniels Date: Thu, 15 Dec 2022 17:45:40 -0500 Subject: [PATCH] When deploying Next.js utilize esbuild via NPX (#5336) * Drop esbuild as a dependency of firebase-tools * Spawn npx esbuild to bundle next.config.js when deploying a Next.js application * Widen the net on externals, we were missing deps of deps --- CHANGELOG.md | 1 + npm-shrinkwrap.json | 608 +++++++++++++++++++--- package.json | 3 - src/frameworks/next/index.ts | 48 +- src/frameworks/next/interfaces.ts | 16 + src/frameworks/next/utils.ts | 23 +- src/test/frameworks/next/helpers/index.ts | 1 + src/test/frameworks/next/helpers/npm.ts | 129 +++++ src/test/frameworks/next/utils.spec.ts | 47 ++ 9 files changed, 789 insertions(+), 87 deletions(-) create mode 100644 src/test/frameworks/next/helpers/npm.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index d96f38d154f..fc9926853ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,4 @@ +- Remove esbuild dependency, instead bundle Next.js configuration on deploy with NPX (#5336) - Add sharp NPM module to Cloud Functions when using Next.js Image Optimization (#5238) - Adds user-defined env vars into the functions emulator (#5330). - Support Next.js Middleware (#5320) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index c4cb36e76d3..346a4c13aa6 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -160,9 +160,6 @@ }, "engines": { "node": "^14.18.0 || >=16.4.0" - }, - "optionalDependencies": { - "esbuild": "^0.15.7" } }, "node_modules/@ampproject/remapping": { @@ -698,6 +695,38 @@ "node": "^14 || ^16 || ^17 || ^18" } }, + "node_modules/@esbuild/android-arm": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.18.tgz", + "integrity": "sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz", + "integrity": "sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint/eslintrc": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", @@ -5793,10 +5822,10 @@ "dev": true }, "node_modules/esbuild": { - "version": "0.15.8", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.8.tgz", - "integrity": "sha512-Remsk2dmr1Ia65sU+QasE6svJbsHe62lzR+CnjpUvbZ+uSYo1SitiOWPRfZQkCu82YWZBBKXiD/j0i//XWMZ+Q==", - "devOptional": true, + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.18.tgz", + "integrity": "sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==", + "dev": true, "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" @@ -5805,37 +5834,70 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/android-arm": "0.15.8", - "@esbuild/linux-loong64": "0.15.8", - "esbuild-android-64": "0.15.8", - "esbuild-android-arm64": "0.15.8", - "esbuild-darwin-64": "0.15.8", - "esbuild-darwin-arm64": "0.15.8", - "esbuild-freebsd-64": "0.15.8", - "esbuild-freebsd-arm64": "0.15.8", - "esbuild-linux-32": "0.15.8", - "esbuild-linux-64": "0.15.8", - "esbuild-linux-arm": "0.15.8", - "esbuild-linux-arm64": "0.15.8", - "esbuild-linux-mips64le": "0.15.8", - "esbuild-linux-ppc64le": "0.15.8", - "esbuild-linux-riscv64": "0.15.8", - "esbuild-linux-s390x": "0.15.8", - "esbuild-netbsd-64": "0.15.8", - "esbuild-openbsd-64": "0.15.8", - "esbuild-sunos-64": "0.15.8", - "esbuild-windows-32": "0.15.8", - "esbuild-windows-64": "0.15.8", - "esbuild-windows-arm64": "0.15.8" + "@esbuild/android-arm": "0.15.18", + "@esbuild/linux-loong64": "0.15.18", + "esbuild-android-64": "0.15.18", + "esbuild-android-arm64": "0.15.18", + "esbuild-darwin-64": "0.15.18", + "esbuild-darwin-arm64": "0.15.18", + "esbuild-freebsd-64": "0.15.18", + "esbuild-freebsd-arm64": "0.15.18", + "esbuild-linux-32": "0.15.18", + "esbuild-linux-64": "0.15.18", + "esbuild-linux-arm": "0.15.18", + "esbuild-linux-arm64": "0.15.18", + "esbuild-linux-mips64le": "0.15.18", + "esbuild-linux-ppc64le": "0.15.18", + "esbuild-linux-riscv64": "0.15.18", + "esbuild-linux-s390x": "0.15.18", + "esbuild-netbsd-64": "0.15.18", + "esbuild-openbsd-64": "0.15.18", + "esbuild-sunos-64": "0.15.18", + "esbuild-windows-32": "0.15.18", + "esbuild-windows-64": "0.15.18", + "esbuild-windows-arm64": "0.15.18" + } + }, + "node_modules/esbuild-android-64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.18.tgz", + "integrity": "sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-android-arm64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.18.tgz", + "integrity": "sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" } }, "node_modules/esbuild-darwin-64": { - "version": "0.15.8", - "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.8.tgz", - "integrity": "sha512-KaKcGfJ+yto7Fo5gAj3xwxHMd1fBIKatpCHK8znTJLVv+9+NN2/tIPBqA4w5rBwjX0UqXDeIE2v1xJP+nGEXgA==", + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.18.tgz", + "integrity": "sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==", "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -5844,6 +5906,278 @@ "node": ">=12" } }, + "node_modules/esbuild-darwin-arm64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.18.tgz", + "integrity": "sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.18.tgz", + "integrity": "sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-arm64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.18.tgz", + "integrity": "sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-32": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.18.tgz", + "integrity": "sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.18.tgz", + "integrity": "sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.18.tgz", + "integrity": "sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.18.tgz", + "integrity": "sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-mips64le": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.18.tgz", + "integrity": "sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-ppc64le": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.18.tgz", + "integrity": "sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-riscv64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.18.tgz", + "integrity": "sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-s390x": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.18.tgz", + "integrity": "sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-netbsd-64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.18.tgz", + "integrity": "sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-openbsd-64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.18.tgz", + "integrity": "sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-sunos-64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.18.tgz", + "integrity": "sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-32": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.18.tgz", + "integrity": "sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.18.tgz", + "integrity": "sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-arm64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.18.tgz", + "integrity": "sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -15681,6 +16015,20 @@ "jsdoc-type-pratt-parser": "~3.0.1" } }, + "@esbuild/android-arm": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.18.tgz", + "integrity": "sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz", + "integrity": "sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==", + "dev": true, + "optional": true + }, "@eslint/eslintrc": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", @@ -19782,39 +20130,173 @@ "dev": true }, "esbuild": { - "version": "0.15.8", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.8.tgz", - "integrity": "sha512-Remsk2dmr1Ia65sU+QasE6svJbsHe62lzR+CnjpUvbZ+uSYo1SitiOWPRfZQkCu82YWZBBKXiD/j0i//XWMZ+Q==", - "devOptional": true, - "requires": { - "@esbuild/android-arm": "0.15.8", - "@esbuild/linux-loong64": "0.15.8", - "esbuild-android-64": "0.15.8", - "esbuild-android-arm64": "0.15.8", - "esbuild-darwin-64": "0.15.8", - "esbuild-darwin-arm64": "0.15.8", - "esbuild-freebsd-64": "0.15.8", - "esbuild-freebsd-arm64": "0.15.8", - "esbuild-linux-32": "0.15.8", - "esbuild-linux-64": "0.15.8", - "esbuild-linux-arm": "0.15.8", - "esbuild-linux-arm64": "0.15.8", - "esbuild-linux-mips64le": "0.15.8", - "esbuild-linux-ppc64le": "0.15.8", - "esbuild-linux-riscv64": "0.15.8", - "esbuild-linux-s390x": "0.15.8", - "esbuild-netbsd-64": "0.15.8", - "esbuild-openbsd-64": "0.15.8", - "esbuild-sunos-64": "0.15.8", - "esbuild-windows-32": "0.15.8", - "esbuild-windows-64": "0.15.8", - "esbuild-windows-arm64": "0.15.8" - } + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.18.tgz", + "integrity": "sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==", + "dev": true, + "requires": { + "@esbuild/android-arm": "0.15.18", + "@esbuild/linux-loong64": "0.15.18", + "esbuild-android-64": "0.15.18", + "esbuild-android-arm64": "0.15.18", + "esbuild-darwin-64": "0.15.18", + "esbuild-darwin-arm64": "0.15.18", + "esbuild-freebsd-64": "0.15.18", + "esbuild-freebsd-arm64": "0.15.18", + "esbuild-linux-32": "0.15.18", + "esbuild-linux-64": "0.15.18", + "esbuild-linux-arm": "0.15.18", + "esbuild-linux-arm64": "0.15.18", + "esbuild-linux-mips64le": "0.15.18", + "esbuild-linux-ppc64le": "0.15.18", + "esbuild-linux-riscv64": "0.15.18", + "esbuild-linux-s390x": "0.15.18", + "esbuild-netbsd-64": "0.15.18", + "esbuild-openbsd-64": "0.15.18", + "esbuild-sunos-64": "0.15.18", + "esbuild-windows-32": "0.15.18", + "esbuild-windows-64": "0.15.18", + "esbuild-windows-arm64": "0.15.18" + } + }, + "esbuild-android-64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.18.tgz", + "integrity": "sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==", + "dev": true, + "optional": true + }, + "esbuild-android-arm64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.18.tgz", + "integrity": "sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==", + "dev": true, + "optional": true }, "esbuild-darwin-64": { - "version": "0.15.8", - "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.8.tgz", - "integrity": "sha512-KaKcGfJ+yto7Fo5gAj3xwxHMd1fBIKatpCHK8znTJLVv+9+NN2/tIPBqA4w5rBwjX0UqXDeIE2v1xJP+nGEXgA==", + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.18.tgz", + "integrity": "sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==", + "dev": true, + "optional": true + }, + "esbuild-darwin-arm64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.18.tgz", + "integrity": "sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==", + "dev": true, + "optional": true + }, + "esbuild-freebsd-64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.18.tgz", + "integrity": "sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==", + "dev": true, + "optional": true + }, + "esbuild-freebsd-arm64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.18.tgz", + "integrity": "sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==", + "dev": true, + "optional": true + }, + "esbuild-linux-32": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.18.tgz", + "integrity": "sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==", + "dev": true, + "optional": true + }, + "esbuild-linux-64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.18.tgz", + "integrity": "sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==", + "dev": true, + "optional": true + }, + "esbuild-linux-arm": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.18.tgz", + "integrity": "sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==", + "dev": true, + "optional": true + }, + "esbuild-linux-arm64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.18.tgz", + "integrity": "sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==", + "dev": true, + "optional": true + }, + "esbuild-linux-mips64le": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.18.tgz", + "integrity": "sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==", + "dev": true, + "optional": true + }, + "esbuild-linux-ppc64le": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.18.tgz", + "integrity": "sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==", + "dev": true, + "optional": true + }, + "esbuild-linux-riscv64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.18.tgz", + "integrity": "sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==", + "dev": true, + "optional": true + }, + "esbuild-linux-s390x": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.18.tgz", + "integrity": "sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==", + "dev": true, + "optional": true + }, + "esbuild-netbsd-64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.18.tgz", + "integrity": "sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==", + "dev": true, + "optional": true + }, + "esbuild-openbsd-64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.18.tgz", + "integrity": "sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==", + "dev": true, + "optional": true + }, + "esbuild-sunos-64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.18.tgz", + "integrity": "sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==", + "dev": true, + "optional": true + }, + "esbuild-windows-32": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.18.tgz", + "integrity": "sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==", + "dev": true, + "optional": true + }, + "esbuild-windows-64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.18.tgz", + "integrity": "sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==", + "dev": true, + "optional": true + }, + "esbuild-windows-arm64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.18.tgz", + "integrity": "sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==", + "dev": true, "optional": true }, "escalade": { diff --git a/package.json b/package.json index e74c2adf0a5..c20ef17ba25 100644 --- a/package.json +++ b/package.json @@ -239,8 +239,5 @@ "typescript": "^4.5.4", "typescript-json-schema": "^0.50.1", "vite": "^3.1.0" - }, - "optionalDependencies": { - "esbuild": "^0.15.7" } } diff --git a/src/frameworks/next/index.ts b/src/frameworks/next/index.ts index 459e6e4aa4f..9e1b8690e37 100644 --- a/src/frameworks/next/index.ts +++ b/src/frameworks/next/index.ts @@ -1,4 +1,4 @@ -import { execSync } from "child_process"; +import { execSync, spawnSync } from "child_process"; import { mkdir, copyFile } from "fs/promises"; import { dirname, join } from "path"; import type { NextConfig } from "next"; @@ -22,7 +22,6 @@ import { SupportLevel, } from ".."; import { promptOnce } from "../../prompt"; -import { logger } from "../../logger"; import { FirebaseError } from "../../error"; import { cleanEscapedChars, @@ -33,8 +32,9 @@ import { isUsingAppDirectory, isUsingImageOptimization, isUsingMiddleware, + allDependencyNames, } from "./utils"; -import type { Manifest } from "./interfaces"; +import type { Manifest, NpmLsReturn } from "./interfaces"; import { readJSON } from "../utils"; import { warnIfCustomBuildScript } from "../utils"; import type { EmulatorInfo } from "../../emulator/types"; @@ -344,25 +344,33 @@ export async function ɵcodegenFunctionsDirectory(sourceDir: string, destDir: st const { distDir } = await getConfig(sourceDir); const packageJson = await readJSON(join(sourceDir, "package.json")); if (existsSync(join(sourceDir, "next.config.js"))) { - let esbuild; - try { - esbuild = await import("esbuild"); - } catch (e: unknown) { - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions - logger.debug(`Failed to load 'esbuild': ${e}`); - throw new FirebaseError( - `Unable to find 'esbuild'. Install it into your local dev dependencies with 'npm i --save-dev esbuild''` + // Bundle their next.config.js with esbuild via NPX, pinned version was having troubles on m1 + // macs and older Node versions; either way, we should avoid taking on any deps in firebase-tools + // Alternatively I tried using @swc/spack and the webpack bundled into Next.js but was + // encountering difficulties with both of those + const dependencyTree: NpmLsReturn = JSON.parse( + spawnSync("npm", ["ls", "--omit=dev", "--all", "--json"], { + cwd: sourceDir, + }).stdout.toString() + ); + // Mark all production deps as externals, so they aren't bundled + // DevDeps won't be included in the Cloud Function, so they should be bundled + const esbuildArgs = allDependencyNames(dependencyTree) + .map((it) => `--external:${it}`) + .concat( + "--bundle", + "--platform=node", + `--target=node${NODE_VERSION}`, + `--outdir=${destDir}`, + "--log-level=error" ); - } - await esbuild.build({ - bundle: true, - external: Object.keys(packageJson.dependencies), - absWorkingDir: sourceDir, - entryPoints: ["next.config.js"], - outfile: join(destDir, "next.config.js"), - target: `node${NODE_VERSION}`, - platform: "node", + const bundle = spawnSync("npx", ["--yes", "esbuild", "next.config.js", ...esbuildArgs], { + cwd: sourceDir, }); + if (bundle.status) { + console.error(bundle.stderr.toString()); + throw new FirebaseError("Unable to bundle next.config.js for use in Cloud Functions"); + } } if (await pathExists(join(sourceDir, "public"))) { await mkdir(join(destDir, "public")); diff --git a/src/frameworks/next/interfaces.ts b/src/frameworks/next/interfaces.ts index 31b6d09b95d..ecdab1bee46 100644 --- a/src/frameworks/next/interfaces.ts +++ b/src/frameworks/next/interfaces.ts @@ -44,3 +44,19 @@ export interface ImagesManifest { sizes: number[]; }; } + +export interface NpmLsDepdendency { + version?: string; + resolved?: string; + dependencies?: { + [key: string]: NpmLsDepdendency; + }; +} + +export interface NpmLsReturn { + version: string; + name: string; + dependencies: { + [key: string]: NpmLsDepdendency; + }; +} diff --git a/src/frameworks/next/utils.ts b/src/frameworks/next/utils.ts index 852088e6b04..793a8cd1245 100644 --- a/src/frameworks/next/utils.ts +++ b/src/frameworks/next/utils.ts @@ -5,7 +5,13 @@ import type { Header, Redirect, Rewrite } from "next/dist/lib/load-custom-routes import type { MiddlewareManifest } from "next/dist/build/webpack/plugins/middleware-plugin"; import { isUrl, readJSON } from "../utils"; -import type { Manifest, RoutesManifestRewrite, ExportMarker, ImagesManifest } from "./interfaces"; +import type { + Manifest, + RoutesManifestRewrite, + ExportMarker, + ImagesManifest, + NpmLsDepdendency, +} from "./interfaces"; import { APP_PATH_ROUTES_MANIFEST, EXPORT_MARKER, @@ -211,3 +217,18 @@ export function isUsingAppDirectory(dir: string): boolean { return fileExistsSync(appPathRoutesManifestPath); } + +/** + * Given input from `npm ls` flatten the dependency tree and return all module names + * + * @param dependencies returned from `npm ls` + */ +export function allDependencyNames(mod: NpmLsDepdendency): string[] { + if (!mod.dependencies) return []; + const dependencyNames = Object.keys(mod.dependencies).reduce( + (acc, it) => [...acc, it, ...allDependencyNames(mod.dependencies![it])], + [] as string[] + ); + // deduplicate the names + return [...new Set(dependencyNames)]; +} diff --git a/src/test/frameworks/next/helpers/index.ts b/src/test/frameworks/next/helpers/index.ts index 4a61b6042d1..c399ba13819 100644 --- a/src/test/frameworks/next/helpers/index.ts +++ b/src/test/frameworks/next/helpers/index.ts @@ -4,3 +4,4 @@ export * from "./redirects"; export * from "./rewrites"; export * from "./images"; export * from "./middleware"; +export * from "./npm"; diff --git a/src/test/frameworks/next/helpers/npm.ts b/src/test/frameworks/next/helpers/npm.ts new file mode 100644 index 00000000000..64972c1afe1 --- /dev/null +++ b/src/test/frameworks/next/helpers/npm.ts @@ -0,0 +1,129 @@ +import { NpmLsReturn } from "../../../../frameworks/next/interfaces"; + +export const npmLsReturn: NpmLsReturn = { + version: "0.1.0", + name: "next-next", + dependencies: { + "@next/font": { + version: "13.0.6", + resolved: "https://registry.npmjs.org/@next/font/-/font-13.0.6.tgz", + }, + next: { + version: "13.0.6", + resolved: "https://registry.npmjs.org/next/-/next-13.0.6.tgz", + dependencies: { + "@next/env": { + version: "13.0.6", + resolved: "https://registry.npmjs.org/@next/env/-/env-13.0.6.tgz", + }, + "@next/swc-android-arm-eabi": {}, + "@next/swc-android-arm64": {}, + "@next/swc-darwin-arm64": {}, + "@next/swc-darwin-x64": { + version: "13.0.6", + resolved: "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.0.6.tgz", + }, + "@next/swc-freebsd-x64": {}, + "@next/swc-linux-arm-gnueabihf": {}, + "@next/swc-linux-arm64-gnu": {}, + "@next/swc-linux-arm64-musl": {}, + "@next/swc-linux-x64-gnu": {}, + "@next/swc-linux-x64-musl": {}, + "@next/swc-win32-arm64-msvc": {}, + "@next/swc-win32-ia32-msvc": {}, + "@next/swc-win32-x64-msvc": {}, + "@swc/helpers": { + version: "0.4.14", + resolved: "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz", + dependencies: { + tslib: { + version: "2.4.1", + resolved: "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + }, + }, + }, + "caniuse-lite": { + version: "1.0.30001439", + resolved: "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001439.tgz", + }, + fibers: {}, + "node-sass": {}, + postcss: { + version: "8.4.14", + resolved: "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", + dependencies: { + nanoid: { + version: "3.3.4", + resolved: "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + }, + picocolors: { + version: "1.0.0", + resolved: "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + }, + "source-map-js": { + version: "1.0.2", + resolved: "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + }, + }, + }, + "react-dom": { + version: "18.2.0", + }, + react: { + version: "18.2.0", + }, + sass: {}, + "styled-jsx": { + version: "5.1.0", + resolved: "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.0.tgz", + dependencies: { + "client-only": { + version: "0.0.1", + resolved: "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + }, + react: { + version: "18.2.0", + }, + }, + }, + }, + }, + "react-dom": { + version: "18.2.0", + resolved: "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + dependencies: { + "loose-envify": { + version: "1.4.0", + resolved: "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + dependencies: { + "js-tokens": { + version: "4.0.0", + resolved: "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + }, + }, + }, + react: { + version: "18.2.0", + }, + scheduler: { + version: "0.23.0", + resolved: "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + dependencies: { + "loose-envify": { + version: "1.4.0", + }, + }, + }, + }, + }, + react: { + version: "18.2.0", + resolved: "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + dependencies: { + "loose-envify": { + version: "1.4.0", + }, + }, + }, + }, +}; diff --git a/src/test/frameworks/next/utils.spec.ts b/src/test/frameworks/next/utils.spec.ts index 776d13af163..31d5877dc49 100644 --- a/src/test/frameworks/next/utils.spec.ts +++ b/src/test/frameworks/next/utils.spec.ts @@ -21,6 +21,7 @@ import { isUsingMiddleware, isUsingImageOptimization, isUsingAppDirectory, + allDependencyNames, } from "../../../frameworks/next/utils"; import * as frameworksUtils from "../../../frameworks/utils"; import * as fsUtils from "../../../fsutils"; @@ -43,6 +44,7 @@ import { unsupportedHeaders, unsupportedRedirects, unsupportedRewritesArray, + npmLsReturn, } from "./helpers"; describe("Next.js utils", () => { @@ -312,4 +314,49 @@ describe("Next.js utils", () => { expect(isUsingAppDirectory("")).to.be.false; }); }); + + describe("allDependencyNames", () => { + it("should return empty on stopping conditions", () => { + expect(allDependencyNames({})).to.eql([]); + expect(allDependencyNames({ version: "foo" })).to.eql([]); + }); + + it("should return expected dependency names", () => { + expect(allDependencyNames(npmLsReturn)).to.eql([ + "@next/font", + "next", + "@next/env", + "@next/swc-android-arm-eabi", + "@next/swc-android-arm64", + "@next/swc-darwin-arm64", + "@next/swc-darwin-x64", + "@next/swc-freebsd-x64", + "@next/swc-linux-arm-gnueabihf", + "@next/swc-linux-arm64-gnu", + "@next/swc-linux-arm64-musl", + "@next/swc-linux-x64-gnu", + "@next/swc-linux-x64-musl", + "@next/swc-win32-arm64-msvc", + "@next/swc-win32-ia32-msvc", + "@next/swc-win32-x64-msvc", + "@swc/helpers", + "tslib", + "caniuse-lite", + "fibers", + "node-sass", + "postcss", + "nanoid", + "picocolors", + "source-map-js", + "react-dom", + "react", + "sass", + "styled-jsx", + "client-only", + "loose-envify", + "js-tokens", + "scheduler", + ]); + }); + }); });