Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: do not inject $img by default #836

Merged
merged 8 commits into from
Jun 6, 2023
12 changes: 12 additions & 0 deletions docs/content/5.configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,18 @@ export default defineNuxtConfig({
})
```

## `inject`

By default Nuxt Image v1 adopts a composable approach. If you do not use the components no additional code will be added to your bundle. But if you wish to globally initialize an `$img` helper that will be available throughout your application, you can do so.

```ts [nuxt.config.ts]
export default defineNuxtConfig({
image: {
inject: true
}
})
```

## `screens`

List of predefined screen sizes.
Expand Down
1 change: 1 addition & 0 deletions playground/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { defineNuxtConfig } from 'nuxt/config'
export default defineNuxtConfig({
modules: ['@nuxt/image-edge'],
image: {
inject: true,
domains: [
'https://nuxtjs.org',
'https://images.unsplash.com',
Expand Down
15 changes: 11 additions & 4 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import { resolveProviders, detectProvider, resolveProvider } from './provider'
import type { ImageProviders, ImageOptions, InputProvider, CreateImageOptions } from './types'

export interface ModuleOptions extends ImageProviders {
staticFilename: string,
inject: boolean
staticFilename: string
provider: CreateImageOptions['provider']
presets: { [name: string]: ImageOptions }
dir: string
domains: string[]
sharp: any
alias: Record<string, string>
screens: CreateImageOptions['screens'],
screens: CreateImageOptions['screens']
internalUrl: string
providers: { [name: string]: InputProvider | any } & ImageProviders
[key: string]: any
Expand All @@ -22,6 +23,7 @@ export * from './types'

export default defineNuxtModule<ModuleOptions>({
defaults: nuxt => ({
inject: false,
staticFilename: '[publicPath]/image/[hash][ext]',
provider: 'auto',
dir: nuxt.options.dir.public,
Expand Down Expand Up @@ -139,8 +141,13 @@ ${providers.map(p => ` ['${p.name}']: { provider: ${p.importName}, defaults: ${
}
})

// Add runtime plugin
addPlugin({ src: resolver.resolve('./runtime/plugin') })
if (options.inject) {
// Add runtime plugin
addPlugin({ src: resolver.resolve('./runtime/plugin') })
} else if (nuxt.options.dev) {
// Add placeholder runtime plugin
addPlugin({ src: resolver.resolve('./runtime/plugin.placeholder') })
}

// TODO: Transform asset urls that pass to `src` attribute on image components
}
Expand Down
20 changes: 16 additions & 4 deletions src/runtime/composables.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
import { $Img } from '../types'
import { useNuxtApp } from '#imports'
import type { $Img } from '../types'

export const useImage = () => {
return useNuxtApp().$img as $Img
import { createImage } from './image'
// @ts-expect-error virtual file
import { imageOptions } from '#build/image-options'
import { useNuxtApp, useRuntimeConfig } from '#imports'

export const useImage = (): $Img => {
const config = useRuntimeConfig()
const nuxtApp = useNuxtApp()

return nuxtApp.$img as $Img || nuxtApp._img || (nuxtApp._img = createImage({
...imageOptions,
nuxt: {
baseURL: config.app.baseURL
}
}))
}
13 changes: 13 additions & 0 deletions src/runtime/plugin.placeholder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { defineNuxtPlugin } from '#imports'

export default defineNuxtPlugin((nuxtApp) => {
const $img = () => throwImgError()
$img.getImage = () => throwImgError()
$img.getSizes = () => throwImgError()
$img.getMeta = () => throwImgError()
nuxtApp.provide('img', $img)
})

function throwImgError () {
throw new Error('[nuxt] [image] `$img` global utility is not enabled. You can enable it by setting `image: { inject: true }` in `nuxt.config`.')
}
14 changes: 2 additions & 12 deletions src/runtime/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,11 @@
import type { Plugin } from 'nuxt/app'
import type { $Img } from '../types'
import { createImage } from '#image'
// @ts-ignore
import { imageOptions } from '#build/image-options'
import { defineNuxtPlugin, useRuntimeConfig } from '#imports'
import { defineNuxtPlugin, useImage } from '#imports'

export default defineNuxtPlugin(() => {
const config = useRuntimeConfig()
const img = createImage({
...imageOptions,
nuxt: {
baseURL: config.app.baseURL
}
})
return {
provide: {
img
img: useImage()
}
}
}) as Plugin<{ img: $Img }>
3 changes: 3 additions & 0 deletions test/e2e/generate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ await setup({
rootDir: fileURLToPath(new URL('../../playground', import.meta.url)),
build: true,
nuxtConfig: {
image: {
inject: false
},
hooks: {
'modules:before' () {
const nuxt = useNuxt()
Expand Down
1 change: 1 addition & 0 deletions test/e2e/no-ssr.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ await setup({
nuxtConfig: {
ssr: false,
image: {
inject: false,
provider: 'ipx'
}
}
Expand Down
1 change: 1 addition & 0 deletions test/e2e/ssr.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ await setup({
browser: true,
nuxtConfig: {
image: {
inject: false,
provider: 'ipx'
}
}
Expand Down