E
E
Evgeniy V.2020-10-30 12:05:16
JavaScript
Evgeniy V., 2020-10-30 12:05:16

How to correctly include images and fonts in scss webpack?

Webpack is trying to find images and fonts included in scss in the css/... folder, how can I fix this?

5f9bd73032f2c378680905.png

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');
    }
  }
}

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question