How to access assets with webpacker gem

If I understand your question correctly, you will have to find the webpack.base.conf.js file inside your build folder, then find the code that looks like this:

resolve: {
  extensions: ['.js', '.vue', '.json'],
  alias: {
    'vue$': 'vue/dist/vue.esm.js',
    '@': resolve('src')
  }
}

Then add the following line to the alias object: 'assets': resolve('src/assets/'), which will work for the assets folder being right below the src folder. You can also change the key string from assets to whatever alias name you desire.

EDIT:

I forgot to mention, to access aliases in style code, you have to prefix it with a ~ (telda) so that assets becomes ~assets.


Since this is tagged with Vue.js I will answer for that. None of the other answers worked with Vue 2.x.

For Attributes

A webpacker require statement returns the full URL of the required asset (resolved based on your resolved_paths inside webpacker.yml). Based on that, you can do something like this:

<img :src="require('images/what-a-pain.png')" alt="Finally working" />

Please note the colon causing the src attribute to be bound to the result of the javascript expression.

You can also use ID anchors by appending them, for example with SVG:

<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
    <use :href="require('images/icons.svg') + '#copy'" />
</svg>

Vue templates are generally pre-compiled to javascript equivalents, so a require statement is needed to pull the assets in at compile time, not runtime.

For CSS urls, scoped or not

Simply use a tilde ~ and a path. The path must be relative to either the file including it or the resolved_paths from webpacker.yml.

.relative-pathed {
    background: url(~../../../assets/images/quitethepath.svg) center center no-repeat;
}
.works-after-editing-webpackeryml {
    background: url(~images/quitethepath.svg) center center no-repeat;
}

For this usage there is no need to require() the asset.

Please note: there is a difference in paths between development and production, especially if Sprockets is also used. Simply doing src="/assets/image.png" will sometimes work in developement, but not production.


New Rails' webpacker stuff is pretty raw, so that's the configuration that works for me:

config/webpacker.yml (for webpacker 3):

resolved_paths: ['app/javascript/images', 'app/javascript/src']
compile: false
# ...

JS files:

/app
  /javascript
    /packs
      # only entry point files
      vue_application.js
    /src
      some_component.vue
    /images
      logo.svg

in component:

<script>
import 'images/logo.svg'
</script>

in template:

<img src='~images/logo.svg' />

point the tilde here - it means that the image is a module dependency

in CSS:

<style lang='sass'>
#app
  background: url('../images/logo.svg')
</style>

For some reason tilde does not work here, so relative path is used.