diff --git a/docs/content/en/providers/local.md b/docs/content/en/providers/local.md index 13c58b15c..3eeb058ed 100644 --- a/docs/content/en/providers/local.md +++ b/docs/content/en/providers/local.md @@ -17,10 +17,6 @@ Internally nuxt image uses [ipx](https://github.com/nuxt-contrib/ipx) to modify export default { image: { local: { - /** - * Input directory for images - **/ - dir: '~/static', /** * Cache directory for optimized images **/ diff --git a/package.json b/package.json index d05f39764..6d9467ac1 100755 --- a/package.json +++ b/package.json @@ -25,8 +25,10 @@ "defu": "^3.2.2", "hasha": "^5.2.2", "image-meta": "^0.0.1", - "ipx": "^0.4.1", + "ipx": "^0.4.2", + "is-https": "^2.0.2", "node-fetch": "^2.6.1", + "requrl": "^2.0.1", "upath": "^2.0.1" }, "devDependencies": { diff --git a/playground/assets/nuxt-white.svg b/playground/assets/nuxt-white.svg new file mode 100644 index 000000000..d3dff8425 --- /dev/null +++ b/playground/assets/nuxt-white.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/playground/pages/index.vue b/playground/pages/index.vue index dd9e88450..1eebf850c 100644 --- a/playground/pages/index.vue +++ b/playground/pages/index.vue @@ -2,7 +2,7 @@

SVG image inside project

- +

SVG image from remote url

diff --git a/src/index.ts b/src/index.ts index c0e84aedb..44d20365c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,7 @@ import path from 'path' import fs from 'fs-extra' import { ModuleOptions } from 'types' +import defu from 'defu' import { downloadImage, getFileExtension, getProviders, hash } from './utils' import { cleanDoubleSlashes } from './runtime/utils' export type { Provider, RuntimeProvider } from 'types' @@ -57,6 +58,15 @@ async function imageModule (moduleOptions: ModuleOptions) { nuxt.options.alias['~image'] = runtimeDir nuxt.options.build.transpile.push(runtimeDir) + nuxt.options.build.loaders = defu({ + vue: { + transformAssetUrls: { + 'nuxt-img': 'src', + 'nuxt-picture': 'src' + } + } + }, nuxt.options.build.loaders || {}) + nuxt.hook('generate:before', () => { handleStaticGeneration(nuxt, options) }) diff --git a/src/providers/local/index.ts b/src/providers/local/index.ts index b645d0213..f263f1e9a 100644 --- a/src/providers/local/index.ts +++ b/src/providers/local/index.ts @@ -1,4 +1,7 @@ +import { ServerResponse, IncomingMessage } from 'http' import { ProviderFactory } from 'types' +import isHttps from 'is-https' +import requrl from 'requrl' export default function (providerOptions) { return { @@ -15,11 +18,6 @@ function createMiddleware (options) { const ipx = new IPX({ inputs: [ - { - name: 'local', - adapter: 'fs', - dir: options.dir - }, { name: 'remote', adapter: 'remote', @@ -32,5 +30,19 @@ function createMiddleware (options) { }, sharp: options.sharp }) - return IPXMiddleware(ipx) + const ipxMiddleware = IPXMiddleware(ipx) + + return (req: IncomingMessage, res: ServerResponse) => { + const host = new URL(requrl(req)).host + const url = req.url || '/' + const urlArgs = url.substr(1).split('/') + const adapter = decodeURIComponent(urlArgs.shift() || '') + const format = decodeURIComponent(urlArgs.shift() || '') + const operations = decodeURIComponent(urlArgs.shift() || '') + const src = urlArgs.map(c => decodeURIComponent(c)).join('/') + if (adapter === 'remote' && !src.startsWith('http')) { + req.url = `/${adapter}/${format}/${operations}/http${isHttps(req) ? 's' : ''}://${host}/${src}` + } + return ipxMiddleware(req, res) + } } diff --git a/src/providers/local/runtime.ts b/src/providers/local/runtime.ts index bf0feb685..7825d6c38 100644 --- a/src/providers/local/runtime.ts +++ b/src/providers/local/runtime.ts @@ -1,14 +1,8 @@ import { RuntimeProvider, ImageModifiers } from 'types' - -function predictAdapter (src: string) { - if (src.match(/^https?:\/\//)) { - return 'remote' - } - return 'local' -} +import { isRemoteUrl } from '~image/utils' export default { - getImage (src: string, modifiers: ImageModifiers, _options: any) { + getImage (src: string, modifiers: ImageModifiers, options: any) { const operations = [] const fit = modifiers.fit ? `_${modifiers.fit}` : '' @@ -23,13 +17,13 @@ export default { operations.push(`q_${modifiers.quality}`) } - const adapter = predictAdapter(src) + src = isRemoteUrl(src) ? src : (options.baseURL || '') + src const operationsString = operations.join(',') || '_' return { - url: `/_image/local/${adapter}/${modifiers.format || '_'}/${operationsString}/${src}`, - isStatic: true + url: `/_image/local/remote/${modifiers.format || '_'}/${operationsString}/${src}`, + static: true } } } diff --git a/src/runtime/image.ts b/src/runtime/image.ts index 3aa970150..f7a1f4cff 100644 --- a/src/runtime/image.ts +++ b/src/runtime/image.ts @@ -78,7 +78,7 @@ export function createImage (context, { providers, defaultProvider, presets, int const image = provider.provider.getImage( src, - defu(modifiers, preset.modifiers), + defu(modifiers, (preset && preset.modifiers) || {}), { ...provider.defaults, ...options } ) diff --git a/src/utils.ts b/src/utils.ts index 0ca7c3669..25a1aaf43 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -56,38 +56,12 @@ export async function getProviders (nuxt, options: ModuleOptions): Promise