From ee750087ce360c54d349f160d84bbdafb0ec83b4 Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Mon, 14 Nov 2022 13:42:35 -0500 Subject: [PATCH] Fix usage of the Image component with the Vercel adapter (#5361) * Revert "Revert "Allow image-pool to be used as its own Worker (#5317)" (#5360)" This reverts commit 20e60c6e0857f7b6938494df6027e8c1ad74cdc1. * Remove special image-pool.js moving around * Merge in assetIncludes * changeset * Copy to chunk folder in SSR too * Update tidy-shoes-yawn.md --- .changeset/tidy-shoes-yawn.md | 6 ++++++ packages/integrations/image/src/index.ts | 15 ++++++++++++- .../integrations/image/src/loaders/squoosh.ts | 5 +++-- .../image/src/vendor/squoosh/image-pool.ts | 3 ++- packages/integrations/vercel/package.json | 3 ++- .../vercel/src/serverless/adapter.ts | 21 ++++++++++++++++++- pnpm-lock.yaml | 2 ++ 7 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 .changeset/tidy-shoes-yawn.md diff --git a/.changeset/tidy-shoes-yawn.md b/.changeset/tidy-shoes-yawn.md new file mode 100644 index 000000000..e7d2e268e --- /dev/null +++ b/.changeset/tidy-shoes-yawn.md @@ -0,0 +1,6 @@ +--- +'@astrojs/image': patch +'@astrojs/vercel': patch +--- + +Allows @astrojs/image to be used in Vercel SSR diff --git a/packages/integrations/image/src/index.ts b/packages/integrations/image/src/index.ts index e3770d5e9..ebb91e17b 100644 --- a/packages/integrations/image/src/index.ts +++ b/packages/integrations/image/src/index.ts @@ -11,6 +11,12 @@ export { getPicture } from './lib/get-picture.js'; const PKG_NAME = '@astrojs/image'; const ROUTE_PATTERN = '/_image'; +const UNSUPPORTED_ADAPTERS = new Set([ + '@astrojs/cloudflare', + '@astrojs/deno', + '@astrojs/netlify/edge-functions', + '@astrojs/vercel/edge', +]); interface BuildConfig { client: URL; @@ -100,6 +106,13 @@ export default function integration(options: IntegrationOptions = {}): AstroInte _buildConfig = config.build; }, 'astro:build:start': ({ buildConfig }) => { + const adapterName = _config.adapter?.name; + if (adapterName && UNSUPPORTED_ADAPTERS.has(adapterName)) { + throw new Error( + `@astrojs/image is not supported with the ${adapterName} adapter. Please choose a Node.js compatible adapter.` + ); + } + // Backwards compat if (needsBuildConfig) { _buildConfig = buildConfig; @@ -158,7 +171,7 @@ export default function integration(options: IntegrationOptions = {}): AstroInte }, 'astro:build:ssr': async () => { if (resolvedOptions.serviceEntryPoint === '@astrojs/image/squoosh') { - await copyWasmFiles(_buildConfig.server); + await copyWasmFiles(new URL('./chunks/', _buildConfig.server)); } }, }, diff --git a/packages/integrations/image/src/loaders/squoosh.ts b/packages/integrations/image/src/loaders/squoosh.ts index 87d6e26ec..5d71cdb7f 100644 --- a/packages/integrations/image/src/loaders/squoosh.ts +++ b/packages/integrations/image/src/loaders/squoosh.ts @@ -3,11 +3,12 @@ import { red } from 'kleur/colors'; import { error } from '../utils/logger.js'; import { metadata } from '../utils/metadata.js'; import { isRemoteImage } from '../utils/paths.js'; -import { processBuffer } from '../vendor/squoosh/image-pool.js'; import type { Operation } from '../vendor/squoosh/image.js'; import type { OutputFormat, TransformOptions } from './index.js'; import { BaseSSRService } from './index.js'; +const imagePoolModulePromise = import('../vendor/squoosh/image-pool.js'); + class SquooshService extends BaseSSRService { async processAvif(image: any, transform: TransformOptions) { const encodeOptions = transform.quality @@ -112,7 +113,7 @@ class SquooshService extends BaseSSRService { }); throw new Error(`Unknown image output: "${transform.format}" used for ${transform.src}`); } - + const { processBuffer } = await imagePoolModulePromise; const data = await processBuffer(inputBuffer, operations, transform.format, transform.quality); return { diff --git a/packages/integrations/image/src/vendor/squoosh/image-pool.ts b/packages/integrations/image/src/vendor/squoosh/image-pool.ts index d29245fb4..e19215397 100644 --- a/packages/integrations/image/src/vendor/squoosh/image-pool.ts +++ b/packages/integrations/image/src/vendor/squoosh/image-pool.ts @@ -1,5 +1,6 @@ import { isMainThread } from 'node:worker_threads'; import { cpus } from 'os'; +import { fileURLToPath } from 'url'; import type { OutputFormat } from '../../loaders/index.js'; import execOnce from '../../utils/execOnce.js'; import WorkerPool from '../../utils/workerPool.js'; @@ -12,7 +13,7 @@ const getWorker = execOnce( // There will be at most 7 workers needed since each worker will take // at least 1 operation type. Math.max(1, Math.min(cpus().length - 1, 7)), - './node_modules/@astrojs/image/dist/vendor/squoosh/image-pool.js' + fileURLToPath(import.meta.url) ); } ) diff --git a/packages/integrations/vercel/package.json b/packages/integrations/vercel/package.json index db7541fd5..1d30fb5e7 100644 --- a/packages/integrations/vercel/package.json +++ b/packages/integrations/vercel/package.json @@ -45,7 +45,8 @@ }, "dependencies": { "@astrojs/webapi": "^1.1.1", - "@vercel/nft": "^0.22.1" + "@vercel/nft": "^0.22.1", + "fast-glob": "^3.2.11" }, "devDependencies": { "astro": "workspace:*", diff --git a/packages/integrations/vercel/src/serverless/adapter.ts b/packages/integrations/vercel/src/serverless/adapter.ts index 3c7ba15de..3fff42f04 100644 --- a/packages/integrations/vercel/src/serverless/adapter.ts +++ b/packages/integrations/vercel/src/serverless/adapter.ts @@ -3,6 +3,8 @@ import type { AstroAdapter, AstroConfig, AstroIntegration } from 'astro'; import { getVercelOutput, removeDir, writeJson } from '../lib/fs.js'; import { copyDependenciesToFunction } from '../lib/nft.js'; import { getRedirects } from '../lib/redirects.js'; +import glob from 'fast-glob'; +import { pathToFileURL } from 'url'; const PACKAGE_NAME = '@astrojs/vercel/serverless'; @@ -66,11 +68,28 @@ export default function vercelServerless({ } }, 'astro:build:done': async ({ routes }) => { + // Merge any includes from `vite.assetsInclude + const inc = includeFiles?.map((file) => new URL(file, _config.root)) || []; + if(_config.vite.assetsInclude) { + const mergeGlobbedIncludes = (globPattern: unknown) => { + if(typeof globPattern === 'string') { + const entries = glob.sync(globPattern).map(p => pathToFileURL(p)); + inc.push(...entries); + } else if(Array.isArray(globPattern)) { + for(const pattern of globPattern) { + mergeGlobbedIncludes(pattern); + } + } + }; + + mergeGlobbedIncludes(_config.vite.assetsInclude); + } + // Copy necessary files (e.g. node_modules/) const { handler } = await copyDependenciesToFunction({ entry: new URL(serverEntry, buildTempFolder), outDir: functionFolder, - includeFiles: includeFiles?.map((file) => new URL(file, _config.root)) || [], + includeFiles: inc, excludeFiles: excludeFiles?.map((file) => new URL(file, _config.root)) || [], }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4661fb19e..b4f3a0ac2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3186,10 +3186,12 @@ importers: astro: workspace:* astro-scripts: workspace:* chai: ^4.3.6 + fast-glob: ^3.2.11 mocha: ^9.2.2 dependencies: '@astrojs/webapi': link:../../webapi '@vercel/nft': 0.22.1 + fast-glob: 3.2.12 devDependencies: astro: link:../../astro astro-scripts: link:../../../scripts