How to properly connect images and fonts in scss webpack?

  • 0
    The webpack tries to find images and font included in scss in the css / ... folder, how to fix it?



    const path = require('path')
    const HTMLWebpackPlugin = require('html-webpack-plugin')
    const {CleanWebpackPlugin} = require('clean-webpack-plugin')
    const CopyWebpackPlugin = require('copy-webpack-plugin')
    const MiniCssExtractPlugin = require('mini-css-extract-plugin')
    const OptimizeCssAssetWebpackPlugin = require('optimize-css-assets-webpack-plugin')
    const TerserWebpackPlugin = require('terser-webpack-plugin')
    const Autoprefixer = require('autoprefixer')
    const webpack = require("webpack");
    const ImageminPlugin = require("imagemin-webpack-plugin").default;
    const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer')
    
    const isDev = process.env.NODE_ENV === 'development'
    const isProd = !isDev
    
    const optimization = () => {
        const config = {
            splitChunks: {
                chunks: 'all'
            }
        }
    
        if (isProd) {
            config.minimizer = [
                new OptimizeCssAssetWebpackPlugin(),
                new TerserWebpackPlugin()
            ]
        }
    
        return config
    }
    
    const filename = ext => isDev ? `${ext}/[name].${ext}` : `${ext}/[name].[hash].${ext}`
    
    const cssLoaders = extra => {
        const loaders = [
            {
                loader: MiniCssExtractPlugin.loader,
                options: {
                    name: "[path][name].[ext]",
                    hmr: isDev,
                    reloadAll: true,
                },
            },
            'css-loader',
            'postcss-loader'
        ]
    
        if (extra) {
            loaders.push(extra)
        }
    
        return loaders
    }
    
    const babelOptions = preset => {
        const opts = {
            presets: [
                '@babel/preset-env'
            ],
            plugins: [
                '@babel/plugin-proposal-class-properties'
            ]
        }
    
        if (preset) {
            opts.presets.push(preset)
        }
    
        return opts
    }
    
    
    const jsLoaders = () => {
        const loaders = [{
            loader: 'babel-loader',
            options: babelOptions()
        }]
    
        /*if (isDev) {
            loaders.push({
                loader: 'eslint-loader'
            })
        }*/
    
        return loaders
    }
    
    const plugins = () => {
        const base = [
            new HTMLWebpackPlugin({
                template: './index.html',
                minify: {
                    collapseWhitespace: isProd
                }
            }),
            new CleanWebpackPlugin(),
            new CopyWebpackPlugin(
                [
                    {
                        from: path.resolve(__dirname, 'src/.htaccess'),
                        to: path.resolve(__dirname, 'dist/')
                    },
                    {
                        from: path.resolve(__dirname, 'src/img/favicon'),
                        to: path.resolve(__dirname, 'dist/img/favicon')
                    }
                ]
            ),
            new MiniCssExtractPlugin({
                filename: filename('css')
            }),
            new webpack.LoaderOptionsPlugin({
                options: {
                    postcss: [
                        Autoprefixer()
                    ]
                }
            }),
        ]
    
        if (isProd) {
            //base.push(new BundleAnalyzerPlugin())
            base.push(new ImageminPlugin({
                test: /\.(png|jpg|gif|ico|svg)$/
            }))
        }
    
        return base
    }
    
    module.exports = {
        context: path.resolve(__dirname, 'src'),
        mode: 'development',
        entry: {
            main: ['@babel/polyfill', './index.js'],
        },
        output: {
            filename: filename('js'),
            path: path.resolve(__dirname, 'dist')
        },
        resolve: {
            extensions: ['.js', '.json', '.png', '.svg', ],
            alias: {
                '@img': path.resolve(__dirname, 'src/img'),
                '@': path.resolve(__dirname, 'src/img'),
            }
        },
        optimization: optimization(),
        devServer: {
            port: 3001 ,
            hot: isDev
        },
        devtool: isDev ? 'source-map' : '',
        plugins: plugins(),
        module: {
            rules: [
                {
                    test: /\.html$/,
                    use: 'html-loader'
                },
                {
                    test: /\.css$/,
                    use: cssLoaders()
                },
                {
                    test: /\.s[ac]ss$/,
                    use: cssLoaders('sass-loader')
                },
                {
                    test: /\.(png|jpg|svg|gif)$/,
                    use: [{
                        loader: 'file-loader',
                        options: {
                            name: "[name].[ext]"
                        }
                    }]
                },
                {
                    test: /\.(ttf|woff|woff2|eot)$/,
                    use: [{
                        loader: 'file-loader',
                        options: {
                            name: "[path][name].[ext]",
                        }
                    }]
                },
                {
                    test: /\.js$/,
                    exclude: /node_modules/,
                    use: jsLoaders()
                },
                {
                    test: /\.jsx$/,
                    exclude: /node_modules/,
                    loader: {
                        loader: 'babel-loader',
                        options: babelOptions('@babel/preset-react')
                    }
                }
            ]
        }
    }


    &:after {
    			content: url("/img/roadmap/line.svg");
    			position: absolute;
    			left: 50%;
    			transform: translateX(-50%) translateY(100%);
    			bottom: -12px;
    			height: 65px;
    		}


    @include font-face("arial", "../fonts/ArialRegular/ArialRegular");
    @include font-face("arial", "../fonts/ArialBold/ArialBold", bold);
    
    
    @mixin font-face($font-family, $file-path, $weight: normal, $style: normal, $asset-pipeline: false ) {
    	@font-face {
    		font-family: $font-family;
    		font-weight: $weight;
    		font-style: $style;
    
    		@if $asset-pipeline == true {
    			src: font-url('#{$file-path}.eot');
    			src: font-url('#{$file-path}.eot?#iefix') format('embedded-opentype'), font-url('#{$file-path}.woff') format('woff'), font-url('#{$file-path}.ttf') format('truetype');
    		} @else {
    			src: url('#{$file-path}.eot');
    			src: url('#{$file-path}.eot?#iefix') format('embedded-opentype'), url('#{$file-path}.woff') format('woff'), url('#{$file-path}.ttf') format('truetype');
    		}
    	}
    }
    JavaScript Anonymous, Jan 30, 2019

  • 0 Answers
Your Answer
To place the code, please use CodePen or similar tool. Thanks you!