Webpack 5: assets folder is generated only after the second npm run dev command

Viewed 4588

I'm just starting to use Webpack and now I'm trying to set up my project using Webpack 5 and its new feature: asset modules for fonts(tf|woff|woff2|eot|otf) and images(png|jpg|gif|svg). The project builds sucessfully: I get dist/main.css, dist/main.js, dist/index.html. All images and fonts files are emitted within the output dist directory with [hash][ext][query] filename.

My project tree is :

webpack.config.js
dist
src
--css
--fonts
--img
--index.html
--index.js

My webpack config:

const path = require('path');

const HTMLWebpackPlugin = require('html-webpack-plugin');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin'); 
const TerserWebpackPlugin = require('terser-webpack-plugin');

const NODE_ENV = process.env.NODE_ENV;
const IS_DEV = NODE_ENV === 'development';
const IS_PROD = !IS_DEV;

module.exports = {
mode: NODE_ENV ? NODE_ENV : 'development',
entry: path.resolve(__dirname, 'src/index.js'),
output : {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist'),
    publicPath: './',
    // assetModuleFilename: 'assets/[hash][ext][query]',
},

module: {
    rules: [

        {
        test: /\.html$/,
        use: 'html-loader'
        },

        {
            test: /\.css$/,
            use: [
                {
                loader: MiniCssExtractPlugin.loader, //instead of style-loader
                options: {
                    publicPath: './'
                    },
                },
                'css-loader'
                ],
        },

        {
            test: /\.(png|jpg|gif|svg)$/,
            type: 'asset/resource',
            // generator: {
            //  filename: 'images/[hash][ext][query]'
            // }
        },

        {
            test: /\.(ttf|woff|woff2|eot|otf)$/,
            type: 'asset/resource',
        },
    ],
},

plugins:
[
    new CleanWebpackPlugin({
        cleanStaleWebpackAssets: false
    }),

    new HTMLWebpackPlugin({
        template: path.resolve(__dirname, 'src/index.html'),
        minify: {
            collapseWhitespace: IS_PROD,
        }
    }),

    new MiniCssExtractPlugin(),
],

optimization: {
    minimizer: [
        new CssMinimizerWebpackPlugin(),
        new TerserWebpackPlugin(),
    ],
},

devServer: {
    port: 3000,
    hot: true,
}

}

Problem #1: When I set assetModuleFilename: 'assets/[hash][ext][query]' to the output in my webpack config

module.exports = {
mode: NODE_ENV ? NODE_ENV : 'development',
entry: path.resolve(__dirname, 'src/index.js'),
output : {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist'),
    publicPath: './',
    assetModuleFilename: 'assets/[hash][ext][query]',
},

and run build (npm run dev) FIRST time I get error.

 Error: EPERM: operation not permitted, lstat 'E:\WEB\MiTravel\MiTravel\dist\assets\0a04460c0a144cf3f0a9.svg'
at Object.lstatSync (fs.js:1077:3)
at Function.rimrafSync [as sync] (E:\WEB\MiTravel\MiTravel\node_modules\rimraf\rimraf.js:299:24)
at E:\WEB\MiTravel\MiTravel\node_modules\del\index.js:65:11
at Array.map (<anonymous>)
at module.exports.sync (E:\WEB\MiTravel\MiTravel\node_modules\del\index.js:57:40)
at CleanWebpackPlugin.removeFiles (E:\WEB\MiTravel\MiTravel\node_modules\clean-webpack-plugin\dist\clean-webpack-plugin.js:198:37)

At this moment there are sucessfully built main.js, index.html, main.css and NO dist/assets dir in the output dist directory. Then I just repeat (SECOND time) npm run dev command and get dist/assets dir with all assets files and main.js, index.html, main.css in the output dist directory. And all fonts and images are ok.

I googled the error, tried to change different parametres but I still can't fix this bug.

Thank you in advance for help and advice.

1 Answers

i am using it using the same first name and it is working.

assetModuleFilename: 'assets/[hash][ext][query]'
generator: {
        filename: 'assets/[hash][ext][query]'

try to change assets to images an see if it works.

Related