Webpack 5: how to disable copying static files to build folder?

I am used webpack 2 for project, and some days ago I have upgraded to version 5.6. 2-3 hours and project compiling OK, but I have just one problem.

All static files (images, fonts) I store in /static/ folder.

CSS file:

.link-yellow{
    background-image: url("/static/wifi2.png");
}
.link-red{
    background-image: url("/static/wifi4.png");
}
.link-grey{
    background-image: url("/static/wifi3.png");
}

Webpack 2 after compiling JS bundle file don't touch css url(...) links but webpack 5 copying files to folder /build/ and finally I have this:

4e4b4524859364a45966.png
5b97c8a6a9b9aa05b4be.otf
7ed064d8178174fa9ce1.woff2
14d3902c59ccd98328c8.png
440e51cee01b3e78fed5.png
664550a92a1dbb39a80a.png
build.js

And this records (like 4e4b4524859364a45966.png) in build.js:

...3197:function(t,e,n){"use strict";t.exports=n.p+"4e4b4524859364a45966.png"}...

Build progress: enter image description here

I tried to use file-loader with this params:

module: {
        rules: [
                       ....
                         {
                            test: /\.(png|svg|jpg|jpeg|gif|gif|woff|woff2|eot|ttf|otf)$/,
                            loader: 'file-loader',
                            options:{
                              emitFile: false,
                              name: '[name].[ext]'
                            }
                         }
                    ....
              ]
}

but after that I have the same files in /build/ folder with texts inside like this:

export default __webpack_public_path__ + "wifi2.png";
export default __webpack_public_path__ + "exo2.otf";
export default __webpack_public_path__ + "wifi3.png";

I moved some images files to style="..." attributes in vue files:

<div id="mainFooter" style="background: transparent url('/static/wifi3.png') no-repeat 0 0">

and webpack don't touch this text and not generate copies of static files in /build/ folder and all works fine. It is that I need.

Full source of webpack.config.js:

var path = require('path');
var webpack = require('webpack');
const { VueLoaderPlugin } = require('vue-loader');
const TerserPlugin = require("terser-webpack-plugin");

module.exports = {
    entry: './src/main.js',
    output: {
        path: path.resolve(__dirname, './dist'),
        publicPath: '/dist/',
        filename: 'build.js'
    },
    mode: 'production',
    plugins: [
        new VueLoaderPlugin()
    ],
    module: {
        rules: [
            {
                test: /\.styl$/,
                use: ['style-loader', 'css-loader', 'stylus-loader']
            },
            {
                test: /\.css$/,
                use: ['vue-style-loader','css-loader']
            },
            {
                test: /\.scss$/,
                use: ['vue-style-loader','css-loader','sass-loader'],
            },
            {
                test: /\.sass$/,
                use: ['vue-style-loader','css-loader','sass-loader?indentedSyntax'],
            },
            {
                test: /\.vue$/,
                loader: 'vue-loader',
                options: {
                    loaders: {
                        'scss': [
                            'vue-style-loader',
                            'css-loader',
                            'sass-loader'
                        ],
                        'sass': [
                            'vue-style-loader',
                            'css-loader',
                            'sass-loader?indentedSyntax'
                        ]
                    }
                }
            },
            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: /node_modules/
            },
            {
                        test: /\.(png|svg|jpg|jpeg|gif|gif|woff|woff2|eot|ttf|otf)$/,
                        loader: 'file-loader',
                options:{
                    emitFile: false,
                    name: '[name].[ext]'
                }
               }
        ]
    },
    resolve: {
        alias: {
            'vue$': 'vue/dist/vue.esm.js'
        },
        extensions: ['*', '.js', '.vue', '.json']
    },
    devServer: {
        historyApiFallback: true,
        client: {
              overlay: true,
        },
        static: './'
    },
    performance: {
        hints: false
    },
    devtool: 'eval-source-map',
    optimization: {
        minimize: true,
        portableRecords: true,
        removeAvailableModules: true,
        minimizer: [
            new TerserPlugin({
                parallel: true,
                terserOptions: {
                            format: {
                        comments: false,
                    },
                },
                extractComments: false
                })
        ]
    }
};

if (process.env.NODE_ENV === 'production') {
    module.exports.devtool = 'inline-nosources-cheap-source-map';//source-map
    module.exports.plugins = (module.exports.plugins || []).concat([
        new webpack.DefinePlugin({
            'process.env': {
                NODE_ENV: '"production"'
            }
        }),
        new webpack.LoaderOptionsPlugin({
            minimize: true
        })
    ])
}

Maybe someone know how to disable generating static files in /build/ folder and leave files url's in css with no modifying paths?

Upvotes: 1

Views: 1778

Answers (2)

Pixel online
Pixel online

Reputation: 73

I have the same problem, partly resolved. This is a homemade project with parts in React.

Image URLs in css no longer create file duplication in the build.

On the other hand in my react it still creates the file

            {
            test: /\.css$/,
            use: [
                MiniCssExtractPlugin.loader,
                {
                    loader: 'css-loader',
                    options: {
                        url: false,
                    },
                },
            ],
        },

For the CSS part it's perfect it works But for the react part, it's not good Si j'utilise :

import puce from '../../../../public/Back/assets/Image/puce_titre.gif';

With this configuration :

{
            test: /\.(png|webp|jpg|jpeg|gif)$/i,
            include: path.resolve(__dirname, './public/Back/assets/Image/'),
            type: 'asset/resource',
            generator: {
                filename: 'back/images/[name][ext]',
            },
        }

This duplicates the image in the build file, this is normal given the configuration!

With this configuration :

            {
            test: /\.(png|webp|jpg|jpeg|gif)$/i,
            include: path.resolve(__dirname, './public/Back/assets/Image/'),
            type: 'asset/inline',
        },

This is not working properly. The image is no longer duplicated in build but is added as Inline data.

I would like to know if it is possible to just use the initial image via its path defined in the "import" without duplicating it and without having inline data.

Can't find anything conclusive in Webpack 5 documentation

Edit it's work !:

{
            test: /\.(png|webp|jpg|jpeg|gif)$/i,
            include: path.resolve(__dirname, './public/Back/assets/Image/'),
            loader: 'file-loader',
            options: {
                emitFile: false,
                name: '[path][name].[ext]',
                publicPath: '/',
                context: path.resolve(__dirname, './public'),
            },
        },

Upvotes: 0

UPDATE: I have some progress. Code disabling touching urls in css files, but fonts still copying:

{
    test: /\.css$/,
    use: ['vue-style-loader']
},
{
    test: /\.css$/,
    loader: 'css-loader',
        options: {
            url: false,
        },
},

UPDATE2: Done. Adding:

{
    test: /\.(png|jpe?g|gif|svg|eot|ttf|woff|woff2)$/i,
    type: "asset",
}

finally disabling generate other files. At now generating only /build/build.js file

Upvotes: 4

Related Questions