Fixes type definitions @astrojs/image
and adds more documentation to the README (#4045)
* WIP: moving to a static .d.ts types file * fixing named exports for getImage and getPicture * removing the exports.astro map for now * WIP: adding readme docs for component attributes * Adding docs for getImage and getPicture * leaning fully on TSC to build .d.ts files * finally found the solution for proper ESM import types * adding a note to the README for tsconfig updates * chore: add changesets * typo * docs: removing the "Images in Markdown" example * removing the need for publishing src to NPM * fix: make type re-export explicit * updating image module defs to match InputFormat * using astro syntax highlighting for README code blocks * nit: missing backtick in README * make sure Astro component directives aren't recommended twice
This commit is contained in:
parent
55c8aced44
commit
a397b981f5
22 changed files with 606 additions and 363 deletions
5
.changeset/fifty-apricots-clap.md
Normal file
5
.changeset/fifty-apricots-clap.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Adding support for custom "astro/client" type definitions in `@astrojs/image`
|
5
.changeset/five-singers-notice.md
Normal file
5
.changeset/five-singers-notice.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'@astrojs/image': minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Big improvements to the TypeScript and Language Tools support for `@astrojs/image` :tada:
|
173
packages/astro/client-base.d.ts
vendored
Normal file
173
packages/astro/client-base.d.ts
vendored
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
/// <reference types="vite/types/importMeta" />
|
||||||
|
|
||||||
|
// CSS modules
|
||||||
|
type CSSModuleClasses = { readonly [key: string]: string };
|
||||||
|
|
||||||
|
declare module '*.module.css' {
|
||||||
|
const classes: CSSModuleClasses;
|
||||||
|
export default classes;
|
||||||
|
}
|
||||||
|
declare module '*.module.scss' {
|
||||||
|
const classes: CSSModuleClasses;
|
||||||
|
export default classes;
|
||||||
|
}
|
||||||
|
declare module '*.module.sass' {
|
||||||
|
const classes: CSSModuleClasses;
|
||||||
|
export default classes;
|
||||||
|
}
|
||||||
|
declare module '*.module.less' {
|
||||||
|
const classes: CSSModuleClasses;
|
||||||
|
export default classes;
|
||||||
|
}
|
||||||
|
declare module '*.module.styl' {
|
||||||
|
const classes: CSSModuleClasses;
|
||||||
|
export default classes;
|
||||||
|
}
|
||||||
|
declare module '*.module.stylus' {
|
||||||
|
const classes: CSSModuleClasses;
|
||||||
|
export default classes;
|
||||||
|
}
|
||||||
|
declare module '*.module.pcss' {
|
||||||
|
const classes: CSSModuleClasses;
|
||||||
|
export default classes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CSS
|
||||||
|
declare module '*.css' {
|
||||||
|
const css: string;
|
||||||
|
export default css;
|
||||||
|
}
|
||||||
|
declare module '*.scss' {
|
||||||
|
const css: string;
|
||||||
|
export default css;
|
||||||
|
}
|
||||||
|
declare module '*.sass' {
|
||||||
|
const css: string;
|
||||||
|
export default css;
|
||||||
|
}
|
||||||
|
declare module '*.less' {
|
||||||
|
const css: string;
|
||||||
|
export default css;
|
||||||
|
}
|
||||||
|
declare module '*.styl' {
|
||||||
|
const css: string;
|
||||||
|
export default css;
|
||||||
|
}
|
||||||
|
declare module '*.stylus' {
|
||||||
|
const css: string;
|
||||||
|
export default css;
|
||||||
|
}
|
||||||
|
declare module '*.pcss' {
|
||||||
|
const css: string;
|
||||||
|
export default css;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Built-in asset types
|
||||||
|
// see `src/constants.ts`
|
||||||
|
|
||||||
|
// media
|
||||||
|
declare module '*.mp4' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
declare module '*.webm' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
declare module '*.ogg' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
declare module '*.mp3' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
declare module '*.wav' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
declare module '*.flac' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
declare module '*.aac' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fonts
|
||||||
|
declare module '*.woff' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
declare module '*.woff2' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
declare module '*.eot' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
declare module '*.ttf' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
declare module '*.otf' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
|
||||||
|
// other
|
||||||
|
declare module '*.wasm' {
|
||||||
|
const initWasm: (options: WebAssembly.Imports) => Promise<WebAssembly.Exports>;
|
||||||
|
export default initWasm;
|
||||||
|
}
|
||||||
|
declare module '*.webmanifest' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
declare module '*.pdf' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
declare module '*.txt' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
|
||||||
|
// web worker
|
||||||
|
declare module '*?worker' {
|
||||||
|
const workerConstructor: {
|
||||||
|
new (): Worker;
|
||||||
|
};
|
||||||
|
export default workerConstructor;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*?worker&inline' {
|
||||||
|
const workerConstructor: {
|
||||||
|
new (): Worker;
|
||||||
|
};
|
||||||
|
export default workerConstructor;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*?sharedworker' {
|
||||||
|
const sharedWorkerConstructor: {
|
||||||
|
new (): SharedWorker;
|
||||||
|
};
|
||||||
|
export default sharedWorkerConstructor;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*?raw' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*?url' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*?inline' {
|
||||||
|
const src: string;
|
||||||
|
export default src;
|
||||||
|
}
|
174
packages/astro/client.d.ts
vendored
174
packages/astro/client.d.ts
vendored
|
@ -1,69 +1,4 @@
|
||||||
/// <reference types="vite/types/importMeta" />
|
/// <reference path="./client-base.d.ts" />
|
||||||
|
|
||||||
// CSS modules
|
|
||||||
type CSSModuleClasses = { readonly [key: string]: string };
|
|
||||||
|
|
||||||
declare module '*.module.css' {
|
|
||||||
const classes: CSSModuleClasses;
|
|
||||||
export default classes;
|
|
||||||
}
|
|
||||||
declare module '*.module.scss' {
|
|
||||||
const classes: CSSModuleClasses;
|
|
||||||
export default classes;
|
|
||||||
}
|
|
||||||
declare module '*.module.sass' {
|
|
||||||
const classes: CSSModuleClasses;
|
|
||||||
export default classes;
|
|
||||||
}
|
|
||||||
declare module '*.module.less' {
|
|
||||||
const classes: CSSModuleClasses;
|
|
||||||
export default classes;
|
|
||||||
}
|
|
||||||
declare module '*.module.styl' {
|
|
||||||
const classes: CSSModuleClasses;
|
|
||||||
export default classes;
|
|
||||||
}
|
|
||||||
declare module '*.module.stylus' {
|
|
||||||
const classes: CSSModuleClasses;
|
|
||||||
export default classes;
|
|
||||||
}
|
|
||||||
declare module '*.module.pcss' {
|
|
||||||
const classes: CSSModuleClasses;
|
|
||||||
export default classes;
|
|
||||||
}
|
|
||||||
|
|
||||||
// CSS
|
|
||||||
declare module '*.css' {
|
|
||||||
const css: string;
|
|
||||||
export default css;
|
|
||||||
}
|
|
||||||
declare module '*.scss' {
|
|
||||||
const css: string;
|
|
||||||
export default css;
|
|
||||||
}
|
|
||||||
declare module '*.sass' {
|
|
||||||
const css: string;
|
|
||||||
export default css;
|
|
||||||
}
|
|
||||||
declare module '*.less' {
|
|
||||||
const css: string;
|
|
||||||
export default css;
|
|
||||||
}
|
|
||||||
declare module '*.styl' {
|
|
||||||
const css: string;
|
|
||||||
export default css;
|
|
||||||
}
|
|
||||||
declare module '*.stylus' {
|
|
||||||
const css: string;
|
|
||||||
export default css;
|
|
||||||
}
|
|
||||||
declare module '*.pcss' {
|
|
||||||
const css: string;
|
|
||||||
export default css;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Built-in asset types
|
|
||||||
// see `src/constants.ts`
|
|
||||||
|
|
||||||
// images
|
// images
|
||||||
declare module '*.jpg' {
|
declare module '*.jpg' {
|
||||||
|
@ -98,110 +33,3 @@ declare module '*.avif' {
|
||||||
const src: string;
|
const src: string;
|
||||||
export default src;
|
export default src;
|
||||||
}
|
}
|
||||||
|
|
||||||
// media
|
|
||||||
declare module '*.mp4' {
|
|
||||||
const src: string;
|
|
||||||
export default src;
|
|
||||||
}
|
|
||||||
declare module '*.webm' {
|
|
||||||
const src: string;
|
|
||||||
export default src;
|
|
||||||
}
|
|
||||||
declare module '*.ogg' {
|
|
||||||
const src: string;
|
|
||||||
export default src;
|
|
||||||
}
|
|
||||||
declare module '*.mp3' {
|
|
||||||
const src: string;
|
|
||||||
export default src;
|
|
||||||
}
|
|
||||||
declare module '*.wav' {
|
|
||||||
const src: string;
|
|
||||||
export default src;
|
|
||||||
}
|
|
||||||
declare module '*.flac' {
|
|
||||||
const src: string;
|
|
||||||
export default src;
|
|
||||||
}
|
|
||||||
declare module '*.aac' {
|
|
||||||
const src: string;
|
|
||||||
export default src;
|
|
||||||
}
|
|
||||||
|
|
||||||
// fonts
|
|
||||||
declare module '*.woff' {
|
|
||||||
const src: string;
|
|
||||||
export default src;
|
|
||||||
}
|
|
||||||
declare module '*.woff2' {
|
|
||||||
const src: string;
|
|
||||||
export default src;
|
|
||||||
}
|
|
||||||
declare module '*.eot' {
|
|
||||||
const src: string;
|
|
||||||
export default src;
|
|
||||||
}
|
|
||||||
declare module '*.ttf' {
|
|
||||||
const src: string;
|
|
||||||
export default src;
|
|
||||||
}
|
|
||||||
declare module '*.otf' {
|
|
||||||
const src: string;
|
|
||||||
export default src;
|
|
||||||
}
|
|
||||||
|
|
||||||
// other
|
|
||||||
declare module '*.wasm' {
|
|
||||||
const initWasm: (options: WebAssembly.Imports) => Promise<WebAssembly.Exports>;
|
|
||||||
export default initWasm;
|
|
||||||
}
|
|
||||||
declare module '*.webmanifest' {
|
|
||||||
const src: string;
|
|
||||||
export default src;
|
|
||||||
}
|
|
||||||
declare module '*.pdf' {
|
|
||||||
const src: string;
|
|
||||||
export default src;
|
|
||||||
}
|
|
||||||
declare module '*.txt' {
|
|
||||||
const src: string;
|
|
||||||
export default src;
|
|
||||||
}
|
|
||||||
|
|
||||||
// web worker
|
|
||||||
declare module '*?worker' {
|
|
||||||
const workerConstructor: {
|
|
||||||
new (): Worker;
|
|
||||||
};
|
|
||||||
export default workerConstructor;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module '*?worker&inline' {
|
|
||||||
const workerConstructor: {
|
|
||||||
new (): Worker;
|
|
||||||
};
|
|
||||||
export default workerConstructor;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module '*?sharedworker' {
|
|
||||||
const sharedWorkerConstructor: {
|
|
||||||
new (): SharedWorker;
|
|
||||||
};
|
|
||||||
export default sharedWorkerConstructor;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module '*?raw' {
|
|
||||||
const src: string;
|
|
||||||
export default src;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module '*?url' {
|
|
||||||
const src: string;
|
|
||||||
export default src;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module '*?inline' {
|
|
||||||
const src: string;
|
|
||||||
export default src;
|
|
||||||
}
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
".": "./astro.js",
|
".": "./astro.js",
|
||||||
"./env": "./env.d.ts",
|
"./env": "./env.d.ts",
|
||||||
"./client": "./client.d.ts",
|
"./client": "./client.d.ts",
|
||||||
|
"./client-base": "./client-base.d.ts",
|
||||||
"./astro-jsx": "./astro-jsx.d.ts",
|
"./astro-jsx": "./astro-jsx.d.ts",
|
||||||
"./jsx/*": "./dist/jsx/*",
|
"./jsx/*": "./dist/jsx/*",
|
||||||
"./jsx-runtime": "./dist/jsx-runtime/index.js",
|
"./jsx-runtime": "./dist/jsx-runtime/index.js",
|
||||||
|
@ -65,6 +66,7 @@
|
||||||
"config.mjs",
|
"config.mjs",
|
||||||
"env.d.ts",
|
"env.d.ts",
|
||||||
"client.d.ts",
|
"client.d.ts",
|
||||||
|
"client-base.d.ts",
|
||||||
"astro-jsx.d.ts",
|
"astro-jsx.d.ts",
|
||||||
"README.md",
|
"README.md",
|
||||||
"vendor"
|
"vendor"
|
||||||
|
|
|
@ -63,11 +63,205 @@ export default {
|
||||||
Then, restart the dev server.
|
Then, restart the dev server.
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
### Update `tsconfig.json`
|
||||||
|
|
||||||
|
For the best development experience, add the integrations type definitions to your project's `tsconfig.json` file.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
// Replace `astro/client` with `@astrojs/image/client`
|
||||||
|
"types": ["@astrojs/image/client"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
The included `sharp` transformer supports resizing images and encoding them to different image formats. Third-party image services will be able to add support for custom transformations as well (ex: `blur`, `filter`, `rotate`, etc).
|
||||||
|
|
||||||
|
### `<Image />`
|
||||||
|
|
||||||
The built-in `<Image />` component is used to create an optimized `<img />` for both remote images hosted on other domains as well as local images imported from your project's `src` directory.
|
The built-in `<Image />` component is used to create an optimized `<img />` for both remote images hosted on other domains as well as local images imported from your project's `src` directory.
|
||||||
|
|
||||||
The included `sharp` transformer supports resizing images and encoding them to different image formats. Third-party image services will be able to add support for custom transformations as well (ex: `blur`, `filter`, `rotate`, etc).
|
In addition to the component-specific properties, any valid HTML attribute for the `<img />` included in the `<Image />` component will be included in the built `<img />`.
|
||||||
|
|
||||||
|
#### src
|
||||||
|
|
||||||
|
<p>
|
||||||
|
|
||||||
|
**Type:** `string` | `ImageMetadata` | `Promise<ImageMetadata>`<br>
|
||||||
|
**Required:** `true`
|
||||||
|
</p>
|
||||||
|
|
||||||
|
Source for the original image file.
|
||||||
|
|
||||||
|
For images in your project's repository, use the `src` relative to the `public` directory. For remote images, provide the full URL.
|
||||||
|
|
||||||
|
#### format
|
||||||
|
|
||||||
|
<p>
|
||||||
|
|
||||||
|
**Type:** 'avif' | 'jpeg' | 'png' | 'webp'<br>
|
||||||
|
**Default:** `undefined`
|
||||||
|
</p>
|
||||||
|
|
||||||
|
The output format to be used in the optimized image. The original image format will be used if `format` is not provided.
|
||||||
|
|
||||||
|
#### quality
|
||||||
|
|
||||||
|
<p>
|
||||||
|
|
||||||
|
**Type:** `number`<br>
|
||||||
|
**Default:** `undefined`
|
||||||
|
</p>
|
||||||
|
|
||||||
|
The compression quality used during optimization. The image service will use a default quality if not provided.
|
||||||
|
|
||||||
|
#### width
|
||||||
|
|
||||||
|
<p>
|
||||||
|
|
||||||
|
**Type:** `number`<br>
|
||||||
|
**Default:** `undefined`
|
||||||
|
</p>
|
||||||
|
|
||||||
|
The desired width of the output image. Combine with `height` to crop the image to an exact size, or `aspectRatio` to automatically calculate and crop the height.
|
||||||
|
|
||||||
|
Dimensions are optional for local images, the original image size will be used if not provided.
|
||||||
|
|
||||||
|
For remote images, the integration needs to be able to calculate dimensions for the optimized image. This can be done by providing `width` and `height` or by providing one dimension and an `aspectRatio`.
|
||||||
|
|
||||||
|
#### height
|
||||||
|
|
||||||
|
<p>
|
||||||
|
|
||||||
|
**Type:** `number`<br>
|
||||||
|
**Default:** `undefined`
|
||||||
|
</p>
|
||||||
|
|
||||||
|
The desired height of the output image. Combine with `width` to crop the image to an exact size, or `aspectRatio` to automatically calculate and crop the width.
|
||||||
|
|
||||||
|
Dimensions are optional for local images, the original image size will be used if not provided.
|
||||||
|
|
||||||
|
For remote images, the integration needs to be able to calculate dimensions for the optimized image. This can be done by providing `width` and `height` or by providing one dimension and an `aspectRatio`.
|
||||||
|
|
||||||
|
#### aspectRatio
|
||||||
|
|
||||||
|
<p>
|
||||||
|
|
||||||
|
**Type:** `number` | `string`<br>
|
||||||
|
**Default:** `undefined`
|
||||||
|
</p>
|
||||||
|
|
||||||
|
The desired aspect ratio of the output image. Combine with either `width` or `height` to automatically calculate and crop the other dimension.
|
||||||
|
|
||||||
|
A `string` can be provided in the form of `{width}:{height}`, ex: `16:9` or `3:4`.
|
||||||
|
|
||||||
|
A `number` can also be provided, useful when the aspect ratio is calculated at build time. This can be an inline number such as `1.777` or inlined as a JSX expression like `aspectRatio={16/9}`.
|
||||||
|
|
||||||
|
### `<Picture /`>
|
||||||
|
|
||||||
|
#### src
|
||||||
|
|
||||||
|
<p>
|
||||||
|
|
||||||
|
**Type:** `string` | `ImageMetadata` | `Promise<ImageMetadata>`<br>
|
||||||
|
**Required:** `true`
|
||||||
|
</p>
|
||||||
|
|
||||||
|
Source for the original image file.
|
||||||
|
|
||||||
|
For images in your project's repository, use the `src` relative to the `public` directory. For remote images, provide the full URL.
|
||||||
|
|
||||||
|
#### alt
|
||||||
|
|
||||||
|
<p>
|
||||||
|
|
||||||
|
**Type:** `string`<br>
|
||||||
|
**Default:** `undefined`
|
||||||
|
</p>
|
||||||
|
|
||||||
|
If provided, the `alt` string will be included on the built `<img />` element.
|
||||||
|
|
||||||
|
#### sizes
|
||||||
|
|
||||||
|
<p>
|
||||||
|
|
||||||
|
**Type:** `string`<br>
|
||||||
|
**Required:** `true`
|
||||||
|
</p>
|
||||||
|
|
||||||
|
The HTMLImageElement property `sizes` allows you to specify the layout width of the image for each of a list of media conditions.
|
||||||
|
|
||||||
|
See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/sizes) for more details.
|
||||||
|
|
||||||
|
#### widths
|
||||||
|
|
||||||
|
<p>
|
||||||
|
|
||||||
|
**Type:** `number[]`<br>
|
||||||
|
**Reuqired:** `true`
|
||||||
|
</p>
|
||||||
|
|
||||||
|
The list of sizes that should be built for responsive images. This is combined with `aspectRatio` to calculate the final dimensions of each built image.
|
||||||
|
|
||||||
|
```astro
|
||||||
|
// Builds three images: 400x400, 800x800, and 1200x1200
|
||||||
|
<Picture src={...} widths={[400, 800, 1200]} aspectRatio="1:1" />
|
||||||
|
```
|
||||||
|
|
||||||
|
#### aspectRatio
|
||||||
|
|
||||||
|
<p>
|
||||||
|
|
||||||
|
**Type:** `number` | `string`<br>
|
||||||
|
**Required:** `true`
|
||||||
|
</p>
|
||||||
|
|
||||||
|
The desired aspect ratio of the output image. This is combined with `widhts` to calculate the final dimensions of each built image.
|
||||||
|
|
||||||
|
A `string` can be provided in the form of `{width}:{height}`, ex: `16:9` or `3:4`.
|
||||||
|
|
||||||
|
A `number` can also be provided, useful when the aspect ratio is calculated at build time. This can be an inline number such as `1.777` or inlined as a JSX expression like `aspectRatio={16/9}`.
|
||||||
|
|
||||||
|
#### formats
|
||||||
|
|
||||||
|
<p>
|
||||||
|
|
||||||
|
**Type:** Array<'avif' | 'jpeg' | 'png' | 'webp'><br>
|
||||||
|
**Default:** `undefined`
|
||||||
|
</p>
|
||||||
|
|
||||||
|
The output formats to be used in the optimized image. If not provided, `webp` and `avif` will be used in addition to the original image format.
|
||||||
|
|
||||||
|
### `getImage`
|
||||||
|
|
||||||
|
This is the helper function used by the `<Image />` component to build `<img />` attributes for the transformed image. This helper can be used directly for more complex use cases that aren't currently supported by the `<Image />` component.
|
||||||
|
|
||||||
|
This helper takes in an object with the same properties as the `<Image />` component and returns an object with attributes that should be included on the final `<img />` element.
|
||||||
|
|
||||||
|
This can helpful if you need to add preload links to a page's `<head>`.
|
||||||
|
|
||||||
|
```astro
|
||||||
|
---
|
||||||
|
import { getImage } from '@astrojs/image';
|
||||||
|
|
||||||
|
const { src } = await getImage('../assets/hero.png');
|
||||||
|
---
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link rel="preload" as="image" href={src}>
|
||||||
|
</head>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
### `getPicture`
|
||||||
|
|
||||||
|
This is the helper function used by the `<Picture />` component to build multiple sizes and formats for responsive images. This helper can be used directly for more complex use cases that aren't currently supported by the `<Picture />` component.
|
||||||
|
|
||||||
|
This helper takes in an object with the same properties as the `<Picture />` component and returns an object attributes that should be included on the final `<img />` element **and** a list of sources that should be used to render all `<source>`s for the `<picture>` element.
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
|
@ -102,7 +296,7 @@ export default {
|
||||||
|
|
||||||
Image files in your project's `src` directory can be imported in frontmatter and passed directly to the `<Image />` component. All other properties are optional and will default to the original image file's properties if not provided.
|
Image files in your project's `src` directory can be imported in frontmatter and passed directly to the `<Image />` component. All other properties are optional and will default to the original image file's properties if not provided.
|
||||||
|
|
||||||
```html
|
```astro
|
||||||
---
|
---
|
||||||
import { Image } from '@astrojs/image/components';
|
import { Image } from '@astrojs/image/components';
|
||||||
import heroImage from '../assets/hero.png';
|
import heroImage from '../assets/hero.png';
|
||||||
|
@ -130,7 +324,7 @@ import heroImage from '../assets/hero.png';
|
||||||
|
|
||||||
Remote images can be transformed with the `<Image />` component. The `<Image />` component needs to know the final dimensions for the `<img />` element to avoid content layout shifts. For remote images, this means you must either provide `width` and `height`, or one of the dimensions plus the required `aspectRatio`.
|
Remote images can be transformed with the `<Image />` component. The `<Image />` component needs to know the final dimensions for the `<img />` element to avoid content layout shifts. For remote images, this means you must either provide `width` and `height`, or one of the dimensions plus the required `aspectRatio`.
|
||||||
|
|
||||||
```html
|
```astro
|
||||||
---
|
---
|
||||||
import { Image } from '@astrojs/image/components';
|
import { Image } from '@astrojs/image/components';
|
||||||
|
|
||||||
|
@ -148,28 +342,6 @@ const imageUrl = 'https://www.google.com/images/branding/googlelogo/2x/googlelog
|
||||||
```
|
```
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary><strong>Images in markdown</strong></summary>
|
|
||||||
|
|
||||||
The `<Image />` component can also be used to optimize images in markdown pages. For local images imported from your project's `src` directory, use Astro's the `setup` frontmatter to import the image file.
|
|
||||||
|
|
||||||
```html
|
|
||||||
---
|
|
||||||
setup: |
|
|
||||||
import { Image } from '@astrojs/image/components'
|
|
||||||
import hero from '../../assets/blog/introducing-astro.jpg'
|
|
||||||
title: Hello world!
|
|
||||||
publishDate: 12 Sep 2021
|
|
||||||
name: Nate Moore
|
|
||||||
value: 128
|
|
||||||
description: Just a Hello World Post!
|
|
||||||
---
|
|
||||||
|
|
||||||
<Image src={hero} width={640} />
|
|
||||||
<Image src="https://example.com/image.jpg" width={640} aspectRatio="16:9" />
|
|
||||||
```
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><strong>Responsive pictures</strong></summary>
|
<summary><strong>Responsive pictures</strong></summary>
|
||||||
|
|
||||||
|
@ -179,7 +351,7 @@ description: Just a Hello World Post!
|
||||||
|
|
||||||
For remote images, an `aspectRatio` is required to ensure the correct `height` can be calculated at build time.
|
For remote images, an `aspectRatio` is required to ensure the correct `height` can be calculated at build time.
|
||||||
|
|
||||||
```html
|
```astro
|
||||||
---
|
---
|
||||||
import { Picture } from '@astrojs/image/components';
|
import { Picture } from '@astrojs/image/components';
|
||||||
import hero from '../assets/hero.png';
|
import hero from '../assets/hero.png';
|
||||||
|
|
55
packages/integrations/image/client.d.ts
vendored
Normal file
55
packages/integrations/image/client.d.ts
vendored
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
type InputFormat =
|
||||||
|
| 'avif'
|
||||||
|
| 'gif'
|
||||||
|
| 'heic'
|
||||||
|
| 'heif'
|
||||||
|
| 'jpeg'
|
||||||
|
| 'jpg'
|
||||||
|
| 'png'
|
||||||
|
| 'tiff'
|
||||||
|
| 'webp';
|
||||||
|
|
||||||
|
interface ImageMetadata {
|
||||||
|
src: string;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
format: InputFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
// images
|
||||||
|
declare module '*.avif' {
|
||||||
|
const metadata: ImageMetadata;
|
||||||
|
export default metadata;
|
||||||
|
}
|
||||||
|
declare module '*.gif' {
|
||||||
|
const metadata: ImageMetadata;
|
||||||
|
export default metadata;
|
||||||
|
}
|
||||||
|
declare module '*.heic' {
|
||||||
|
const metadata: ImageMetadata;
|
||||||
|
export default metadata;
|
||||||
|
}
|
||||||
|
declare module '*.heif' {
|
||||||
|
const metadata: ImageMetadata;
|
||||||
|
export default metadata;
|
||||||
|
}
|
||||||
|
declare module '*.jpeg' {
|
||||||
|
const metadata: ImageMetadata;
|
||||||
|
export default metadata;
|
||||||
|
}
|
||||||
|
declare module '*.jpg' {
|
||||||
|
const metadata: ImageMetadata;
|
||||||
|
export default metadata;
|
||||||
|
}
|
||||||
|
declare module '*.png' {
|
||||||
|
const metadata: ImageMetadata;
|
||||||
|
export default metadata;
|
||||||
|
}
|
||||||
|
declare module '*.tiff' {
|
||||||
|
const metadata: ImageMetadata;
|
||||||
|
export default metadata;
|
||||||
|
}
|
||||||
|
declare module '*.webp' {
|
||||||
|
const metadata: ImageMetadata;
|
||||||
|
export default metadata;
|
||||||
|
}
|
|
@ -1,13 +1,16 @@
|
||||||
---
|
---
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { getImage } from '../dist/index.js';
|
import { getImage } from '../dist/index.js';
|
||||||
import type { ImageAttributes, ImageMetadata, TransformOptions, OutputFormat } from '../dist/types';
|
import type { ImgHTMLAttributes } from './index.js';
|
||||||
|
import type { ImageMetadata, TransformOptions, OutputFormat } from '../dist/index.js';
|
||||||
|
|
||||||
export interface LocalImageProps extends Omit<TransformOptions, 'src'>, Omit<ImageAttributes, 'src' | 'width' | 'height'> {
|
interface LocalImageProps extends
|
||||||
|
Omit<TransformOptions, 'src'>,
|
||||||
|
Omit<ImgHTMLAttributes, | 'src' | 'width' | 'height'> {
|
||||||
src: ImageMetadata | Promise<{ default: ImageMetadata }>;
|
src: ImageMetadata | Promise<{ default: ImageMetadata }>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RemoteImageProps extends TransformOptions, ImageAttributes {
|
interface RemoteImageProps extends TransformOptions, astroHTML.JSX.ImgHTMLAttributes {
|
||||||
src: string;
|
src: string;
|
||||||
format: OutputFormat;
|
format: OutputFormat;
|
||||||
width: number;
|
width: number;
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
---
|
---
|
||||||
import { getPicture } from '../dist/index.js';
|
import { getPicture } from '../dist/index.js';
|
||||||
import type { ImageAttributes, ImageMetadata, OutputFormat, PictureAttributes, TransformOptions } from '../dist/types';
|
import type { ImgHTMLAttributes, HTMLAttributes } from './index.js';
|
||||||
|
import type { ImageMetadata, OutputFormat, TransformOptions } from '../dist/index.js';
|
||||||
|
|
||||||
export interface LocalImageProps extends Omit<PictureAttributes, 'src' | 'width' | 'height'>, Omit<TransformOptions, 'src'>, Pick<ImageAttributes, 'loading' | 'decoding'> {
|
interface LocalImageProps extends
|
||||||
|
Omit<HTMLAttributes, 'src' | 'width' | 'height'>,
|
||||||
|
Omit<TransformOptions, 'src'>,
|
||||||
|
Pick<astroHTML.JSX.ImgHTMLAttributes, 'loading' | 'decoding'> {
|
||||||
src: ImageMetadata | Promise<{ default: ImageMetadata }>;
|
src: ImageMetadata | Promise<{ default: ImageMetadata }>;
|
||||||
alt?: string;
|
alt?: string;
|
||||||
sizes: HTMLImageElement['sizes'];
|
sizes: HTMLImageElement['sizes'];
|
||||||
|
@ -10,7 +14,10 @@ export interface LocalImageProps extends Omit<PictureAttributes, 'src' | 'width'
|
||||||
formats?: OutputFormat[];
|
formats?: OutputFormat[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RemoteImageProps extends Omit<PictureAttributes, 'src' | 'width' | 'height'>, TransformOptions, Pick<ImageAttributes, 'loading' | 'decoding'> {
|
interface RemoteImageProps extends
|
||||||
|
Omit<HTMLAttributes, 'src' | 'width' | 'height'>,
|
||||||
|
TransformOptions,
|
||||||
|
Pick<ImgHTMLAttributes, 'loading' | 'decoding'> {
|
||||||
src: string;
|
src: string;
|
||||||
alt?: string;
|
alt?: string;
|
||||||
sizes: HTMLImageElement['sizes'];
|
sizes: HTMLImageElement['sizes'];
|
||||||
|
|
|
@ -1,2 +1,7 @@
|
||||||
|
/// <reference types="astro/astro-jsx" />
|
||||||
export { default as Image } from './Image.astro';
|
export { default as Image } from './Image.astro';
|
||||||
export { default as Picture } from './Picture.astro';
|
export { default as Picture } from './Picture.astro';
|
||||||
|
|
||||||
|
// TODO: should these directives be removed from astroHTML.JSX?
|
||||||
|
export type ImgHTMLAttributes = Omit<astroHTML.JSX.ImgHTMLAttributes, 'client:list' | 'set:text' | 'set:html' | 'is:raw'>;
|
||||||
|
export type HTMLAttributes = Omit<astroHTML.JSX.HTMLAttributes, 'client:list' | 'set:text' | 'set:html' | 'is:raw'>;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"description": "Load and transform images in your Astro site.",
|
"description": "Load and transform images in your Astro site.",
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"types": "./dist/types.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
"author": "withastro",
|
"author": "withastro",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -20,21 +20,18 @@
|
||||||
"bugs": "https://github.com/withastro/astro/issues",
|
"bugs": "https://github.com/withastro/astro/issues",
|
||||||
"homepage": "https://docs.astro.build/en/guides/integrations-guide/image/",
|
"homepage": "https://docs.astro.build/en/guides/integrations-guide/image/",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": "./dist/index.js",
|
||||||
"astro": "./components/index.js",
|
|
||||||
"import": "./dist/index.js"
|
|
||||||
},
|
|
||||||
"./sharp": "./dist/loaders/sharp.js",
|
"./sharp": "./dist/loaders/sharp.js",
|
||||||
"./endpoints/dev": "./dist/endpoints/dev.js",
|
"./endpoints/dev": "./dist/endpoints/dev.js",
|
||||||
"./endpoints/prod": "./dist/endpoints/prod.js",
|
"./endpoints/prod": "./dist/endpoints/prod.js",
|
||||||
"./components": "./components/index.js",
|
"./components": "./components/index.js",
|
||||||
"./package.json": "./package.json"
|
"./package.json": "./package.json",
|
||||||
|
"./client": "./client.d.ts"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"components",
|
"components",
|
||||||
"dist",
|
"dist",
|
||||||
"src",
|
"client.d.ts"
|
||||||
"types"
|
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
|
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
|
||||||
|
|
|
@ -2,7 +2,7 @@ import fs from 'node:fs/promises';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
import { OUTPUT_DIR } from '../constants.js';
|
import { OUTPUT_DIR } from '../constants.js';
|
||||||
import type { SSRImageService, TransformOptions } from '../types.js';
|
import type { SSRImageService, TransformOptions } from '../loaders/index.js';
|
||||||
import { isRemoteImage, loadLocalImage, loadRemoteImage } from '../utils/images.js';
|
import { isRemoteImage, loadLocalImage, loadRemoteImage } from '../utils/images.js';
|
||||||
import { ensureDir } from '../utils/paths.js';
|
import { ensureDir } from '../utils/paths.js';
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,116 @@
|
||||||
import integration from './integration.js';
|
import type { AstroConfig, AstroIntegration } from 'astro';
|
||||||
export * from './lib/get-image.js';
|
import { ssgBuild } from './build/ssg.js';
|
||||||
export * from './lib/get-picture.js';
|
import { ssrBuild } from './build/ssr.js';
|
||||||
|
import { PKG_NAME, ROUTE_PATTERN } from './constants.js';
|
||||||
|
import { ImageService, TransformOptions } from './loaders/index.js';
|
||||||
|
import { filenameFormat, propsToFilename } from './utils/paths.js';
|
||||||
|
import { createPlugin } from './vite-plugin-astro-image.js';
|
||||||
|
|
||||||
export default integration;
|
export { getImage } from './lib/get-image.js';
|
||||||
|
export { getPicture } from './lib/get-picture.js';
|
||||||
|
export * from './loaders/index.js';
|
||||||
|
export type { ImageMetadata} from './vite-plugin-astro-image.js';
|
||||||
|
|
||||||
|
interface ImageIntegration {
|
||||||
|
loader?: ImageService;
|
||||||
|
addStaticImage?: (transform: TransformOptions) => void;
|
||||||
|
filenameFormat?: (transform: TransformOptions, searchParams: URLSearchParams) => string;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
// eslint-disable-next-line no-var
|
||||||
|
var astroImage: ImageIntegration | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IntegrationOptions {
|
||||||
|
/**
|
||||||
|
* Entry point for the @type {HostedImageService} or @type {LocalImageService} to be used.
|
||||||
|
*/
|
||||||
|
serviceEntryPoint?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function integration(options: IntegrationOptions = {}): AstroIntegration {
|
||||||
|
const resolvedOptions = {
|
||||||
|
serviceEntryPoint: '@astrojs/image/sharp',
|
||||||
|
...options,
|
||||||
|
};
|
||||||
|
|
||||||
|
// During SSG builds, this is used to track all transformed images required.
|
||||||
|
const staticImages = new Map<string, Map<string, TransformOptions>>();
|
||||||
|
|
||||||
|
let _config: AstroConfig;
|
||||||
|
let output: 'server' | 'static';
|
||||||
|
|
||||||
|
function getViteConfiguration() {
|
||||||
|
return {
|
||||||
|
plugins: [createPlugin(_config, resolvedOptions)],
|
||||||
|
optimizeDeps: {
|
||||||
|
include: ['image-size', 'sharp'],
|
||||||
|
},
|
||||||
|
ssr: {
|
||||||
|
noExternal: ['@astrojs/image', resolvedOptions.serviceEntryPoint],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: PKG_NAME,
|
||||||
|
hooks: {
|
||||||
|
'astro:config:setup': ({ command, config, injectRoute, updateConfig }) => {
|
||||||
|
_config = config;
|
||||||
|
|
||||||
|
// Always treat `astro dev` as SSR mode, even without an adapter
|
||||||
|
output = command === 'dev' ? 'server' : config.output;
|
||||||
|
|
||||||
|
updateConfig({ vite: getViteConfiguration() });
|
||||||
|
|
||||||
|
if (output === 'server') {
|
||||||
|
injectRoute({
|
||||||
|
pattern: ROUTE_PATTERN,
|
||||||
|
entryPoint:
|
||||||
|
command === 'dev' ? '@astrojs/image/endpoints/dev' : '@astrojs/image/endpoints/prod',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'astro:server:setup': async () => {
|
||||||
|
globalThis.astroImage = {};
|
||||||
|
},
|
||||||
|
'astro:build:setup': () => {
|
||||||
|
// Used to cache all images rendered to HTML
|
||||||
|
// Added to globalThis to share the same map in Node and Vite
|
||||||
|
function addStaticImage(transform: TransformOptions) {
|
||||||
|
const srcTranforms = staticImages.has(transform.src)
|
||||||
|
? staticImages.get(transform.src)!
|
||||||
|
: new Map<string, TransformOptions>();
|
||||||
|
|
||||||
|
srcTranforms.set(propsToFilename(transform), transform);
|
||||||
|
|
||||||
|
staticImages.set(transform.src, srcTranforms);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helpers for building static images should only be available for SSG
|
||||||
|
globalThis.astroImage =
|
||||||
|
output === 'static'
|
||||||
|
? {
|
||||||
|
addStaticImage,
|
||||||
|
filenameFormat,
|
||||||
|
}
|
||||||
|
: {};
|
||||||
|
},
|
||||||
|
'astro:build:done': async ({ dir }) => {
|
||||||
|
if (output === 'server') {
|
||||||
|
// for SSR builds, copy all image files from src to dist
|
||||||
|
// to make sure they are available for use in production
|
||||||
|
await ssrBuild({ srcDir: _config.srcDir, outDir: dir });
|
||||||
|
} else {
|
||||||
|
// for SSG builds, build all requested image transforms to dist
|
||||||
|
const loader = globalThis?.astroImage?.loader;
|
||||||
|
|
||||||
|
if (loader && 'transform' in loader && staticImages.size > 0) {
|
||||||
|
await ssgBuild({ loader, staticImages, srcDir: _config.srcDir, outDir: dir });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -1,93 +0,0 @@
|
||||||
import type { AstroConfig, AstroIntegration } from 'astro';
|
|
||||||
import { ssgBuild } from './build/ssg.js';
|
|
||||||
import { ssrBuild } from './build/ssr.js';
|
|
||||||
import { PKG_NAME, ROUTE_PATTERN } from './constants.js';
|
|
||||||
import { IntegrationOptions, TransformOptions } from './types.js';
|
|
||||||
import { filenameFormat, propsToFilename } from './utils/paths.js';
|
|
||||||
import { createPlugin } from './vite-plugin-astro-image.js';
|
|
||||||
|
|
||||||
export default function integration(options: IntegrationOptions = {}): AstroIntegration {
|
|
||||||
const resolvedOptions = {
|
|
||||||
serviceEntryPoint: '@astrojs/image/sharp',
|
|
||||||
...options,
|
|
||||||
};
|
|
||||||
|
|
||||||
// During SSG builds, this is used to track all transformed images required.
|
|
||||||
const staticImages = new Map<string, Map<string, TransformOptions>>();
|
|
||||||
|
|
||||||
let _config: AstroConfig;
|
|
||||||
let output: 'server' | 'static';
|
|
||||||
|
|
||||||
function getViteConfiguration() {
|
|
||||||
return {
|
|
||||||
plugins: [createPlugin(_config, resolvedOptions)],
|
|
||||||
optimizeDeps: {
|
|
||||||
include: ['image-size', 'sharp'],
|
|
||||||
},
|
|
||||||
ssr: {
|
|
||||||
noExternal: ['@astrojs/image', resolvedOptions.serviceEntryPoint],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
name: PKG_NAME,
|
|
||||||
hooks: {
|
|
||||||
'astro:config:setup': ({ command, config, injectRoute, updateConfig }) => {
|
|
||||||
_config = config;
|
|
||||||
|
|
||||||
// Always treat `astro dev` as SSR mode, even without an adapter
|
|
||||||
output = command === 'dev' ? 'server' : config.output;
|
|
||||||
|
|
||||||
updateConfig({ vite: getViteConfiguration() });
|
|
||||||
|
|
||||||
if (output === 'server') {
|
|
||||||
injectRoute({
|
|
||||||
pattern: ROUTE_PATTERN,
|
|
||||||
entryPoint:
|
|
||||||
command === 'dev' ? '@astrojs/image/endpoints/dev' : '@astrojs/image/endpoints/prod',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'astro:server:setup': async () => {
|
|
||||||
globalThis.astroImage = {};
|
|
||||||
},
|
|
||||||
'astro:build:setup': () => {
|
|
||||||
// Used to cache all images rendered to HTML
|
|
||||||
// Added to globalThis to share the same map in Node and Vite
|
|
||||||
function addStaticImage(transform: TransformOptions) {
|
|
||||||
const srcTranforms = staticImages.has(transform.src)
|
|
||||||
? staticImages.get(transform.src)!
|
|
||||||
: new Map<string, TransformOptions>();
|
|
||||||
|
|
||||||
srcTranforms.set(propsToFilename(transform), transform);
|
|
||||||
|
|
||||||
staticImages.set(transform.src, srcTranforms);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helpers for building static images should only be available for SSG
|
|
||||||
globalThis.astroImage =
|
|
||||||
output === 'static'
|
|
||||||
? {
|
|
||||||
addStaticImage,
|
|
||||||
filenameFormat,
|
|
||||||
}
|
|
||||||
: {};
|
|
||||||
},
|
|
||||||
'astro:build:done': async ({ dir }) => {
|
|
||||||
if (output === 'server') {
|
|
||||||
// for SSR builds, copy all image files from src to dist
|
|
||||||
// to make sure they are available for use in production
|
|
||||||
await ssrBuild({ srcDir: _config.srcDir, outDir: dir });
|
|
||||||
} else {
|
|
||||||
// for SSG builds, build all requested image transforms to dist
|
|
||||||
const loader = globalThis?.astroImage?.loader;
|
|
||||||
|
|
||||||
if (loader && 'transform' in loader && staticImages.size > 0) {
|
|
||||||
await ssgBuild({ loader, staticImages, srcDir: _config.srcDir, outDir: dir });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,15 +1,15 @@
|
||||||
|
/// <reference types="astro/astro-jsx" />
|
||||||
import slash from 'slash';
|
import slash from 'slash';
|
||||||
import { ROUTE_PATTERN } from '../constants.js';
|
import { ROUTE_PATTERN } from '../constants.js';
|
||||||
import sharp from '../loaders/sharp.js';
|
import sharp from '../loaders/sharp.js';
|
||||||
import {
|
import {
|
||||||
ImageAttributes,
|
|
||||||
ImageMetadata,
|
|
||||||
ImageService,
|
ImageService,
|
||||||
isSSRService,
|
isSSRService,
|
||||||
OutputFormat,
|
OutputFormat,
|
||||||
TransformOptions,
|
TransformOptions,
|
||||||
} from '../types.js';
|
} from '../loaders/index.js';
|
||||||
import { isRemoteImage, parseAspectRatio } from '../utils/images.js';
|
import { isRemoteImage, parseAspectRatio } from '../utils/images.js';
|
||||||
|
import { ImageMetadata } from '../vite-plugin-astro-image.js';
|
||||||
|
|
||||||
export interface GetImageTransform extends Omit<TransformOptions, 'src'> {
|
export interface GetImageTransform extends Omit<TransformOptions, 'src'> {
|
||||||
src: string | ImageMetadata | Promise<{ default: ImageMetadata }>;
|
src: string | ImageMetadata | Promise<{ default: ImageMetadata }>;
|
||||||
|
@ -101,7 +101,7 @@ async function resolveTransform(input: GetImageTransform): Promise<TransformOpti
|
||||||
* @param transform @type {TransformOptions} The transformations requested for the optimized image.
|
* @param transform @type {TransformOptions} The transformations requested for the optimized image.
|
||||||
* @returns @type {ImageAttributes} The HTML attributes to be included on the built `<img />` element.
|
* @returns @type {ImageAttributes} The HTML attributes to be included on the built `<img />` element.
|
||||||
*/
|
*/
|
||||||
export async function getImage(transform: GetImageTransform): Promise<ImageAttributes> {
|
export async function getImage(transform: GetImageTransform): Promise<astroHTML.JSX.ImgHTMLAttributes> {
|
||||||
if (!transform.src) {
|
if (!transform.src) {
|
||||||
throw new Error('[@astrojs/image] `src` is required');
|
throw new Error('[@astrojs/image] `src` is required');
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
|
/// <reference types="astro/astro-jsx" />
|
||||||
import { lookup } from 'mrmime';
|
import { lookup } from 'mrmime';
|
||||||
import { extname } from 'node:path';
|
import { extname } from 'node:path';
|
||||||
import { ImageAttributes, ImageMetadata, OutputFormat, TransformOptions } from '../types.js';
|
import { OutputFormat, TransformOptions } from '../loaders/index.js';
|
||||||
import { parseAspectRatio } from '../utils/images.js';
|
import { parseAspectRatio } from '../utils/images.js';
|
||||||
|
import { ImageMetadata } from '../vite-plugin-astro-image.js';
|
||||||
import { getImage } from './get-image.js';
|
import { getImage } from './get-image.js';
|
||||||
|
|
||||||
export interface GetPictureParams {
|
export interface GetPictureParams {
|
||||||
|
@ -12,7 +14,7 @@ export interface GetPictureParams {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GetPictureResult {
|
export interface GetPictureResult {
|
||||||
image: ImageAttributes;
|
image: astroHTML.JSX.HTMLAttributes;
|
||||||
sources: { type: string; srcset: string }[];
|
sources: { type: string; srcset: string }[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,4 @@
|
||||||
/// <reference types="astro/astro-jsx" />
|
/// <reference types="astro/astro-jsx" />
|
||||||
export * from './index.js';
|
|
||||||
|
|
||||||
interface ImageIntegration {
|
|
||||||
loader?: ImageService;
|
|
||||||
addStaticImage?: (transform: TransformOptions) => void;
|
|
||||||
filenameFormat?: (transform: TransformOptions, searchParams: URLSearchParams) => string;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
// eslint-disable-next-line no-var
|
|
||||||
var astroImage: ImageIntegration | undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type InputFormat =
|
export type InputFormat =
|
||||||
| 'heic'
|
| 'heic'
|
||||||
| 'heif'
|
| 'heif'
|
||||||
|
@ -25,21 +12,6 @@ export type InputFormat =
|
||||||
|
|
||||||
export type OutputFormat = 'avif' | 'jpeg' | 'png' | 'webp';
|
export type OutputFormat = 'avif' | 'jpeg' | 'png' | 'webp';
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a set of image transforms to the filename to use when building for static.
|
|
||||||
*
|
|
||||||
* This is only used for static production builds and ignored when an SSR adapter is used,
|
|
||||||
* or in `astro dev` for static builds.
|
|
||||||
*/
|
|
||||||
export type FilenameFormatter = (transform: TransformOptions) => string;
|
|
||||||
|
|
||||||
export interface IntegrationOptions {
|
|
||||||
/**
|
|
||||||
* Entry point for the @type {HostedImageService} or @type {LocalImageService} to be used.
|
|
||||||
*/
|
|
||||||
serviceEntryPoint?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the original image and transforms that need to be applied to it.
|
* Defines the original image and transforms that need to be applied to it.
|
||||||
*/
|
*/
|
||||||
|
@ -83,22 +55,19 @@ export interface TransformOptions {
|
||||||
aspectRatio?: number | `${number}:${number}`;
|
aspectRatio?: number | `${number}:${number}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ImageAttributes = astroHTML.JSX.ImgHTMLAttributes;
|
|
||||||
export type PictureAttributes = astroHTML.JSX.HTMLAttributes;
|
|
||||||
|
|
||||||
export interface HostedImageService<T extends TransformOptions = TransformOptions> {
|
export interface HostedImageService<T extends TransformOptions = TransformOptions> {
|
||||||
/**
|
/**
|
||||||
* Gets the HTML attributes needed for the server rendered `<img />` element.
|
* Gets the HTML attributes needed for the server rendered `<img />` element.
|
||||||
*/
|
*/
|
||||||
getImageAttributes(transform: T): Promise<ImageAttributes>;
|
getImageAttributes(transform: T): Promise<astroHTML.JSX.ImgHTMLAttributes>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SSRImageService<T extends TransformOptions = TransformOptions>
|
export interface SSRImageService<T extends TransformOptions = TransformOptions>
|
||||||
extends HostedImageService<T> {
|
extends HostedImageService<T> {
|
||||||
/**
|
/**
|
||||||
* Gets tthe HTML attributes needed for the server rendered `<img />` element.
|
* Gets the HTML attributes needed for the server rendered `<img />` element.
|
||||||
*/
|
*/
|
||||||
getImageAttributes(transform: T): Promise<Exclude<ImageAttributes, 'src'>>;
|
getImageAttributes(transform: T): Promise<Exclude<astroHTML.JSX.ImgHTMLAttributes, 'src'>>;
|
||||||
/**
|
/**
|
||||||
* Serializes image transformation properties to URLSearchParams, used to build
|
* Serializes image transformation properties to URLSearchParams, used to build
|
||||||
* the final `src` that points to the self-hosted SSR endpoint.
|
* the final `src` that points to the self-hosted SSR endpoint.
|
||||||
|
@ -134,10 +103,3 @@ export function isHostedService(service: ImageService): service is ImageService
|
||||||
export function isSSRService(service: ImageService): service is SSRImageService {
|
export function isSSRService(service: ImageService): service is SSRImageService {
|
||||||
return 'transform' in service;
|
return 'transform' in service;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ImageMetadata {
|
|
||||||
src: string;
|
|
||||||
width: number;
|
|
||||||
height: number;
|
|
||||||
format: InputFormat;
|
|
||||||
}
|
|
|
@ -1,5 +1,5 @@
|
||||||
import sharp from 'sharp';
|
import sharp from 'sharp';
|
||||||
import type { OutputFormat, SSRImageService, TransformOptions } from '../types.js';
|
import type { OutputFormat, SSRImageService, TransformOptions } from './index.js';
|
||||||
import { isAspectRatioString, isOutputFormat } from '../utils/images.js';
|
import { isAspectRatioString, isOutputFormat } from '../utils/images.js';
|
||||||
|
|
||||||
class SharpService implements SSRImageService {
|
class SharpService implements SSRImageService {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import fs from 'node:fs/promises';
|
import fs from 'node:fs/promises';
|
||||||
import type { OutputFormat, TransformOptions } from '../types.js';
|
import type { OutputFormat, TransformOptions } from '../loaders/index.js';
|
||||||
|
|
||||||
export function isOutputFormat(value: string): value is OutputFormat {
|
export function isOutputFormat(value: string): value is OutputFormat {
|
||||||
return ['avif', 'jpeg', 'png', 'webp'].includes(value);
|
return ['avif', 'jpeg', 'png', 'webp'].includes(value);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import sizeOf from 'image-size';
|
import sizeOf from 'image-size';
|
||||||
import fs from 'node:fs/promises';
|
import fs from 'node:fs/promises';
|
||||||
import { ImageMetadata, InputFormat } from '../types.js';
|
import { InputFormat } from '../loaders/index.js';
|
||||||
|
import { ImageMetadata } from '../vite-plugin-astro-image.js';
|
||||||
|
|
||||||
export async function metadata(src: string): Promise<ImageMetadata | undefined> {
|
export async function metadata(src: string): Promise<ImageMetadata | undefined> {
|
||||||
const file = await fs.readFile(src);
|
const file = await fs.readFile(src);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import { OUTPUT_DIR } from '../constants.js';
|
import { OUTPUT_DIR } from '../constants.js';
|
||||||
import type { TransformOptions } from '../types.js';
|
import type { TransformOptions } from '../loaders/index.js';
|
||||||
import { isRemoteImage } from './images.js';
|
import { isRemoteImage } from './images.js';
|
||||||
import { shorthash } from './shorthash.js';
|
import { shorthash } from './shorthash.js';
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,17 @@ import { pathToFileURL } from 'node:url';
|
||||||
import type { PluginContext } from 'rollup';
|
import type { PluginContext } from 'rollup';
|
||||||
import slash from 'slash';
|
import slash from 'slash';
|
||||||
import type { Plugin, ResolvedConfig } from 'vite';
|
import type { Plugin, ResolvedConfig } from 'vite';
|
||||||
import type { IntegrationOptions } from './types.js';
|
import type { IntegrationOptions } from './index.js';
|
||||||
|
import type { InputFormat } from './loaders/index.js';
|
||||||
import { metadata } from './utils/metadata.js';
|
import { metadata } from './utils/metadata.js';
|
||||||
|
|
||||||
|
export interface ImageMetadata {
|
||||||
|
src: string;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
format: InputFormat;
|
||||||
|
}
|
||||||
|
|
||||||
export function createPlugin(config: AstroConfig, options: Required<IntegrationOptions>): Plugin {
|
export function createPlugin(config: AstroConfig, options: Required<IntegrationOptions>): Plugin {
|
||||||
const filter = (id: string) =>
|
const filter = (id: string) =>
|
||||||
/^(?!\/_image?).*.(heic|heif|avif|jpeg|jpg|png|tiff|webp|gif)$/.test(id);
|
/^(?!\/_image?).*.(heic|heif|avif|jpeg|jpg|png|tiff|webp|gif)$/.test(id);
|
||||||
|
|
Loading…
Reference in a new issue