Webpack 5 资源模块:如何在输出文件夹中保持文件夹结构?

9
我尝试配置Webpack 5,以便保留我的图片和字体的资产文件夹结构。
我有以下结构:
- /app
    /assets
        /images
            /topic1
            /topic2
        /fonts

在我的webpack配置中,我已经像这样配置了Assets模块:
{
    test: /\.(png|svg|jpg|jpeg|gif|xml)$/i,
    type: 'asset/resource'
}
...
same for Font files...

如果我运行Webpack 5构建,它默认将资产复制到我的dist/文件夹中的扁平结构中,例如,文件夹/topic1下的图像直接复制到dist/my-topic1-img.png,但实际上我希望它在这里:dist/assets/images/topic1/my-topic1-img.png
我该如何轻松实现这个目标?
我在这里看到了这个文档链接:https://webpack.js.org/configuration/module/#rulegeneratorfilename。所以我认为一个解决方案可能是编写一些自定义的filename函数,根据文件路径动态设置新的文件名,包括每个资产的路径元素。
Webpack 5是否支持这样的配置,还是我真的需要编写一些自定义函数来实现?
感谢您的帮助和意见。
1个回答

20

你可以使用 output.assetModuleFilename 选项和 模板字符串 来实现这一点。

assetModuleFilename 可以是一个函数。我们可以从 pathData.filename 获取类似于 app/assets/images/topic1/icons8-apple-logo-16.png 的文件名,然后删除路径中的 app/ 部分。

目标资产目录将变为 assets/images/topic1/icons8-apple-logo-16.png

例如,文件夹结构如下:

⚡  tree -L 5 -I 'node_modules'
.
├── app
│   ├── assets
│   │   └── images
│   │       ├── topic1
│   │       │   └── icons8-apple-logo-16.png
│   │       └── topic2
│   │           └── icons8-itunes-store-16.png
│   └── index.js
├── package-lock.json
├── package.json
└── webpack.config.js

5 directories, 6 files

app/index.js:

import appleLogo from "./assets/images/topic1/icons8-apple-logo-16.png";
import itunesLogo from "./assets/images/topic2/icons8-itunes-store-16.png";

console.log("appleLogo: ", appleLogo);
console.log("itunesLogo: ", itunesLogo);

webpack.config.js:

const path = require("path");

module.exports = {
  entry: "./app/index.js",
  output: {
    filename: "[name].js",
    path: path.resolve(__dirname, "dist"),
    publicPath: '',
    assetModuleFilename: (pathData) => {
      const filepath = path
        .dirname(pathData.filename)
        .split("/")
        .slice(1)
        .join("/");
      return `${filepath}/[name].[hash][ext][query]`;
    },
  },
  mode: "development",
  module: {
    rules: [
      {
        test: /\.png/,
        type: "asset/resource",
      },
    ],
  },
};

我们获得输出目录结构:

⚡  tree -L 5 -I 'node_modules'
.
├── app
│   ├── assets
│   │   └── images
│   │       ├── topic1
│   │       │   └── icons8-apple-logo-16.png
│   │       └── topic2
│   │           └── icons8-itunes-store-16.png
│   └── index.js
├── dist
│   ├── assets
│   │   └── images
│   │       ├── topic1
│   │       │   └── icons8-apple-logo-16.eb98638de0872628930f.png
│   │       └── topic2
│   │           └── icons8-itunes-store-16.960fdc610bcb77ab473c.png
│   └── main.js
├── package-lock.json
├── package.json
└── webpack.config.js

执行 dist/main.js 的日志:

  node dist/main.js
appleLogo:  assets/images/topic1/icons8-apple-logo-16.eb98638de0872628930f.png
itunesLogo:  assets/images/topic2/icons8-itunes-store-16.960fdc610bcb77ab473c.png

webpack 版本:

"devDependencies": {
  "webpack": "^5.51.1",
  "webpack-cli": "^4.8.0"
}

运行得非常好!救了我的命。谢谢! - mupinnn
在我的情况下,由于某种原因,SVG文件也被复制到字体文件夹中,但我不希望它们出现在我的发布目录中,只想保留字体文件。有没有办法做到这一点? - Amit Pandey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接