nuxt / image

Plug-and-play image optimization for Nuxt applications.
https://image.nuxt.com
MIT License
1.34k stars 270 forks source link

Generate adds double slashes when using build.publicPath with domain #463

Open KStenK opened 2 years ago

KStenK commented 2 years ago

Hello,

We are using the Images module to convert static images to Webp format. We want to serve static files from other domain, so as I understand that we need to change build.publicPath to serve all static files from other domain.

Here are our settings:

// packages.json

"dependencies": {
  "@nuxtjs/i18n": "^7.2.0",
  "@nuxtjs/sentry": "^5.1.6",
  "core-js": "^3.17.1",
  "nuxt": "^2.15.8"
},
"devDependencies": {
  "@mdi/js": "^6.4.95",
  "@nuxt/image": "^0.6.0",
  "@nuxt/types": "^2.15.8",
  "@nuxtjs/pwa": "^3.3.5",
  "@nuxtjs/vuetify": "^1.12.1",
  "@vue/test-utils": "^1.2.1",
  "babel-core": "7.0.0-bridge.0",
  "babel-jest": "^27.0.5",
  "jest": "^27.0.5",
  "nuxt-purgecss": "^1.0.0",
  "vue-jest": "^3.0.4",
  "webpack": "^4.46.0"
}
// nuxt.config.js

ssr: true,

target: 'static',

. . .

buildModules: [
  '@nuxt/image',
],

. . .

image: {
  dir: 'assets/images'
},

. . .

build: {
  extractCSS: {
    ignoreOrder: true
  },
  publicPath: process.env.NODE_ENV === 'production' ? 'https://static.domain.com/_nuxt/' : '/_nuxt/'
}

Unfortunately, after the generate, I see a tag like this.

<img src="https://static.domain.com/_nuxt//image/4bf726.webp" width="187" height="80" loading="eager" sizes="600px" srcset="https://static.domain.com/_nuxt//image/4bf726.webp 600w" data-v-8380cc7e>

I'm pretty sure those double slashes (_nuxt//image) should not be there.

Without a domain (publicPath: '/some/random/path/'), there are no double slashes added and everything is correct.

Red-Asuka commented 2 years ago

I encountered the same problem, When I set the build.publicPath: https://static.domain.com and using the default staticFilename setting [publicPath]/image/[hash][ext] or other setting starting with [publicPath], it will generated contain double slashes. like this https://static.domain.com//image/e94057.png.

And then I checked code. Use the settings above, params.publicPath: '/', staticImages[url] will startWith double slashes, so just delete [publicPath], set staticFilename setting to /image/[name]-[hash][ext], It works fine. This doesn't match the example given in the documentation and I'm not sure if it's a bug or not.

nuxt.hook('vue-renderer:ssr:prepareContext', (renderContext: any) => {
    renderContext.image = renderContext.image || {}
    renderContext.image.mapToStatic = <MapToStatic> function ({ url, format }: ResolvedImage, input: string) {
      if (!staticImages[url]) {
        const { pathname } = parseURL(input)
        const params: any = {
          name: trimExt(basename(pathname)),
          ext: (format && `.${format}`) || guessExt(input),
          hash: hash(url),
          // TODO: pass from runtimeConfig to mapStatic as param
          publicPath: nuxt.options.app.cdnURL ? '/' : withoutTrailingSlash(nuxt.options.build.publicPath)
        }

        staticImages[url] = options.staticFilename.replace(/\[(\w+)]/g, (match, key) => params[key] || match)
      }
      return joinURL(nuxt.options.app.cdnURL || nuxt.options.app.basePath, staticImages[url])
    }
})