P
P
Pavel Petrov2021-07-24 18:22:43
JavaScript
Pavel Petrov, 2021-07-24 18:22:43

Why are fonts not included using webpack 5?

After the project is built, all image and font files are copied to the root of the '/app/' directory.
How can I make sure that images and fonts are saved to the '/app/img' and '/app/fonts' directories, respectively, after the project is built?

Project structure before assembly

project
|- /app
|- /src
  |-  index.html
  |- /assets
    |- favicon.ico
  |- /js
    |- index.js
  |- /scss
    |- style.scss
  |- /img
    |- some.img
  |- /fonts
    |- ZenLoop-Regular.ttf
|- package.json
|- webpack.config.js



Project structure after build

project
|- /app
  |- assets
    |- favicon.ico
  |- /css
    |- style.css
  |- /js
    |- index.js
  |- asdqdq1asd23d.img
  |- asd2312qw24gg.woff
  |- fnnjnveqrjqerpoin.ico
|- /src
  |- index.html
  |- /assets
    |- favicon.ico
  |- /js
    |- index.js
  |- /scss
    |- style.scss
  |- /img
    |- some.img
  |- /fonts
    |- ZenLoop-Regular.ttf
|- package.json
|- webpack.config.js



The webpack config looks like this:

const path = require("path");
const HTMLWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const filename = (ext) =>
  isDev ? `[name].${ext}` : `[name].[contenthash].${ext}`;

const isDev = process.env.NODE_ENV === "development";
const isProd = !isDev;

module.exports = {
  context: path.resolve(__dirname, "src"),

  mode: "development",

  entry: "./js/main.js",

  output: {
    filename: `./js/${filename("js")}`,
    path: path.resolve(__dirname, "app"),
    publicPath: "",
  },
  
  devtool: "inline-source-map",

  devServer: {
    contentBase: path.resolve(__dirname, "app"),
    port: 4200,
  },

  plugins: [
    new HTMLWebpackPlugin({
      title: "My App",
      template: path.resolve(__dirname, "src/index.html"),
      filename: "index.html",
      minify: {
        collapseWhitespace: isProd,
      },
    }),
    new CleanWebpackPlugin(),
    new MiniCssExtractPlugin({
      filename: `css/${filename("css")}`,
    }),
    new CopyWebpackPlugin({
      patterns: [
        {
          from: path.resolve(__dirname, "src/assets/"),
          to: path.resolve(__dirname, "app/assets"),
        },
      ],
    }),
  ],
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              hmr: isDev,
            },
          },
          "css-loader",
        ],
      },
      {
        test: /\.s[ac]ss$/i,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              publicPath: (resourcePath, context) => {
                return path.relative(path.dirname(resourcePath), context) + "/";
              },
            },
          },
          "css-loader",
          "sass-loader",
        ],
      },
      {
        test: /\.(?:|gif|png|ico|jpg|jpeg|svg)$/,
        type: 'asset/resource',
      },
      {
        test: /\.(?:|woff2|woff|ttf)$/,
        type: 'asset/resource',
      },
    ],
  },
};

Style code
@font-face {
    font-family: 'ZenLoopRegular';
    src: url('../fonts/ZenLoop-Regular.ttf') format('truetype');
}
body {
    background-image: url('../img/birthday-1061.jpeg');
    font-family: 'ZenLoopRegular';
}



Dependencies

{

  "devDependencies": {
    "clean-webpack-plugin": "^4.0.0-alpha.0",
    "copy-webpack-plugin": "^9.0.1",
    "cross-env": "^7.0.3",
    "css-loader": "^6.2.0",
    "html-webpack-plugin": "^5.3.2",
    "mini-css-extract-plugin": "^2.1.0",
    "node-sass": "^6.0.1",
    "sass-loader": "^12.1.0",
    "webpack": "^5.6.0",
    "webpack-cli": "^4.7.2",
    "webpack-dev-server": "^3.11.2"
  },
  "dependencies": {
    "file-loader": "^6.2.0",
    "normalize.css": "^8.0.1"
  }
}



styles in scss

@font-face {
    font-family: 'ZenLoopRegular';
    src: url('../fonts/ZenLoop-Regular.ttf') format('truetype');
}
 

body {
    background-image: url('../img/birthday-1061.jpeg');
    font-family: 'ZenLoopRegular';
}



This is what /app/css/style.css looks like after build

@font-face {
  font-family: 'ZenLoopRegular';
  src: url(../f6f4362d900538955a17.ttf) format("truetype"); }

body {
  background-image: url(../1d15ea9e41b8ec41279d.jpeg);
  font-family: 'ZenLoopRegular'; }

Answer the question

In order to leave comments, you need to log in

1 answer(s)
P
Pavel Petrov, 2021-07-24
@Hakas_Lepehen

Hurry up, make people laugh. I've been looking for an answer to my question for three days. And only when I decided to turn to the experts - I kind of found the answer.
Must be used to set custom paths for saving images, fonts assetModuleFilename: '[path][name].[ext]'

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question