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 20e60c6e08
.
* Remove special image-pool.js moving around
* Merge in assetIncludes
* changeset
* Copy to chunk folder in SSR too
* Update tidy-shoes-yawn.md
This commit is contained in:
parent
993b58d567
commit
ee750087ce
7 changed files with 49 additions and 6 deletions
6
.changeset/tidy-shoes-yawn.md
Normal file
6
.changeset/tidy-shoes-yawn.md
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
'@astrojs/image': patch
|
||||||
|
'@astrojs/vercel': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Allows @astrojs/image to be used in Vercel SSR
|
|
@ -11,6 +11,12 @@ export { getPicture } from './lib/get-picture.js';
|
||||||
|
|
||||||
const PKG_NAME = '@astrojs/image';
|
const PKG_NAME = '@astrojs/image';
|
||||||
const ROUTE_PATTERN = '/_image';
|
const ROUTE_PATTERN = '/_image';
|
||||||
|
const UNSUPPORTED_ADAPTERS = new Set([
|
||||||
|
'@astrojs/cloudflare',
|
||||||
|
'@astrojs/deno',
|
||||||
|
'@astrojs/netlify/edge-functions',
|
||||||
|
'@astrojs/vercel/edge',
|
||||||
|
]);
|
||||||
|
|
||||||
interface BuildConfig {
|
interface BuildConfig {
|
||||||
client: URL;
|
client: URL;
|
||||||
|
@ -100,6 +106,13 @@ export default function integration(options: IntegrationOptions = {}): AstroInte
|
||||||
_buildConfig = config.build;
|
_buildConfig = config.build;
|
||||||
},
|
},
|
||||||
'astro:build:start': ({ buildConfig }) => {
|
'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
|
// Backwards compat
|
||||||
if (needsBuildConfig) {
|
if (needsBuildConfig) {
|
||||||
_buildConfig = buildConfig;
|
_buildConfig = buildConfig;
|
||||||
|
@ -158,7 +171,7 @@ export default function integration(options: IntegrationOptions = {}): AstroInte
|
||||||
},
|
},
|
||||||
'astro:build:ssr': async () => {
|
'astro:build:ssr': async () => {
|
||||||
if (resolvedOptions.serviceEntryPoint === '@astrojs/image/squoosh') {
|
if (resolvedOptions.serviceEntryPoint === '@astrojs/image/squoosh') {
|
||||||
await copyWasmFiles(_buildConfig.server);
|
await copyWasmFiles(new URL('./chunks/', _buildConfig.server));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,11 +3,12 @@ import { red } from 'kleur/colors';
|
||||||
import { error } from '../utils/logger.js';
|
import { error } from '../utils/logger.js';
|
||||||
import { metadata } from '../utils/metadata.js';
|
import { metadata } from '../utils/metadata.js';
|
||||||
import { isRemoteImage } from '../utils/paths.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 { Operation } from '../vendor/squoosh/image.js';
|
||||||
import type { OutputFormat, TransformOptions } from './index.js';
|
import type { OutputFormat, TransformOptions } from './index.js';
|
||||||
import { BaseSSRService } from './index.js';
|
import { BaseSSRService } from './index.js';
|
||||||
|
|
||||||
|
const imagePoolModulePromise = import('../vendor/squoosh/image-pool.js');
|
||||||
|
|
||||||
class SquooshService extends BaseSSRService {
|
class SquooshService extends BaseSSRService {
|
||||||
async processAvif(image: any, transform: TransformOptions) {
|
async processAvif(image: any, transform: TransformOptions) {
|
||||||
const encodeOptions = transform.quality
|
const encodeOptions = transform.quality
|
||||||
|
@ -112,7 +113,7 @@ class SquooshService extends BaseSSRService {
|
||||||
});
|
});
|
||||||
throw new Error(`Unknown image output: "${transform.format}" used for ${transform.src}`);
|
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);
|
const data = await processBuffer(inputBuffer, operations, transform.format, transform.quality);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { isMainThread } from 'node:worker_threads';
|
import { isMainThread } from 'node:worker_threads';
|
||||||
import { cpus } from 'os';
|
import { cpus } from 'os';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
import type { OutputFormat } from '../../loaders/index.js';
|
import type { OutputFormat } from '../../loaders/index.js';
|
||||||
import execOnce from '../../utils/execOnce.js';
|
import execOnce from '../../utils/execOnce.js';
|
||||||
import WorkerPool from '../../utils/workerPool.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
|
// There will be at most 7 workers needed since each worker will take
|
||||||
// at least 1 operation type.
|
// at least 1 operation type.
|
||||||
Math.max(1, Math.min(cpus().length - 1, 7)),
|
Math.max(1, Math.min(cpus().length - 1, 7)),
|
||||||
'./node_modules/@astrojs/image/dist/vendor/squoosh/image-pool.js'
|
fileURLToPath(import.meta.url)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -45,7 +45,8 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/webapi": "^1.1.1",
|
"@astrojs/webapi": "^1.1.1",
|
||||||
"@vercel/nft": "^0.22.1"
|
"@vercel/nft": "^0.22.1",
|
||||||
|
"fast-glob": "^3.2.11"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"astro": "workspace:*",
|
"astro": "workspace:*",
|
||||||
|
|
|
@ -3,6 +3,8 @@ import type { AstroAdapter, AstroConfig, AstroIntegration } from 'astro';
|
||||||
import { getVercelOutput, removeDir, writeJson } from '../lib/fs.js';
|
import { getVercelOutput, removeDir, writeJson } from '../lib/fs.js';
|
||||||
import { copyDependenciesToFunction } from '../lib/nft.js';
|
import { copyDependenciesToFunction } from '../lib/nft.js';
|
||||||
import { getRedirects } from '../lib/redirects.js';
|
import { getRedirects } from '../lib/redirects.js';
|
||||||
|
import glob from 'fast-glob';
|
||||||
|
import { pathToFileURL } from 'url';
|
||||||
|
|
||||||
const PACKAGE_NAME = '@astrojs/vercel/serverless';
|
const PACKAGE_NAME = '@astrojs/vercel/serverless';
|
||||||
|
|
||||||
|
@ -66,11 +68,28 @@ export default function vercelServerless({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'astro:build:done': async ({ routes }) => {
|
'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/)
|
// Copy necessary files (e.g. node_modules/)
|
||||||
const { handler } = await copyDependenciesToFunction({
|
const { handler } = await copyDependenciesToFunction({
|
||||||
entry: new URL(serverEntry, buildTempFolder),
|
entry: new URL(serverEntry, buildTempFolder),
|
||||||
outDir: functionFolder,
|
outDir: functionFolder,
|
||||||
includeFiles: includeFiles?.map((file) => new URL(file, _config.root)) || [],
|
includeFiles: inc,
|
||||||
excludeFiles: excludeFiles?.map((file) => new URL(file, _config.root)) || [],
|
excludeFiles: excludeFiles?.map((file) => new URL(file, _config.root)) || [],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -3186,10 +3186,12 @@ importers:
|
||||||
astro: workspace:*
|
astro: workspace:*
|
||||||
astro-scripts: workspace:*
|
astro-scripts: workspace:*
|
||||||
chai: ^4.3.6
|
chai: ^4.3.6
|
||||||
|
fast-glob: ^3.2.11
|
||||||
mocha: ^9.2.2
|
mocha: ^9.2.2
|
||||||
dependencies:
|
dependencies:
|
||||||
'@astrojs/webapi': link:../../webapi
|
'@astrojs/webapi': link:../../webapi
|
||||||
'@vercel/nft': 0.22.1
|
'@vercel/nft': 0.22.1
|
||||||
|
fast-glob: 3.2.12
|
||||||
devDependencies:
|
devDependencies:
|
||||||
astro: link:../../astro
|
astro: link:../../astro
|
||||||
astro-scripts: link:../../../scripts
|
astro-scripts: link:../../../scripts
|
||||||
|
|
Loading…
Reference in a new issue