Webpack 5 资产模块:如何保留输出文件夹中的文件夹结构?

obc*_*omv 9 assets webpack webpack-5

我尝试配置 Webpack 5,使其保留图像和字体的资源文件夹结构。

我有以下结构:

- /app
    /assets
        /images
            /topic1
            /topic2
        /fonts
Run Code Online (Sandbox Code Playgroud)

在我的 webpack 配置中,我已经配置了 Assets 模块,如下所示:

{
    test: /\.(png|svg|jpg|jpeg|gif|xml)$/i,
    type: 'asset/resource'
}
...
same for Font files...
Run Code Online (Sandbox Code Playgroud)

如果我运行 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 是否支持这样的开箱即用配置,或者我真的需要为此编写一些自定义函数吗?

感谢您的帮助和投入。

sli*_*wp2 21

您可以使用output.assetModuleFilename选项和 模板字符串来执行此操作。

\n

assetModuleFilename可以是一个函数。我们可以从得到filename类似的东西。然后,我们删除路径段。app/assets/images/topic1/icons8-apple-logo-16.pngpathData.filenameapp/

\n

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

\n

例如文件夹结构:

\n
\xe2\x9a\xa1  tree -L 5 -I \'node_modules\'\n.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 app\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 assets\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 images\n\xe2\x94\x82   \xe2\x94\x82       \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 topic1\n\xe2\x94\x82   \xe2\x94\x82       \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 icons8-apple-logo-16.png\n\xe2\x94\x82   \xe2\x94\x82       \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 topic2\n\xe2\x94\x82   \xe2\x94\x82           \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 icons8-itunes-store-16.png\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 index.js\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 package-lock.json\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 package.json\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 webpack.config.js\n\n5 directories, 6 files\n
Run Code Online (Sandbox Code Playgroud)\n

app/index.js

\n
import appleLogo from "./assets/images/topic1/icons8-apple-logo-16.png";\nimport itunesLogo from "./assets/images/topic2/icons8-itunes-store-16.png";\n\nconsole.log("appleLogo: ", appleLogo);\nconsole.log("itunesLogo: ", itunesLogo);\n
Run Code Online (Sandbox Code Playgroud)\n

webpack.config.js

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

我们得到输出目录结构:

\n
\xe2\x9a\xa1  tree -L 5 -I \'node_modules\'\n.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 app\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 assets\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 images\n\xe2\x94\x82   \xe2\x94\x82       \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 topic1\n\xe2\x94\x82   \xe2\x94\x82       \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 icons8-apple-logo-16.png\n\xe2\x94\x82   \xe2\x94\x82       \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 topic2\n\xe2\x94\x82   \xe2\x94\x82           \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 icons8-itunes-store-16.png\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 index.js\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dist\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 assets\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 images\n\xe2\x94\x82   \xe2\x94\x82       \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 topic1\n\xe2\x94\x82   \xe2\x94\x82       \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 icons8-apple-logo-16.eb98638de0872628930f.png\n\xe2\x94\x82   \xe2\x94\x82       \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 topic2\n\xe2\x94\x82   \xe2\x94\x82           \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 icons8-itunes-store-16.960fdc610bcb77ab473c.png\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 main.js\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 package-lock.json\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 package.json\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 webpack.config.js\n
Run Code Online (Sandbox Code Playgroud)\n

执行日志dist/main.js

\n
\xe2\x9a\xa1  node dist/main.js\nappleLogo:  assets/images/topic1/icons8-apple-logo-16.eb98638de0872628930f.png\nitunesLogo:  assets/images/topic2/icons8-itunes-store-16.960fdc610bcb77ab473c.png\n
Run Code Online (Sandbox Code Playgroud)\n

网页包版本:

\n
\xe2\x9a\xa1  node dist/main.js\nappleLogo:  assets/images/topic1/icons8-apple-logo-16.eb98638de0872628930f.png\nitunesLogo:  assets/images/topic2/icons8-itunes-store-16.960fdc610bcb77ab473c.png\n
Run Code Online (Sandbox Code Playgroud)\n