【问题标题】:Webpack 5 Asset Module (asset/resource) makes all svgs disapperWebpack 5 Asset Module (asset/resource) 使所有 svgs 消失
【发布时间】:2022-10-05 16:20:52
【问题描述】:

Webpack 实际上不是我的强项,我今天遇到了一个问题,我完全卡在一个巨大的项目上。

基本上我只是运行了 webpack 分析器,我们的包太大了,因为我们的项目构建中有大约 200 个 SVG。 我想提出一个简单的解决方案来减小包大小并使用 webpack 压缩 SVG,因为这就是我们正在使用的。 在多次失败之后,我认为它会像包括在内一样简单

     test: /\\.(gif|png|jpe?g|svg)$/i,
     type: \'asset/resource\',
    },

我现在可以看到我的包显着减少了,但是当我加载项目时,我所有的 SVG 都被隐藏了。

可能是什么原因?还有什么是使用 Webpack 5 压缩 SVG 的替代方法???

这是整个 webpack 配置

const path = require(\'path\');
const MiniCssExtractPlugin = require(\'mini-css-extract-plugin\');
const ForkTsCheckerWebpackPlugin = require(\'fork-ts-checker-webpack-plugin\');
const SpriteLoaderPlugin = require(\'svg-sprite-loader/plugin\');
const { WebpackManifestPlugin } = require(\'webpack-manifest-plugin\');

const hashSubstr = \'.[contenthash:8]\';

const svgoPlugins = [
    { cleanUpAttrs: true },
    { removeDoctype: true },
    { removeXMLProcInst: true },
    { removeComments: true },
    { removeMetadata: true },
    { removeDesc: true },
    { removeEditorsNSData: true },
    { removeEmptyAttrs: true },
    { removeHiddenElems: true },
    { removeEmptyText: true },
    { removeEmptyContainers: true },
    { cleanupNumericValues: true },
    { moveElemsAttrsToGroup: true },
    { convertColors: { shorthex: true } },
];

module.exports = (env) => ({
    entry: [\'./scripts/responsive/index.ts\', \'./scripts/pwa/serviceworker.ts\'],
    output: {
        filename: `[name]${!env.development ? hashSubstr : \'\'}.js`,
        globalObject: \'this\',
        path: path.resolve(__dirname, \'./bundles/responsive\'),
        publicPath: \'/\',
        assetModuleFilename: \'[hash][ext][query]\',
    },
    mode: !env.development ? \'production\' : \'development\',
    devtool: \'inline-source-map\',
    optimization: {
        minimize: true,
    },
    module: {
        rules: [
            // {
            //  test: /\\.(gif|png|jpe?g|svg)$/i,
            //  type: \'asset/resource\',
            // },
            {
                test: /\\.(jsx?|tsx?)$/,
                loader: \'babel-loader\',
                options: {
                    presets: [\'@babel/typescript\', \'@babel/env\'],
                },
            },
            {
                test: /\\.s[ac]ss$/i,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader,
                        options: {
                            publicPath: \'../\',
                        },
                    },
                    {
                        loader: \'css-loader\',
                        options: {
                            sourceMap: true,
                        },
                    },
                    {
                        loader: \'sass-loader\',
                        options: {
                            sourceMap: true,
                        },
                    },
                ],
            },
            {
                test: /\\-colou?r\\.svg$/,
                type: \'asset/resource\',
                include: [path.resolve(__dirname, \'Content/responsive/svg\')],
                use: [
                    {
                        loader: \'svg-sprite-loader\',
                        options: {
                            spriteFilename: \'sprite.svg\',
                            esModule: false,
                            symbolId: (fileName) => {
                                return `r-icon-${path.basename(fileName, \'.svg\')}`;
                            },
                        },
                    },
                    {
                        loader: \'svgo-loader\',
                        options: {
                            plugins: svgoPlugins,
                        },
                    },
                ],
            },
            {
                test: /\\.svg$/,
                type: \'asset/resource\',
                exclude: /-colou?r\\.svg$/,
                include: [path.resolve(__dirname, \'Content/responsive/svg\')],
                use: [
                    {
                        loader: \'svg-sprite-loader\',
                        options: {
                            spriteFilename: \'sprite.svg\',
                            esModule: false,
                            symbolId: (fileName) => {
                                return `r-icon-${path.basename(fileName, \'.svg\')}`;
                            },
                        },
                    },
                    {
                        loader: \'svgo-loader\',
                        options: {
                            plugins: [
                                {
                                    removeAttrs: {
                                        attrs: \'(?!mask).*:(stroke|fill)\',
                                    },
                                },
                                ...svgoPlugins,
                            ],
                        },
                    },
                ],
            },
        ],
    },
    //stats: \'verbose\',
    plugins: [
        new ForkTsCheckerWebpackPlugin(),
        new WebpackManifestPlugin({
            fileName: \'asset-manifest.json\',
            generate: (seed, files) => {
                const manifestFiles = files.reduce((manifest, file) => {
                    manifest[file.name] = file.path;
                    return manifest;
                }, seed);

                const entrypointFiles = files
                    .filter((x) => x.isInitial && !x.name.endsWith(\'.map\'))
                    .map((x) => x.path);

                return {
                    files: manifestFiles,
                    entrypoints: entrypointFiles,
                };
            },
        }),
        new MiniCssExtractPlugin({
            // Options similar to the same options in webpackOptions.output
            // both options are optional
            filename: `css/[name]${!env.development ? hashSubstr : \'\'}.css`,
            chunkFilename: `css/[id]${!env.development ? hashSubstr : \'\'}.css`,
        }),
        new SpriteLoaderPlugin({
            plainSprite: true,
        }),
    ],
    resolve: {
        extensions: [\'.js\', \'.jsx\', \'.ts\', \'.tsx\'],
        alias: {
            Svg: path.resolve(__dirname, \'./Content/responsive/svg\'),
        },
    },
});

    标签: javascript webpack frontend


    【解决方案1】:

    就我而言,似乎在使用 type: 'asset/resource' 时,模块被导出为 commonjs 而不是 esmodule 的默认导入

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-28
      • 1970-01-01
      • 2022-07-02
      • 2020-05-02
      • 2013-10-07
      • 2013-12-31
      • 2014-04-24
      相关资源
      最近更新 更多