文件加载器保存每个文件夹的图像,例如Project/Module/src/img/example.jpg 到 Project/Module/dist/img/example.jpg

file-loader save images per folder e.g. Project/Module/src/img/example.jpg to Project/Module/dist/img/example.jpg

您好,我正在尝试创建一个 Webpack 配置,为该项目中的每个文件夹生成文件。为每个文件夹创建 webpack.config 不是 一个选项。

我有一个 index.html,JS 和 SASS 都处理好了。下一步是图像,我正在努力处理它。


目前发生的情况是:

cd /MyProject/ && npm run build

这个文件夹里面有'modules',每个模块都是一个文件夹。


来源:

/MyProject/MyModule/src/js/app.js

/MyProject/MyModule/src/scss/app.scss

/MyProject/MyModule/src/index.html

/MyProject/MyModule/src/img/example1.jpg

距离:

MyProject/MyModule/dist/(app.css|app.js|index.html|img/example1.jpg)


我的问题

保存图像时,以下面当前的方式,

name: '[path]../../dist/img/[name].[ext]'

我的 HTML 输出是这样的: <img src="/MyModule/src/img/../dist/img/screenshot.png" alt="Screenshot">

理解为什么会发生这种情况,但我不知道有什么更好的方法。

如果我删除 [path] 它当然会保存在 MyProject 而不是 MyModule 中,这是我不想要的。

webpack.config.js

const entryPlus = require('webpack-entry-plus');
const glob = require('glob');
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const fs = require('fs');

const htmlList_exclusions = [
    'node_modules'
]

const htmlList = []
const imgList = []

const files = fs.readdirSync(__dirname)

files.forEach(file => {
    var filePath = path.join(__dirname, file);
    var isDir = fs.statSync(filePath).isDirectory();
    if(isDir && !file.startsWith('.') && !file.startsWith('_') && !htmlList_exclusions.includes(file)) {
        htmlList.push(filePath + '/src/index.html')

    }
});

const entryFiles = [
    {
        entryFiles: glob.sync('./*/src/js/app.js'),
        outputName(item) {
            return item.replace('src/js/', 'dist/').replace('.js', '').replace('./', '');
        },
    },
];


const plugins = [
    new MiniCssExtractPlugin({
        // Options similar to the same options in webpackOptions.output
        // both options are optional
        // path: '[folder]tes',
        filename: '[name].css',
    })
]

for(var i in htmlList) {
    plugins.push( new HtmlWebpackPlugin({ 
        template: htmlList[i],
        filename: htmlList[i].replace('src/', '/'),
    }));
}

module.exports = {
    watch: true,
    entry: entryPlus(entryFiles),
    output: {
        path: path.resolve(__dirname, './'),
        filename: '[name].js',
        publicPath: '/',
    },
    module: {
        rules: [
            {
                test: /\.(sa|sc|c)ss$/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader,
                        options: {
                            // you can specify a publicPath here
                            // by default it use publicPath in webpackOptions.output
                            // publicPath: '../',
                            sourceMap: false,
                        }
                    },
                    "css-loader", "sass-loader"
                ]
            },
            {
              test: /\.js$/,
              exclude: /(node_modules)/,
              use: {
                loader: 'babel-loader',
                options: {
                  presets: ['@babel/preset-env'],
                  plugins: ['@babel/plugin-proposal-object-rest-spread', '@babel/plugin-transform-runtime']
                }
              }
            },
            {
                test: /\.html$/,
                use: ['html-loader'],
            },
            {
                test: /\.(jpg|png|gif)$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            name: '[path]../dist/img/[name].[ext]',
                            outputPath: '',
                            publicPath: '/',
                        }
                    }
                ]
            }
        ]
    },
    plugins,
    resolve: {
        alias: {
            globalscss: path.resolve(__dirname, './_global/scss/'),
        }
    }
}

我会为更好的 RegExp 而努力,但我使用了以下解决方案

        {
            test: /\.(jpg|png|gif|svg)$/,
            use: [
                {
                    loader: 'file-loader',
                    options: {
                        regExp: /([^[=10=]]+)\/([^[=10=]]+)\/([^[=10=]]+)\/([^[=10=]]+)\/([^[=10=]]+)\.(jpg|png|gif|svg)$/,
                        name: '[2]/dist/img/[name].[ext]',
                        outputPath: '',
                        publicPath: '/',
                    }
                }
            ]
        }