Компиляция .less с активами .png с помощью webpack для проекта Django

У меня есть папка для файлов .less, в которой находится папка img:

less
|   `-- img
|       `-- good-boy-cleaning.png
`-- index.less

содержимое файла index.less:

html {
    body {
        background-image: url("img/good-boy-cleaning.png");
        max-width: image-width("img/good-boy-cleaning.png");
    }
}

В рамках проекта Django я хотел бы скомпилировать это в css файл в ./myapp/static/myapp/css/, который ссылается на файлы изображений в ./myapp/static/myapp/img/.

Возможно ли это?

Ближе всего я подошел к следующему файлу webpack.config.js:

const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
    entry: {
        myappcss: "./less/index.less",
    },
    mode: "development",
    output: {
        path: path.resolve("./myapp/static/myapp/"),
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: 'css/[name].[contenthash].css',
        }),
    ],
    module: {
        rules: [{
                test: /\.(png|jpg)$/,
                use: [{
                    loader: "file-loader",
                    options: {
                        name: "[path][name].[ext]",
                        context: path.resolve('./less')
                    }
                }]
            }, {
                test: /\.less$/,
                use: [{
                        loader: MiniCssExtractPlugin.loader,
                        options: {
                            publicPath: "../"
                        }
                    }, {
                        loader: "css-loader",
                        options: {
                            // url: false,
                            importLoaders: 1
                        }
                    },
                    'less-loader'
                ]
            }
        ]
    }
}

который копирует ./less/img/good-boy-cleaning.png в ./myapp/static/myapp/img/good-boy-cleaning.png и создает css файл в ./myapp/static/myapp/css/myappcss.03ee...97.css, однако содержимое css файла таково:

html body {
  background-image: url(../f2215e467af7ba27555f.png);
  max-width: 264px;
}

создается указанный файл png, но он содержит только:

export default __webpack_public_path__ + "img/good-boy-cleaning.png";

что не особенно полезно.

Если я включаю закомментированное // url: false,, то png файл не копируется в static, а содержимое css файлов имеет следующий вид:

html body {
  background-image: url("img/good-boy-cleaning.png");
  max-width: 264px;
}

где должен был быть url ../img/good-boy-cleaning.png - при условии, что png файл был скопирован.

Мой package.json:

{
  "name": "webpack-less-test",
  "version": "1.0.0",
  "main": "index.js",
  "repository": "https://github.com/thebjorn/webpack-less-test.git",
  "author": "thebjorn <bp@datakortet.no>",
  "license": "MIT",
  "private": false,
  "devDependencies": {
    "html-webpack-plugin": "^5.3.2",
    "less": "^4.1.2",
    "less-loader": "^10.1.0",
    "mini-css-extract-plugin": "^2.1.0",
    "node-notifier": "^10.0.0",
    "typescript": "^4.3.5",
    "webpack": "^5.44.0",
    "webpack-cli": "^4.7.2",
    "webpack-merge": "^5.8.0",
    "file-loader": "6.2.0",
    "css-loader": "6.7.1"
  }
}

Возможно, само собой разумеется, что я не эксперт по webpack, поэтому, возможно, я неправильно понял, как это должно работать, или пропустил важную опцию...

Похоже, что модули активов обеспечивают необходимую функциональность "из коробки" (иш). Следующий webpack.config.js:

const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
    entry: {
        myappcss: "./less/index.less",
    },
    mode: "production",
    devtool: false,
    output: {
        path: path.resolve("./myapp/static/myapp/"),
        assetModuleFilename: 'img/[name][ext][query]',
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: 'css/[name].[contenthash].css',
        }),
    ],
    module: {
        rules: [{
                test: /\.(png|jpg)$/,
                type: "asset",
            }, {
                test: /\.less$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'less-loader',
                ]
            }
        ]
    }
}

генерирует static/myapp/static/css/myapp.ccc94...634.css, содержащий:

html body {
  background-image: url(../img/good-boy-cleaning.png);
  max-width: 264px;
}

что является ожидаемым url.

Он также копирует png в static/myapp/static/img/good-boy-cleaning.png, что я и хотел.

Вернуться на верх