AMDP
AMDP

Reputation: 365

Image require() in nuxt with hot reload by HRM webpack

I use the dynamic source for vue-webpack images in nuxt :src="require('path/to/image' + dynamic.variable)" in my project navbar. If the users substitute their image through a form which refetches their information and deletes their previous image I get a webpack error module (img) not found (it does not find the new one): is there a way to solve this, like wait for webpack HRM to finish?

I tried setting up a setTimeout() of one second before user re-fetch and it works, but I don't like a random waiting, I'd use a promise or a sync dynamic, the point is webpack hot reload is not controlled by my functions.. I also tried with setting the dynamic path as a computed: but it doesn't fix.

My image tag:

<img v-if="this.$auth.user.image" class="userlogo m-2 rounded-circle" :src="require('@assets/images/users/' + this.$auth.user.image)" alt="usrimg">

My Useredit page methods:

...
methods: {
    userEdit() {
      //uploads the image
      if (this.formImageFilename.name) {
        let formImageData = new FormData()
        formImageData.append('file', this.formImageFilename)
        axios.post('/db/userimage', formImageData, { headers: { 'Content-Type': 'multipart/form-data' } })
        // once it has uploaded the new image, it deletes the old one 
        .then(res=>{this.deleteOldImage()})
        .catch(err=>{console.log(err)})
      }else{
        this.userUpdate() //if no new image has to be inserted, it proceeds to update the user information
      }
    },
    deleteOldImage(){
      if(this.$auth.user.image){axios.delete('/db/userimage', {data: {delimage: this.$auth.user.image}} )}
      console.log(this.$auth.user.image + ' deleted')
      this.userUpdate() // it has deleted the old image so it proceeds to update the user information
    },
    userUpdate(){
      axios.put(
        '/db/user', {
          id: this.id,
          name: this.formName,
          surname: this.formSurname,
          email: this.formEmail,
          password: this.formPassword,
          image: this.formImageFilename.name,
        })
      .then(() => { console.log('User updated'); this.userReload()}) // reloads the updated user information
      .catch(err => {console.log(err)} )
    },
    userReload(){
      console.log('User reloading..')
      this.$auth.fetchUser()
      .then(() => { console.log('User reloaded')})
      .catch(err => {console.log(err)} )
    },
  }
...

the problem happens after "console.log('User reloading..')" and before "console.log('User reloaded');", it is not related to the file upload nor the server response. I broke a single function in many little ones just to check the function progression and its asynchronous dynamics but the only one that is not manageable is the webpack hot reload :/

I'd like the users to upload their images and see their logo in the Navbar appear updated after submitting the form.

Upvotes: 0

Views: 541

Answers (2)

AMDP
AMDP

Reputation: 365

Okay, I probably solved it.

  1. HMR: you are of course right. Thank you for pointing out, I am sorry, I am a beginner and I try to understand stuff along the way.
  2. Aldarund, thank you, your idea of not changing the path and cache it client side.. I am too noob to understand how I could implement it ( :) ) but it gave me a good hint: the solution was to keep the image name as the user id + the '.png' extension and to manage the image with jimp so that the image name, extension and file type are always the same, and with or without webpack compiling the new path, I always have the correct require().
  3. Jair, thank you for the help, I didn't follow that road, but I will keep it as a second chance if my way creates errors. Just to be specific: the error comes when it does not find -and asks for the name of- the NEW image, not the OLD one, as I wrote in my question: it happens because the fetchUser() functions reloads the user information including the new image name.

Do you guys see any future problems in my methodology? Really thank you for your answers. I am learning alone and it's great to receive support.

Upvotes: 0

Jair Reina
Jair Reina

Reputation: 2915

First of all, as somebody told you in the comments, webpack hmr shouldn't be used for production.

In Nuxt, everything that you reference from the assets folder will be optimized and bundled into the project package. So the ideal use case for this folder is all assets that can be packaged and optimized, and most likely won't change like fonts, css, background images, icons, etc.

Then, require is called only once by webpack when it is either building the site for local development or building the site for generating a production package. The problem in your case is that you delete the original file while you're in development and webpack tries to read it and fails.

In the case of these images that the user uploads, I think you should use the static folder instead and instead of using require you'll have to change the :src with

:src="'/images/users/' + this.$auth.user.image"

Let me know if this helps.

Upvotes: 1

Related Questions