usemin и перезапись URL изображений в файлах CSS поставщика с помощью Grunt
grunt-usemin помогает мне трансформироваться
<link href="/dependencies/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" />
<link href="/dependencies/nanoscroller/bin/css/nanoscroller.css" rel="stylesheet" />
<link href="/dependencies/dropzone/downloads/css/dropzone.css" rel="stylesheet" />
в идеально комбинированный и минимизированный JS:
<link href="scripts/8e1991c7.libraries.js" rel="stylesheet" />
После concat, cssmin и uglify у меня почти идеальная структура папок, за исключением изображений и их расположения.
Вот моя проблема:
Все CSS-файлы этих поставщиков включают в себя расположение изображений. Плохо то, что все они живут в разных местах. Некоторые из них используют изображения внутри папки css, тогда как другие используют внутри папки img.
Как я могу настроить grunt usemin для перезаписи всех URL-адресов изображений?
6 ответов
1) Rev изображений. Добавьте пути изображений в задачу rev.
rev: {
dist: {
files: {
src: [
'<%= yeoman.dist %>/static/scripts/{,*/}*.js',
'<%= yeoman.dist %>/static/styles/{,*/}*.css',
'<%= yeoman.dist %>/static/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
]
}
}
}
2) Добавьте пути к файлам, которые включают в себя расположение изображений, в задачу usemin.
usemin: {
html: ['<%= yeoman.dist %>/{,*/}*.html'],
css: ['<%= yeoman.dist %>/static/styles/{,*/}*.css'],
options: {
assetsDirs: ['<%= yeoman.dist %>','<%= yeoman.dist%>/static/images'],
}
}
3) Беги крякнув.
Я решил проблему, используя следующее.
useminPrepare: {
html: 'src/index.html',
options: {
dest: 'build',
flow: {
html: {
steps: {
js: ['concat', 'uglifyjs'],
css: ['cssmin']
},
post: {}
}
}
}
},
cssmin: {
options: {
root: 'src'
}
}
Во-первых, мы переопределяем useminPrepare
"s flow
удаление задачи concat из потоков css. Это необходимо, потому что concat уничтожит информацию об относительном пути. Поскольку cssmin сам объединяет несколько файлов, задача sepearte concat только вредна. ( https://github.com/yeoman/grunt-usemin/issues/225)
Наконец, мы говорим cssmin
где "корень" вашего проекта находится в Gruntfile. Это помогает cssmin
переписать относительные URL-адреса, которые он находит относительно этого "корневого" каталога.
Что исправило CSS background-image
Революция для меня была добавить шаблон CSS в options
, который находит все ссылки на активы в CSS и заменяет их на обновленные активы.
// Performs rewrites based on rev and the useminPrepare configuration
usemin: {
...
...
options: {
...
...
// This is so we update image references in our ng-templates
patterns: {
js: [
[/(assets\/images\/.*?\.(?:gif|jpeg|jpg|png|webp|svg))/gm, 'Update the JS to reference our revved images']
],
css: [
[/(assets\/images\/.*?\.(?:gif|jpeg|jpg|png|webp|svg))/gm, 'Update the CSS to reference our revved images']
]
}
}
},
Мне пришлось реализовать новую задачу. Это моя предварительная реализация.
grunt.registerMultiTask('rewriteCssUrl', 'rewrite url in css', function () {
var options = this.options({
assets: grunt.filerev ? grunt.filerev.summary : {},
postFilter: function identity(input){ return input}
});
var self = this;
var assets = options.assets;
self.filesSrc.forEach(function (file) {
var css = grunt.file.read(file);
var original = css;
css = css.replace(/(?:src=|url\(\s*)['"]?([^'"\)]+)['"]?\s*\)?/gm, function (match, src) {
var key = path.join(path.dirname(file), src);
var asset = assets[path.normalize(key)];
var val = options.postFilter(asset);
return match.replace(src, val || match);
});
if(original !== css) {
grunt.log.writeln('✔ '.green + file + (' was changed.').grey);
grunt.file.write(file, css);
}
});
});
Я немного покопался и нашел пару задач, которые выглядят так, как будто они выполнят свою работу: https://github.com/yeoman/grunt-filerev & https://github.com/richardbolt/grunt-cssurlrev, Единственная проблема заключается в том, что вам придется настраивать пути внутри вашего Gruntfile вручную, например так:
grunt.initConfig({
filerev: {
images: {
src: ['img1.png', 'img2.png'],
dest: 'tmp'
}
},
cssurlrev: {
dist: {
src: ['public/css/*.css']
},
}
});
Насколько мне известно, нет плагина, который выполняет эту задачу автоматически.
Мой подход к этой проблеме заключался в создании отдельного styles/select2/select2.css
для каждого поставщика, а затем все соответствующие изображения могут быть скопированы Grunt в styles/select2
(без необходимости беспокоиться об относительных путях или перезаписи и т. д.) как часть сценария. То есть:
Приложение / index.html
<!-- build:css(.tmp) styles/select2/select2.css -->
<link rel="stylesheet" href="bower_components/select2/select2.css">
<!-- endbuild -->
Gruntfile.js
Добавить новый copy
задача, которая скопирует стили вендора в .tmp
каталог, прежде чем они свернуты с cssmin
:
copy: {
// this copies bower_components/*.css into .tmp so they can be compiled
styles: {
expand: true,
cwd: '<%= yeoman.app %>',
dest: '.tmp/',
src: [
'styles/{,*/}*.css',
'bower_components/**/*.css'
]
},
dist: ...
И затем, как только они будут свернуты, скопируйте соответствующие ресурсы (которые в данном случае, я полагаю, являются просто изображениями в формате PNG и GIF):
// and once we have compiled all of our stylesheets, we need to also copy over any necessary image files
distAssets: {
expand: true,
cwd: '<%= yeoman.app %>/bower_components',
dest: '<%= yeoman.dist %>/styles',
src: [
'**/*.png',
'**/*.gif'
]
}
},
Наконец, добавьте новые задачи в build
задача:
grunt.registerTask('build', [
'clean:dist',
'replace:dist',
'copy:styles', // -- added
'useminPrepare',
// ... etc ...
'copy',
'rev',
'usemin',
'copy:distAssets' // -- added
]);