Search code examples
reactjswebpacksass-loader

Webpack 1 + sass (in react) - leave my images alone


I have a project in React.js with SASS and using Webpack 1.

I have images folders with all the images and other assets' folders.

I do not want webpack to do anything with images, I want them to be loaded at the runtime by url. I solved it in JSX by using image urls inline in the jsx code (rather then importing them) and it's working great.

But when I'm trying to do the same in SASS, it's different: I used to refer to them in absolute pass /images/abc.png and it worked. I didn't even had a webpack loader for them, it just worked. But I had to change it to the relative path ../../www/images/abc.png and it's all broke down: It refuses to work without webpack loader - just gives errors for each image. I've tried using file-loader, but it copies all sass's used images into build folder. I've tried using url-loader, but it just included the images into resulting css file making it enormously bloated.

So, what could I use to ignore the images from sass and just address them by url in the runtime?

Thanks


Solution

  • One possibility is to set the url option of the css-loader to false, so webpack won't touch the urls. Your rule for .scss could look something likes this (assuming you use extract-text-webpack-plugin):

    Webpack 1:

    {
      test: /\.scss$/,
      loader: ExtractTextPlugin.extract('style-loader', 'css-loader?url=false!sass-loader')
    },
    

    Webpack 2:

    {
      test: /\.scss$/,
      use: ExtractTextPlugin.extract({
        fallback: 'style-loader',
        use: [
          { loader: 'css-loader', options: { url: false } },
          { loader: 'sass-loader' }
        ]
      })
    }
    

    But that ignores all urls not just your images. If that is a problem you could use file-loader with the option emitFile: false so it won't copy your files. But you'll need some workaround to get the correct path. When using [path] in the name it will use the relative path from the context. Because you're building it to a directory (e.g. build/) you'll need to go up one directory (../) by setting the publicPath option. Which would give you the following rule:

    Webpack 1:

    {
      test: /\.png/,
      loader: 'file-loader?emitFile=false&name=[path][name].[ext]&publicPath=../'
    },
    

    Webpack 2:

    {
      test: /\.png/,
      loader: 'file-loader',
      options: {
        emitFile: false,
        name: '[path][name].[ext]',
        publicPath: '../'
      }
    }
    

    If you've set context in your webpack config or your output CSS file is more than one level deep in the build directory, you'll need to tweak the publicPath option.