3

在 Angular 应用程序中是否有任何方法无需弹出 webpack 配置来拥有内联资源,如 CSS 背景属性中的 SVG?

我已经尝试过自定义 webpack 构建器来删除内置的文件加载器规则并添加 uri-loader,但是 SVG 没有内联。

我怀疑它可能与使用 postcss 的内部 SCSS/CSS 处理有关。

4

1 回答 1

5

如您所说,url-loader不处理样式文件中的网址。为此,您需要使用postcss-urlpackage

要在不弹出的情况下使用自定义 webpack 配置,您需要安装此包。使用该包中提供的说明配置您的工作区后,您可以使用以下 webpack 配置:

const url = require('postcss-url');    
const urlPlugin = url([{ filter: '**/*.svg', url: 'inline' }]);
    
module.exports = config => {
  for (const rule of config.module.rules) {
      const loader = rule.use && rule.use.find(x => x.loader === 'postcss-loader');
      if (loader) {
          loader.options.plugins = [urlPlugin];
      }
  }
    
  return config;
};

基本上,这段代码在 Angular 的默认 webpack 配置中添加了postcss-url插件。postcss-loader

您可以编辑此配置以根据您的需要进行自定义。例如,您可以使用maxSize参数排除大于特定大小的文件。阅读所有选项的postcss-url回购

Zygimantas 编辑:

我接受你的回答是正确的,并添加了 webpack.config.ts 的 Typescript 版本

import { Configuration, NewLoader } from 'webpack'
import * as PostCssUrlPlugin from 'postcss-url'

export default (config: Configuration) => {
    if (config.module === undefined) {
        throw new Error()
    }

    let patched = false
    for (const rule of config.module.rules) {
        if ('use' in rule && Array.isArray(rule.use)) {
            const loader = rule.use.find(
                (a): a is NewLoader =>
                    typeof a !== 'string' &&
                    'options' in a &&
                    a.loader !== undefined &&
                    a.loader.includes('postcss-loader'),
            )

            if (loader !== undefined && loader.options !== undefined) {
                loader.options.plugins = [PostCssUrlPlugin([{
                  filter: '**/*.svg',
                  url: 'inline',
                }])]

                patched = true
            }
        }
    }

    if (!patched) {
        throw new Error('Could not patch webpack configuration')
    }

    return config
}

笔记:

在 Javascript 版本中,我必须使用x.loader.includes('postcss-loader')而不是x.loader === 'postcss-loader'因为loadervalue 在我的情况下是完整路径。

于 2020-08-08T16:34:52.343 回答