rails / webpacker

Use Webpack to manage app-like JavaScript modules in Rails
MIT License
5.31k stars 1.47k forks source link

Webpacker 6: Missing documentation on how to resolve images or fonts used in scss #3222

Closed kimyu92 closed 2 years ago

kimyu92 commented 2 years ago

I believe it's quite common to use resolver-url-loader to ensure the relative path of image is working in scss. However, it seems like I can't find any documentation in the upgrade guide that talks about this particular changes.

Error

Error 1: Failed to resolve image path used in scss (Resolved)

Module not found: Error: Can't resolve '../assets/images/bar.png' in '/sample/app/javascript/packs'
resolve '../assets/images/bar.png' in '/sample/app/javascript/packs'
  using description file: /sample_app/package.json (relative path: ./app/javascript/packs)
    using description file: /sample_app/package.json (relative path: ./app/javascript/assets/images/bar.png)

Error 2: Similar to issues, https://github.com/rails/webpacker/issues/1267 & https://github.com/rails/webpacker/issues/1119, after upgrading to webpacker 6, it failed to resolve bootstrap glyhicons with previous workaround mentioned in https://github.com/rails/webpacker/issues/1119#issuecomment-352738508

Module not found: Error: Can't resolve '../fonts/bootstrap/glyphicons-halflings-regular.svg' in '/sample/app/javascript/packs'
resolve '../fonts/bootstrap/glyphicons-halflings-regular.svg' in '/sample/app/javascript/packs'
  using description file: /sample_app/package.json (relative path: ./app/javascript/packs)
    using description file: /sample_app/package.json (relative path: ./app/javascript/assets/images/bar.png)

Folder structure

app
  |___ javascript
  |   |
  |   |___ packs
  |      |
  |      |___ ApplicationPack.js
  |      |
  |___assets
  |   |  
  |   |___ stylesheets
  |   |  |   |
  |   |  |   |__ Application.scss
  |   |  |   |
  |   |___ images
  |   |  |   |
  |   |  |   |__ bar.png
# Application.scss
.foo {
  background-image: url('../assets/images/bar.png');
}

Webpack config

// config/webpack/base.js

const { webpackConfig, merge } = require('@rails/webpacker');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

merge(webpackConfig, {
  module: {
    rules: [
      {
        test: /\.(sa|sc|c)ss$/i,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
          },
          'css-loader',
          'postcss-loader',
          'resolve-url-loader',
          {
            loader: 'sass-loader',
            options: {
              sourceMap: true,
              sourceMapContents: false,
            },
          },
        ],
      },
    ],
  },
});

module.exports = webpackConfig;

System

Update

To resolve relative image used in scss

const customConfig = { context: path.resolve(__dirname, '../../app/javascript'), // Default webpacker setup, old setup was app/javascripts, this is the value from webpacker.yml "source_path" // ...rest of your customConfig goes here }

// you may need to update relative path in scss as well, eg. update url('../assets/...') to url('../../assets/..')



Any guidance/insight regarding on how to resolve bootstrap glyphicons would be much appreciated 🙏 .
justin808 commented 2 years ago

@guillaumebriday this seems to be a doc issue, as rails/webpacker code is just for the simple cases.

kimyu92 commented 2 years ago

This seems to be related to resolve-url-loader instead of webpacker upgrade.

However, for those who encounter issue using resolve-url-loader >= 3 to import images in scss file,

I ended up using solution here where I create an alias for image directory in webpack custom.js and then instead of using relative path, I point it to url('~images/x.png')

const path = require('path');
module.exports = {
  resolve: {
    alias: {
      images: path.resolve(__dirname, '../../app/assets/images'),
    },
  },
};

To resolve bootstrap-sass glyphicon issue, credit: https://github.com/maxmx/bootstrap-stylus/issues/129

$icon-font-path: '~bootstrap-sass/assets/fonts/bootstrap/';
@import '~bootstrap-sass/assets/stylesheets/bootstrap';
justin808 commented 2 years ago

Thanks, @kimyu92! This is a useful tip!