From 047d98ad878c47198f2ca61848c7d12ceac1f785 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Wed, 13 Sep 2023 23:01:43 +0100 Subject: [PATCH] feat: add `ipxStatic` provider (#878) --- docs/content/1.get-started/4.configuration.md | 8 ++++---- src/ipx.ts | 8 ++++---- src/module.ts | 16 ++++++++++------ src/provider.ts | 5 +++-- src/runtime/providers/ipxStatic.ts | 1 + test/unit/provider-coverage.test.ts | 1 + 6 files changed, 23 insertions(+), 16 deletions(-) create mode 100644 src/runtime/providers/ipxStatic.ts diff --git a/docs/content/1.get-started/4.configuration.md b/docs/content/1.get-started/4.configuration.md index e4883b53c..dbf87a7bc 100644 --- a/docs/content/1.get-started/4.configuration.md +++ b/docs/content/1.get-started/4.configuration.md @@ -144,7 +144,7 @@ export default defineNuxtConfig({ ## `provider` -Default: `static` +Default: `ipx` (or `ipxStatic` if used with a static nitro preset, such as if you are running `nuxt generate`) We can specify default provider to be used when not specified in component or when calling `$img`. @@ -198,7 +198,7 @@ export default defineNuxtConfig({ Default: `public` -This option allows you to specify the location of the source images when using the `static` or `ipx` provider. +This option allows you to specify the location of the source images when using the `ipx` or `ipxStatic` provider. For example you might want the source images in `assets/images` directory rather than the default `public` directory so the source images don't get copied into `dist` and deployed: @@ -211,9 +211,9 @@ export default defineNuxtConfig({ ``` **Notes:** -- For `static` provider, if images weren't crawled during generation (unreachable modals, pages or dynamic runtime size), changing `dir` from `static` causes 404 errors. +- For `ipxStatic` provider, if images weren't crawled during generation (unreachable modals, pages or dynamic runtime size), changing `dir` from `public` causes 404 errors. - For `ipx` provider, make sure to deploy customized `dir` as well. -- For some providers (like vercel), using a directory other than `static/` for assets is not supported since resizing happens at runtime (instead of build/generate time) and source fetched from the `static/` directory (deployment URL) +- For some providers (like vercel), using a directory other than `public/` for assets is not supported since resizing happens at runtime (instead of build/generate time) and source fetched from the `public/` directory (deployment URL) ## `alias` diff --git a/src/ipx.ts b/src/ipx.ts index a18daa416..7756a0cd8 100644 --- a/src/ipx.ts +++ b/src/ipx.ts @@ -13,7 +13,7 @@ interface IPXRuntimeConfig { alias: Record } -export const ipxSetup: ProviderSetup = async (providerOptions, moduleOptions) => { +export const ipxSetup: (setupOptions?: { isStatic: boolean }) => ProviderSetup = setupOptions => async (providerOptions, moduleOptions) => { const nitro = useNitro() const nuxt = useNuxt() @@ -51,7 +51,9 @@ export const ipxSetup: ProviderSetup = async (providerOptions, moduleOptions) => route: '/_ipx/**', handler: resolver.resolve('./runtime/ipx') } - nitro.options.handlers.push(handler) + if (!setupOptions?.isStatic) { + nitro.options.handlers.push(handler) + } // TODO: Workaround for prerender support nitro.options._config.handlers!.push(handler) return @@ -73,8 +75,6 @@ export const ipxSetup: ProviderSetup = async (providerOptions, moduleOptions) => }) } nitro.options.devHandlers.push(devHandler) - // TODO: Workaround for prerender support - nitro.options._config.devHandlers!.push(devHandler) } declare module 'nitropack' { diff --git a/src/module.ts b/src/module.ts index 6fa3af765..b497bbba8 100644 --- a/src/module.ts +++ b/src/module.ts @@ -88,7 +88,7 @@ export default defineNuxtModule({ // Run setup for (const p of providers) { - if (typeof p.setup === 'function' && p.name !== 'ipx') { + if (typeof p.setup === 'function' && p.name !== 'ipx' && p.name !== 'ipxStatic') { await p.setup(p, options, nuxt) } } @@ -131,12 +131,16 @@ ${providers.map(p => ` ['${p.name}']: { provider: ${p.importName}, defaults: ${ }) nuxt.hook('nitro:init', async (nitro) => { - if (!options.provider || options.provider === 'ipx') { - imageOptions.provider = options.provider = nitro.options.node ? 'ipx' : 'none' - options[options.provider] = options[options.provider] || {} + if (!options.provider || options.provider === 'ipx' || options.provider === 'ipxStatic') { + const resolvedProvider = nitro.options.static || options.provider === 'ipxStatic' + ? 'ipxStatic' + : nitro.options.node ? 'ipx' : 'none' - const p = await resolveProvider(nuxt, options.provider, options[options.provider]) - if (!providers.some(p => p.name === options.provider)) { + imageOptions.provider = options.provider = resolvedProvider + options[resolvedProvider] = options[resolvedProvider] || {} + + const p = await resolveProvider(nuxt, resolvedProvider, options[resolvedProvider]) + if (!providers.some(p => p.name === resolvedProvider)) { providers.push(p) } if (typeof p.setup === 'function') { diff --git a/src/provider.ts b/src/provider.ts index 9de485b9e..5c228e99a 100644 --- a/src/provider.ts +++ b/src/provider.ts @@ -24,6 +24,7 @@ const BuiltInProviders = [ 'imagekit', 'imgix', 'ipx', + 'ipxStatic', 'layer0', 'netlify', 'prepr', @@ -41,8 +42,8 @@ const BuiltInProviders = [ export const providerSetup: Record = { // IPX - ipx: ipxSetup, - static: ipxSetup, + ipx: ipxSetup(), + ipxStatic: ipxSetup({ isStatic: true }), // https://vercel.com/docs/more/adding-your-framework#images vercel (_providerOptions, moduleOptions, nuxt: Nuxt) { diff --git a/src/runtime/providers/ipxStatic.ts b/src/runtime/providers/ipxStatic.ts new file mode 100644 index 000000000..c1eab0d6a --- /dev/null +++ b/src/runtime/providers/ipxStatic.ts @@ -0,0 +1 @@ +export * from './ipx' diff --git a/test/unit/provider-coverage.test.ts b/test/unit/provider-coverage.test.ts index 1b3041d35..f3b1b4ca4 100644 --- a/test/unit/provider-coverage.test.ts +++ b/test/unit/provider-coverage.test.ts @@ -5,6 +5,7 @@ import { images } from '../providers' import { providers as playgroundProviders } from '../../playground/providers' const missingProviderTests = [ + 'ipxStatic', // build-time-only alias for ipx 'strapi', // covered in a unique test 'layer0' // backwards-compatible alias for edgio ]