kimono
@kimono
Web developer

Почему AssetConverter в Yii2 не может минифицировать чистый CSS?

Если сделать так:
class AppAsset extends AssetBundle
    {
        public $sourcePath     = '@common/assets/css';
        public $css            = [
            'styles.less',
            'foo.bar',
            'hello.css',
        ];
    }

и так:
'assetManager' => [
                'converter'       => [
                    'class'    => yii\web\AssetConverter::className(),
                    'commands' => [
                        'bar' => ['css', 'lessc {from} {to} --clean-css'],
                        'less' => ['css', 'lessc {from} {to} --clean-css --no-color'],
                    ],
                ],
            ],

то на сайте мы увидим подключение foo.css, причем минифицированного от foo.bar.
Но я не могу понять, почему если сделать так:
'assetManager' => [
                'converter'       => [
                    'class'    => yii\web\AssetConverter::className(),
                    'commands' => [
                        'css' => ['css', 'lessc {from} {to} --clean-css'], // добавим это
                        'bar' => ['css', 'lessc {from} {to} --clean-css'],
                        'less' => ['css', 'lessc {from} {to} --clean-css --no-color'],
                    ],
                ],
            ],

то ничего не происходит с исходным файлом hello.css. Ищу и не могу найти, от чего отнаследоваться и что изменить там, чтобы голые CSS тоже минифицировались?
  • Вопрос задан
  • 350 просмотров
Решения вопроса 1
kimono
@kimono Автор вопроса
Web developer
В общем выяснил дебагером, что все дело в этой строчке:
/**
     * Converts a given asset file into a CSS or JS file.
     * @param string $asset the asset file path, relative to $basePath
     * @param string $basePath the directory the $asset is relative to.
     * @return string the converted asset file path, relative to $basePath.
     */
    public function convert($asset, $basePath)
    {
        $pos = strrpos($asset, '.');
        if ($pos !== false) {
            $ext = substr($asset, $pos + 1);
            if (isset($this->commands[$ext])) {
                list ($ext, $command) = $this->commands[$ext];
                $result = substr($asset, 0, $pos + 1) . $ext;
                // все дело в этой проверке
                // |||||||||||||||||||||||||||||||||||||||||||
                // VVVVVVVVVVVVVVVVVV
                if ($this->forceConvert || @filemtime("$basePath/$result") < @filemtime("$basePath/$asset")) {
                    $this->runCommand($command, $basePath, $asset, $result);
                }

                return $result;
            }
        }

        return $asset;
    }

Когда мы публикуем foo.bar, то файл foo.bar копируется в assets с таким же именем. Затем, согласно $commands в AssetConverter, имя должно смениться на foo.css. А так как у нас пока еще foo.css не существует, то и filemtime('foo.css') = false, и если forceConvert = false, а ставить его в true имеет мало смысла, тогда и происходит запуск runCommand().
В случае с hello.css, он попадает в assets уже с расширением css, и если сравнить filemtime сорца и результата, то они будут равны, и никакой магии не произойдёт.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы