Search code examples
ruby-on-railsnpmwebpackyarnpkgwebpacker

Import images of an npm package with Webpacker and Rails


I'm trying to install the package lightslider with yarn and webpacker.

Here's what I did so far :

yarn add lightslider
// app/webpacker/packs/application.js

require('lightslider'); 
// app/webpacker/src/application.scss

@import '~lightslider/dist/css/lightslider.min';

However, the Webpack compilation fails because of the following error :

Module not found: Error: Can't resolve '../img/controls.png'

which is an image that is required by lightslider to work properly, and is located in node_modules/lightslider/dist/img/controls.png :

// node_modules/lightslider/dist/css/lightslider.css

.lSAction > a {
    width: 32px;
    display: block;
    top: 50%;
    height: 32px;
    background-image: url('../img/controls.png');
    cursor: pointer;
    position: absolute;
    z-index: 99;
    margin-top: -16px;
    opacity: 0.5;
    -webkit-transition: opacity 0.35s linear 0s;
    transition: opacity 0.35s linear 0s;
}

How can I import this image in my pack so that lightslider will find it ?


Solution

  • From the WebpackER docs: https://github.com/rails/webpacker/blob/76b491750993fada8b0b0cc2546dfcfbc4aaae13/docs/css.md#resolve-url-loader

    Since Sass/libsass does not provide url rewriting, all linked assets must be relative to the output. Add the missing url rewriting using the resolve-url-loader. Place it directly after the sass-loader in the loader chain.

    // webpack/environment.js
    const { environment } = require('@rails/webpacker')
    
    // resolve-url-loader must be used before sass-loader
    environment.loaders.get('sass').use.splice(-1, 0, {
      loader: 'resolve-url-loader'
    });
    

    I was able to reproduce/fix the issue you described without/with the modification above using @rails/[email protected] and [email protected].