簡體   English   中英

Webpack 5 資產模塊(資產/資源)使所有 svg 消失

[英]Webpack 5 Asset Module (asset/resource) makes all svgs disapper

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'),
        },
    },
});

就我而言,似乎在使用type: 'asset/resource'時,模塊被導出為 commonjs 而不是 esmodule 的默認導入

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM