Nuxt.jsでdata-src='~assets/lemon-sour.png'をrequire変換する方法
事の発端は、 Nuxt.js で vue-lazyload を試しに使ってみようと思ったら割とハマったのでメモ。
vue-lazyload
hilongjw/vue-lazyload: A Vue.js plugin for lazyload your Image or Component in your application.
また、 NuxtにLazyLoadを入れてみた - okadak1990’s blog こちらの記事に大変助けられました。
Nuxt.js のプラグインを作ります
plugins/vue-lazyload.ts
import Vue from 'vue'
import VueLazyload from 'vue-lazyload'
Vue.use(VueLazyload, {
preLoad: 1.1,
attempt: 1,
observer: true,
observerOptions: {
rootMargin: '0px',
threshold: 0.1
}
})
Component を作ります
components/LazyImage.vue
<template lang="pug">
img(:alt="alt" v-lazy="src")
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'nuxt-property-decorator'
@Component
export default class LazyImage extends Vue {
@Prop()
src: string
@Prop()
alt: string
}
</script>
読み込む Page を作ります
pages/img-lazy-load.vue
<template lang="pug">
section
h1.title
| assets and static
div
h2 assets lazy-image
<lazy-image src='~assets/images/lemon-sour.medium.jpg' alt='alt'/>
</template>
<script lang="ts">
import { Component, Vue } from 'nuxt-property-decorator'
import LazyImage from '@/components/LazyImage.vue'
@Component({
components: {
LazyImage
}
})
export default class ImgLazyLoad extends Vue {}
</script>
wabpack で vue-loader の設定が必要だった
上記だけだと、 <lazy-load />
に src を渡す際に、 require で Nuxt.js の URL に変換されませんでした。
URL の変換とは、例えば、以下のような感じです。
<img src="~assets/images/lemon-sour.medium.jpg">
↓
<img src="require('~assets/images/lemon-sour.medium.jpg')">
↓
<img src="/_nuxt/src/assets/images/lemon-sour.medium.jpg">
苦戦してる方はそこそこいるが・・・
nuxt.confit.js
以下のように書かれている記事が多いが、これは vue-load のバージョンが v14.x 系でしかうごかない。
build: {
extend(config: Configuration, ctx: Context) {
const vueLoader = config.module!.rules.find((rule) => rule.loader === 'vue-loader')
vueLoader.options.transformToRequire['lazy-image'] = ['src']
}
}
vue-loaderでsourceのsrcsetで指定したファイルも自動でrequireする - Qiita
Nuxt.jsで src="~assets/hoge.jpg" が変換されなくて困った - Qiita
Nuxt.jsでassetsをCDNから配信する - 豆腐とコンソメ
data-src doesn’t load images from assets folder · Issue #2650 · nuxt/nuxt.js · GitHub
import .mp3 file from assets · Issue #3756 · nuxt/nuxt.js · GitHub
Assets path resolution not working for tags different than · Issue #956 · nuxt/nuxt.js
いまは、 v15.x 系なので、書き方が変わっていた。
v14 のオプション
transformToRequire
v15 のオプション
transformAssetUrls
v15 を考慮した nuxt.config.ts
build: {
extend(config: Configuration, ctx: Context) {
const vueLoader = config.module!.rules.find((rule) => rule.loader === 'vue-loader')
vueLoader.options.transformAssetUrls = {
'lazy-image': 'src'
}
}
}
あとがき
Nuxt.js というか webpack というか vue-loader の話でしたが、いやー、これはハマりました。
console.log で options を出力して初めて中身の違和感に気づきました。
今後、この手のものは後方互換がない前提で実装していったほうがよさそうですね。
ではでは。