Webpack: video tag not transforming sources

Created on 26 Sep 2016  路  14Comments  路  Source: vuejs-templates/webpack

So when running the development server if I load in an image let's say ../assets/myimage.png when I inspect element I see the path gets transformed to /static/img/myimage.png; however, when I do the same thing with a video tag

<video src="../assets/image2.png">
    <source src="../assets/myvid.mp4" type="video/mp4"  />
</video>

Neither the video src not the actual video source get's transformed to the correct path

enhancement help wanted

Most helpful comment

@rodzzlessa24
You can just add transformToRequire option like this:

  vue: {
    loaders: utils.cssLoaders({ sourceMap: useCssSourceMap }),
    postcss: [
      require('autoprefixer')({
        browsers: ['last 2 versions']
      })
    ],
    transformToRequire: {
      video: 'src',
      source: 'src'
    }
  }

See there: http://vue-loader.vuejs.org/en/options.html

All 14 comments

There aren't currently any loaders set up for video extensions, only images and fonts. A PR would be welcome though.

I am about to start using vue.js for a video app, hopefully this gets resolved soon.

@chovy You're welcome to submit a PR if it's urgent for you. Videos (or any other file type) can also still be referenced as static assets.

I'd be happy to when I get to that part. I haven't started yet so I don't know what the PR would contain.

This shouldn't be too hard:

1) add a file-loader for video file extensions to this array

{
  test: /\.mp4$/,
  loader: 'file',
},

2) to have html-loader replace src paths on <source> and <video> elements (by default it only does that for <img>), we have to add this as a config for the vue loaders here:

vue: {
    // the template auto-generates the css loaders. 
    // since we want to change the default loader for HTML,
    // we have to add it to that object.
    loaders: utils.cssLoaders().html = 'html?attrs[]=img:src&attrs[]=video:src&attrs[]=source:src',
    postcss: [
      require('autoprefixer')({
        browsers: ['last 2 versions']
      })
    ]
}

@rodzzlessa24 give it a try and let us now how it works.

@LinusBorg It seems to be working only issue is now it throws errors trying to load scss files

Yeah, my code was a bit thrown together from the top of my head, but the assignment inside of an object definition was not a bright moment.

You have to do something that looks more like this I think:

// all of those requires for the webpack configs 
// at the top of the file are here. Insert this right after:
var vue-loaders = utils.cssLoaders().html = 'html?attrs[]=img:src&attrs[]=video:src&attrs[]=source:src'

module.export = {
  // other weboack configs
  vue: {
    loaders: vue-loaders,
    postcss: [
      require('autoprefixer')({
        browsers: ['last 2 versions']
      })
    ]
  }
}

@LinusBorg Still loading scss error. Here is how my webpack config file looks like:
https://gist.github.com/rodzzlessa24/035bcc241b3974bccc3970d291ffa446

Error:

Module not found: Error: Cannot resolve module 'scss' in /path/to/my/component

That's a strange error. Can I see the component? Are you linking to a scss file in the template or something?

can you console.log the "vue-loader" variable?

vue-loader log:

html?attrs[]=img:src&attrs[]=video:src&attrs[]=source:src

And I am importing a .scss file in most my components but even the ones that I'm not I still get the error:

Component:

<script>
    export default {
        name: 'FooterBar'
    }
</script>

<template>
  <div class="cc-footer">
    <div class="cc-container">
      <div class="footer-title">
        HONOR THE CRAFT.DRINK RESPONSIBLY.
      </div>
      <div class="nav">
        Terms of Use | Privacy Policy | Linking Policy | Contact Us
      </div>
      <div class="legals">
        Lorem ipsum dolor sit amet
      </div>
    </div>
  </div>
</template>


<style lang="scss" scoped>
    .cc-footer {
        padding: 70px 30px;
    }
</style>

Error pertaining to that component:

ERROR in ./src/components/FooterBar.vue
Module not found: Error: Cannot resolve module 'scss' in /Users/rodrigo/work/src/gitlab.fg/brownforman/tourapp/src/components
 @ ./src/components/FooterBar.vue 2:0-219

Separate issue when I check which files are being bundled I never see my .mp4 file in there.

UPDATE:
I logged utils.cssLoaders().html and that is undefined. vue-loader doesn't seem to have a .html property:

vue-loader { css: 'vue-style-loader!css-loader',
  postcss: 'vue-style-loader!css-loader',
  less: 'vue-style-loader!css-loader!less-loader',
  sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax',
  scss: 'vue-style-loader!css-loader!sass-loader',
  stylus: 'vue-style-loader!css-loader!stylus-loader',
  styl: 'vue-style-loader!css-loader!stylus-loader' }

I tried doing this but also does not set a html property on utils.cssLoaders

var vueloaders = utils.cssLoaders()
vueloaders.html = 'html?attrs[]=img:src&attrs[]=video:src&attrs[]=source:src'

What the hell, I realized my one-liner was crap, but why is that last thing not working?

@LinusBorg
So when I run the last thing instead can't resolve scss it errors

Module not found: Error: Cannot resolve module 'html'

Is there a chat we can use instead of clogging up everyones notifications?

@rodzzlessa24
You can just add transformToRequire option like this:

  vue: {
    loaders: utils.cssLoaders({ sourceMap: useCssSourceMap }),
    postcss: [
      require('autoprefixer')({
        browsers: ['last 2 versions']
      })
    ],
    transformToRequire: {
      video: 'src',
      source: 'src'
    }
  }

See there: http://vue-loader.vuejs.org/en/options.html

The latest solution proposed by @Zhangdroid works perfectly. Thanks !

Was this page helpful?
0 / 5 - 0 ratings