Is there any way in Angular app without ejecting webpack configuration to have inlined resources, as SVGs in CSS background properties?
I have already tried custom webpack builder to remove built-in file-loader rule and add uri-loader, but, SVGs are not inlined.
I suspect that it may be somehow related to internal SCSS/CSS processing using postcss.
As you said, url-loader
does not handle urls in style files. To do that, you need to use postcss-url
package.
To use a custom webpack configuration without ejecting, you need to install this package. After configuring your workspace with the directions provided in that package, you can use the following webpack configuration:
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;
};
Basically, this code adds postcss-url
plugin to every postcss-loader
in Angular's default webpack configuration.
You can edit this configuration to customize for your needs. For example, you can use maxSize
parameter to exclude files greater than a certain size. Read postcss-url
repo for all options.
EDIT by Zygimantas:
I am accepting your answer as correct and adding a Typescript version of 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
}
NOTE:
In Javascript version, I had to use x.loader.includes('postcss-loader')
instead of x.loader === 'postcss-loader'
because loader
value was a full path in my case.