简体   繁体   English

Gulp-rev-all每次运行都会创建新文件

[英]Gulp-rev-all is creating new files on each run

I've got a problem with gulp-rev-all . 我对gulp-rev-all有问题。 I have the following basic gulpfile: 我有以下基本的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']);

Expectation vs. reality 期望与现实

When I run gulp, it bombs out with the following error: 当我运行gulp时,它炸毁并显示以下错误:

Error: revision() must be called first!

But when I remove the production task and run the following then the sass task finishes as usual: 但是,当我删除生产任务并运行以下命令时,sass任务照常完成:

gulp.task('default', ['sass']);

After this task has created the files, changing the default task back to include the production task will successfully finish and create a fingerprinted CSS file. 在此任务创建文件之后,将默认任务改回为包含生产任务将成功完成并创建指纹CSS文件。

When I run gulp again it does something strange: 当我再次运行gulp时,它做了一些奇怪的事情:

  1. First gulp task (without proudction task) creates: 第一个gulp任务(无骄傲任务)创建:

    application.css (this task is idempotent) application.css (this task is idempotent)

  2. Then I run the gulp task with production for the first time. 然后,我第一次在生产中运行gulp任务。 The folder now looks like: 该文件夹现在看起来像:

    application.css application.css

    application.4434fcd5.css application.4434fcd5.css

  3. Then I run it again and now the folder looks like: 然后我再次运行它,现在文件夹看起来像:

    application.css application.css

    application.4434fcd5.css application.4434fcd5.css

    application.4434fcd5.4434fcd5.css application.4434fcd5.4434fcd5.css

The problem 问题

I think both problems stem from something in the production task creating some sort of look up issue. 我认为这两个问题都源于生产任务中的某些问题,从而造成了某种查找问题。 What is it? 它是什么?

(1) Your first problem is this line: (1)您的第一个问题是这条线:

gulp.task('default', ['sass', 'production']);

This doesn't do what you think it does. 这并没有按照您的想法做。 It doesn't run the sass task and then the production task. 它不会先执行sass任务,再执行production任务。 It runs both at the same time. 它同时运行。

That means that your production task will try to revision files in your ./public/ folder before your sass task has even created any files there. 这意味着您的production任务将在您的sass任务甚至在此创建任何文件之前尝试修订./public/文件夹中的文件。 Since there are no files you end up with the revision() must be called first! 由于没有文件,因此revision() must be called first!带有revision() must be called first!文件revision() must be called first! error message. 错误信息。

You need to tell gulp that your production task depends on your sass task: 您需要告诉gulp您的production任务取决于您的sass任务:

gulp.task('production', ['sass'], function() {

And then you need to return the stream from your sass task so that gulp knows when your sass task has finished : 然后,您需要从sass任务返回流,以便gulp知道您的sass任务何时完成

gulp.task('sass', function () {
  var stream = gulp.src('./app/assets/stylesheets/application.scss')
  //...
  return stream;
});

(2) Your second problem is this line: (2)您的第二个问题是这一行:

gulp.src('./public/*assets/**')

This doesn't just match application.css , but also application.4434fcd5.css . 这不只是比赛application.css ,也application.4434fcd5.css So your already-revisioned files are revisioned again . 因此,您已经修订的文件将再次被修订。

You can solve this in different ways, but the easiest is probably to just delete your entire ./public folder every time you run your sass task (using del ). 您可以用不同的方法解决此问题,但最简单的方法可能是每次运行sass任务时都删除整个./public文件夹(使用del )。

var del = require('del');

gulp.task('clean', function() { 
  return del('./public');
});

gulp.task('sass', ['clean'], function() {
  //...
});

This has the added benefit that you don't end up with multiple revisioned files in your ./public/ folder when one of your files changes (which results in a different hash and therefore a different file name). 这样做还有一个好处,就是当其中一个文件发生更改时,您./public/./public/文件夹中最终拥有多个修订过的文件(这将导致不同的哈希值,因此也将产生不同的文件名)。

I'm not very expert in gulp but: 我在吞咽方面不是很熟练,但是:

When I faced that problem I just had to call .pipe(revDelete()) after .pipe(revAll.revision()) supposing revDelete comes from require('gulp-rev-delete-original') 当我遇到这个问题时,我只需要在.pipe(revAll.revision())之后调用.pipe(revDelete()),假设revDelete来自require('gulp-rev-delete-original')

Doing above you will get rid of the old hashed files. 在上面做,您将摆脱旧的哈希文件。 Problem with that solution is that every time you run the task you will have longer filenames application.4434fcd5.4434fcd5.css, application.4434fcd5.4434fcd5.4434fcd5.css, application.4434fcd5.4434fcd5.4434fcd5.4434fcd5.css, and so on... To solve this issue you can check if the file has already a hash or not, and in the positive case you remove it. 该解决方案的问题在于,每次运行任务时,文件名都将更长:application.4434fcd5.4434fcd5.css,application.4434fcd5.4434fcd5.4434fcd5.css,application.4434fcd5.4434fcd5.4434fcd5.4434fcd5.css等...要解决此问题,您可以检查文件是否已经有哈希,如果确实存在,则将其删除。 To achieve that you can put the following code before .pipe(revAll.revision()): 为此,可以将以下代码放在.pipe(revAll.revision())之前:

.pipe(gulpif(hasOldHash, rename(filenameHashRegex, ''))). .pipe(gulpif(hasOldHash,重命名(filenameHashRegex,``))))。 hasOldHash is a method that contains a Regular Expression that matches the hash format and removes it from the filename if the file already have an old hash. hasOldHash是一种包含正则表达式的方法,该正则表达式与哈希格式匹配,如果文件已经具有旧哈希,则将其从文件名中删除。

Ok that was too much text, I will summarize everything using code: 好的,那是太多的文字,我将使用代码总结所有内容:

// 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
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM