Как переписать URL-адреса изображений в файлах CSS-поставщиков с помощью Grunt

Я пытаюсь переместить внешние зависимости из системы управления версиями. Комбинация Bower.io и Grunt должна быть в состоянии сделать это.

Однако возникает проблема, которую я пока не могу решить, связав несколько библиотек поставщиков. Например, предположим, что у меня есть следующая структура каталогов, где каталог компонентов - это каталог, в котором Bower.io сохраняет зависимости в:

├── assets
└── components
    ├── bootstrap
    │   ├── img
    │   │   └── glyhs.gif
    │   └── less
    │       └── bootstrap.css
    └── jquery-ui
        ├── css
        │   └── style.css
        └── images
            ├── next.gif
            └── prev.gif

Теперь предположим, что я хочу связать jQuery style.css и Bootstrap bootstrap.css. Я сохраню этот связанный файл в assets/bundled.css.

Однако в этом файле ссылки на исходные изображения (../images/next.gif и.. /img/glyhs.gif) неверны. Они должны быть переписаны для работы (так../images/next.gif = > ../components/jquery-ui/images/next.gif). Я полагаю, что (d) это переписывание URL-адресов - это то, что должен сделать Грант. Но я не могу заставить это работать, используя задачи cssmin/less/copy. Например, следующая настройка Grunt (только перемещение 1 файла) не работает:

module.exports = function (grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        less: {
            options: {
                compile: false,
                relativeUrls: true
            },
            bootstrap: {
                src: 'components/bootstrap/less/bootstrap.less',
                dest: 'assets/bootstrap.css'
            }
        }
    });
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.registerTask('dist-css', ['less']);
};

Или:

  • Я неправильно сконфигурировал Grunt или сделал что-то не так?

  • Или рабочий процесс, который я описываю, просто не правильный, и я должен использовать другой.

Спасибо!

Ответ 1

Только для справки: теперь доступно решение. Я отправил эту же проблему в плагин CleanCss grunt, и они приняли это и опубликовали это поведение в своем новом выпуске версии 1.1.

Вы можете найти эту проблему на трекер GitHub здесь: https://github.com/GoalSmashers/clean-css/issues/129

Эта библиотека позволяет либо использовать абсолютную переписывание (из корневого каталога), либо изменять пути относительного образа на основе нового выходного каталога. Найдите директивы --root или --ouput.

Спасибо за советы и ответы людям!

Ответ 2

Вероятно, вы можете посмотреть этот пакет grunt https://github.com/Ideame/grunt-css-urls. Этот пакет, как представляется, предназначен для решения именно вашей проблемы.

Изменить: после просмотра этого плагина Мне не понравилась идея переписать мою разметку, чтобы сделать процесс сборки более плавным. Поэтому я закончил тем, что написал свою собственную крошечную функцию, которая меня переписывает.

Я использую grunt concat плагин для связывания моих файлов css. Хорошая вещь в этом плагине заключается в том, что перед конкатенацией он поддерживает функцию обработки файлов. Теперь мой файл grunt выглядит следующим образом:

grunt.initConfig({
concat: {
    options: {
    separator: '\n',
    process: function (src, filepath) {
        var cssPatt = new RegExp('app(\/.*\/).*\.css$');

        //filter out everithing except css files
        var file = cssPatt.exec(filepath);

        if (file) {
            var urlPatt = /url\(\'(.*)\'\)/g;

        console.log('In file: ' + filepath);

        //replace every url(...) with its absolute path
        return src.replace(urlPatt, function (match, p1) {
            console.log(' * ' + match + ' -> ' + 'url(\'' + file[1] + p1 + '\')');
            return 'url(\'' + file[1] + p1 + '\')';
        });
        }

        return src;
    }
    },
}

Ответ 3

Вам понадобится выполнить поиск/замену в файле dist css для создания правильных относительных путей. Есть несколько плагинов grunt, которые могут сделать это для вас, лично я предпочитаю grunt-replace. Настройте свои не сжатые активы с помощью переменных, а затем создайте dist css с динамически генерируемыми URL-адресами. Итак:

body {
    background:url(@@IMG_PATH/background.jpg);
}

Становится это в dist:

body {
    background:url(path/to/background.jpg);
}

Надеюсь, что это поможет.