How do I pre / post process aggregated css or js files?
Using dependency injection we are able to inject a modified Asset Dumper, which can contain custom code.

Add to a custom module / or create a new module:

mymodule/mymodule.services.yml

services:
  asset.css.dumper:
    class: Drupal\mymodule\Asset\Utf8CssAssetDumper
  asset.css.collection_optimizer:
      class: Drupal\Core\Asset\CssCollectionOptimizer
      arguments: [ '@asset.css.collection_grouper', '@asset.css.optimizer', '@asset.css.dumper', '@state' ]


mymodule/src/Asset/Utf8CssAssetDumper.php

&lt;?php
namespace Drupal\mymodule\Asset;

/**
 * Dumps a CSS asset and injects a utf-8 encoding string at beginning.
 */
class Utf8CssAssetDumper extends \Drupal\Core\Asset\AssetDumper {

  /**
   * {@inheritdoc}
   *
   * Injects utf-8 encoding statement at start of data string.
   */
  public function dump($data, $file_extension) {
    if ($file_extension == 'css') {
      // Don't override existing charsets.
      if (FALSE === strpos($data,'@charset ')) {
        // Charset string not found prepend.
        $data = "@charset \"UTF-8\";\n" . $data;
      }
    }
    return parent::dump($data, $file_extension);
  }
}


A short note on this: since this kicks in for all aggregated css files you might want to add additional checks to existing encodings etc.. If you have everything encoded the same way (which is very much suggestible) then this shouldn't cause weird side effects.

This approach also works for javascript (js) files:

services:
  asset.js.dumper
  asset.js.collection_optimizer