0

I'm using webpack to make cms templates.

In some css file, I'm using some images like background-image: url('../images/space-bg.jpg');

All images are in the webpack folder, and I want webpack to push them to the public folder.

For now I'm using in my index.js file some hardcoded rules such as import '../images/space-bg.jpg';

But I'm wondering if there is a way to handle them automatically?

Here is my webpack.config.js:

var path = require('path');
var MiniCssExtractPlugin = require('mini-css-extract-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
    mode: 'development',
    entry: './src/js/index.js',
    output: {
        filename: 'js/theme-[contentHash].js',
        path: path.resolve('./assets'),
        publicPath: 'themes/mazdigital/assets'
    },
    plugins: [
        new HtmlWebpackPlugin({
            filename: path.resolve(__dirname, 'layouts/default.htm'),
            template: './src/layouts/default.htm'
        }),
        new MiniCssExtractPlugin({
            filename: 'css/theme-[contenthash].css',
            chunkFilename: '[id]-[contenthash].css',
        }),
        new CleanWebpackPlugin()
    ],
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader?url=false',
                    'postcss-loader'
                ],
            },
            {
                test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
                loader: 'file-loader',
                options: {
                    name: 'fonts/[name].[ext]'
                }
            },
            {
                test: /\.(png|jpe?g|gif)$/i,
                loader: 'file-loader',
                options: {
                    name: 'images/[name].[ext]',
                }
            },
        ],
    },
};

1 Answers1

0

You'll want to ensure css-loader is configured properly.

You're using 'css-loader?url=false' in your config. That query string is disabling the ability to treat url(...) expressions as require/import statements.

So, your first loader rule should instead be:

{
  test: /\.css$/,
  use: [
    MiniCssExtractPlugin.loader,
    'css-loader',                 // <- removed ?url=false
    'postcss-loader'
  ],
}
rossta
  • 11,394
  • 1
  • 43
  • 47
  • The problem is: I'm using ?url=false because if I don't, the url() is bad calculated. In local: I access my website with http://mazdigital.app, and webpack is installed in /themes/mazdigital/, if I remove ?url=false, the link to the assets is calculated "themes/mazdigital/assetsimages/space-bg.jpg", but should be: ../images/space-bg.jpg I achieved that by using ?url=false – Romain 'Maz' BILLOIR Dec 23 '19 at 12:08
  • working around publicPath with css loader like that is working, but seems to me really weird, isn't it? loader: MiniCssExtractPlugin.loader, options: { publicPath: '../' } – Romain 'Maz' BILLOIR Dec 23 '19 at 12:47
  • I usually set the trailing slash for my `publicPath`. So instead of `publicPath: 'themes/mazdigital/assets'`, I would use `publicPath: 'themes/mazdigital/assets/'`, which would get you the correct image urls in CSS without overriding the publicPath for MiniCssExtractPlugin. – rossta Dec 23 '19 at 14:56