我遇到gulp-rev-all
的问题。我有以下基本的gulpfile:
var gulp = require('gulp'),
RevAll = require('gulp-rev-all'),
autoPrefixer = require('gulp-autoprefixer'),
rename = require('gulp-rename'),
sass = require('gulp-sass'),
sourceMaps = require('gulp-sourcemaps');
gulp.task('sass', function () {
var stream = gulp.src('./app/assets/stylesheets/application.scss')
.pipe(sourceMaps.init())
.pipe(sass({errLogToConsole: true}))
.pipe(autoPrefixer())
.pipe(rename("application.css"))
.pipe(sourceMaps.write("."))
.pipe(gulp.dest("./public/assets/stylesheets/"))
});
gulp.task('production', function() {
gulp.src('./public/*assets/**')
.pipe(RevAll.revision())
.pipe(gulp.dest('./public'))
.pipe(RevAll.versionFile())
.pipe(gulp.dest('./app/assets'));
});
gulp.task('default', ['sass', 'production']);
当我运行gulp时,它会因以下错误而爆炸:
Error: revision() must be called first!
但是当我删除生产任务并运行以下任务时,sass任务就像往常一样完成:
gulp.task('default', ['sass']);
在此任务创建文件后,将默认任务更改为包括生产任务将成功完成并创建指纹CSS文件。
当我再次吞下gulp时,它会做一些奇怪的事情:
第一个gulp任务(没有自豪任务)创建:
application.css (this task is idempotent)
然后我第一次使用生产执行gulp任务。该文件夹现在看起来像:
application.css
application.4434fcd5.css
然后我再次运行它,现在该文件夹看起来像:
application.css
application.4434fcd5.css
application.4434fcd5.4434fcd5.css
我认为这两个问题都源于生产任务中产生某种查找问题的问题。它是什么?
答案 0 :(得分:2)
(1)您的第一个问题是这一行:
gulp.task('default', ['sass', 'production']);
这并不是你认为它做的。它不会运行sass
任务,然后执行production
任务。它同时运行。
这意味着您的production
任务将在./public/
任务甚至在那里创建任何文件之前尝试修改sass
文件夹中的文件。由于没有文件,您最终会收到revision() must be called first!
错误消息。
您需要告诉gulp您production
任务中的sass
任务depends:
gulp.task('production', ['sass'], function() {
然后您需要从sass
任务返回流,以便gulp知道您的sass
任务has finished:
gulp.task('sass', function () {
var stream = gulp.src('./app/assets/stylesheets/application.scss')
//...
return stream;
});
(2)您的第二个问题是这一行:
gulp.src('./public/*assets/**')
这不仅仅与application.css
匹配,还与application.4434fcd5.css
匹配。因此,您已修订的文件将再次修订。
您可以通过不同方式解决此问题,但最简单的方法可能是每次运行./public
任务时使用del
删除整个sass
文件夹。
var del = require('del');
gulp.task('clean', function() {
return del('./public');
});
gulp.task('sass', ['clean'], function() {
//...
});
这样做的另一个好处是,当您的某个文件发生更改(导致不同的哈希值,因此文件名不同)时,您不会在./public/
文件夹中找到多个修订过的文件。
答案 1 :(得分:0)
我在吞咽方面不是很熟练,但是:
当我遇到这个问题时,我只需要在.pipe(revAll.revision())之后调用 .pipe(revDelete())。假设revDelete来自require('gulp-rev-delete-原始”)
执行上述操作,您将摆脱旧的哈希文件。该解决方案的问题是,每次运行任务时,文件名都将更长:application.4434fcd5.4434fcd5.css,application.4434fcd5.4434fcd5.4434fcd5.css,application.4434fcd5.4434fcd5.4434fcd5.4434fcd5.css等...要解决此问题,您可以检查文件是否已经有哈希,如果确实存在,则将其删除。为此,您可以将以下代码放在.pipe(revAll.revision())之前:
.pipe(gulpif(hasOldHash,重命名(filenameHashRegex,''))))。 hasOldHash是一种包含正则表达式的方法,该正则表达式与哈希格式匹配,如果文件已经具有旧哈希,则将其从文件名中删除。
好吧,这是太多的文字,我将使用代码总结所有内容:
// Imports
const gulp = require('gulp');
const revDelete = require('gulp-rev-delete-original');
const rename = require('gulp-regex-rename');
const gulpif = require('gulp-if');
const path = require('path');
const revAll = require("gulp-rev-all");
gulp.task('revall', function(){
const dest = 'src/app/commons/components';
// . + hash (8 exact alfanumeric characters), i.e.: test.a345fk39.js matches .a345fk39
const filenameHashRegex = ****TODO****
// Function that returns true if the filename has an old hash
const hasOldHash = function(file) {
const fileName = path.parse(file.path).name;
if(filenameHashRegex.test(fileName)){
console.log("***has old hash***");
return true;
}
};
return gulp.src('yourdesiredpath/**/*.{js,html}') // Source files to be hashed
.pipe(gulpif(hasOldHash, rename(filenameHashRegex, ''))) // If the filename contains and old hash, removes it to add the new one
.pipe(revAll.revision()) // Adds hash to the filename and update the references to that new hash
.pipe(revDelete()) // Deletes all inactive and out of date files, so you are left with only the most recent hashed file
.pipe(gulp.dest('yourdesiredpath')); // Final destinations where new hashed files are located
});