Nuxt dynamic asset not loading

Viewed 2741

I'm trying to load dynamic assets in nuxt. I followed all the advice saying one should use require but I can't get it to work.

With this in my template,

<v-img  :src="mimeTypeUrl()"></v-img>

the following results in Error: "Cannot find module '~/assets/media/application-vnd-google-earth-kmz.png'"

methods: {
    mimeTypeUrl() {
      const f = '~/assets/media/application-vnd-google-earth-kmz.png';
      return require(f);
    }
  }

but this works fine:

methods: {
    mimeTypeUrl() {
      return require('~/assets/media/application-vnd-google-earth-kmz.png');
    }
  }

What's the problem here and how can I solve this?

@nuxt/core version: 2.11.0

webpack version: 4.41.6

2 Answers

This is always a tricky situation. In your case, you can solve this by aliasing the f to the icon name, and using it in place, concatenated, within the path:

mimeTypeUrl(icon) {
  return require(`~/assets/media/${icon}`);
}

And then calling it with the icon as an argument:

:src="mimeTypeUrl('application-vnd-google-earth-kmz.png')"

This works because webpack will create an entire context for your /assets/media directory, which will contain your image file.

Not Recommended

You may be able to actually trick webpack by creating a context for your entire project by prepending your path with an empty string

mimeTypeUrl(icon) {
  return require('' + '~/assets/media/application-vnd-google-earth-kmz.png');
}

This is not desired because it will create context for your entire application structure which will increase the bundle size by a measurable amount. It may also have unintended consequences by polluting the global context and making it so aliases resolve incorrectly if there is a collision in the naming of files and or classes.

Though ugly, a work-around I found is to create an object with icon names as keys and require() as values:

const MIME_ICONS_REQUIRE = {
  ...
  'application-msword':require('~/assets/media/mimetypes/application-msword.png'),
  'application-pdf':require('~/assets/media/mimetypes/application-pdf.png'),
  'application-vnd-google-earth-kml':require('~/assets/media/mimetypes/application-vnd-google-earth-kml.png'),
  ...
}

Related