【发布时间】: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