Angular встроенные ресурсы в css как data-uri - PullRequest
3 голосов
/ 05 августа 2020

Есть ли способ в приложении Angular без извлечения конфигурации веб-пакета иметь встроенные ресурсы, такие как SVG в CSS фоновых свойствах?

Я уже пробовал настраиваемый конструктор веб-пакетов для удаления встроенного файла - loader rule и добавьте uri-loader, но SVG не встроены.

Я подозреваю, что это может быть каким-то образом связано с внутренней обработкой SCSS / CSS с использованием post css.

1 Ответ

4 голосов
/ 08 августа 2020

Как вы сказали, url-loader не обрабатывает URL-адреса в файлах стилей. Для этого вам необходимо использовать postcss-url пакет .

Чтобы использовать настраиваемую конфигурацию веб-пакета без извлечения, вам необходимо установить этот пакет . После настройки вашей рабочей области с указаниями, предоставленными в этом пакете, вы можете использовать следующую конфигурацию веб-пакета:

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;
};

По сути, этот код добавляет плагин postcss-url к каждому postcss-loader в Angular по умолчанию конфигурация webpack.

Вы можете отредактировать эту конфигурацию, чтобы настроить ее под свои нужды. Например, вы можете использовать параметр maxSize, чтобы исключить файлы больше определенного размера. Прочтите postcss-url репо для всех опций.

EDIT by Zygimantas:

Я принимаю ваш ответ как правильный и добавляю версию TypeScript webpack.config.ts

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', потому что loader value в моем случае был полным путем.

...