Grunt usemin, получить окончательный путь к сжатым файлам, чтобы разрешить предварительную загрузку

У меня есть такой блок HTML для минимизации файлов css и js:

<!-- build:css static/assets/css/combined.css -->
<link rel="stylesheet" href="static/bower_components/font-awesome/css/font-awesome.css">
<link rel="stylesheet" href="static/bower_components/photoswipe/dist/photoswipe.css" />
<link rel="stylesheet" href="static/bower_components/photoswipe/dist/default-skin/default-skin.css" />
<link rel="stylesheet" href="static/assets/css/jasny-bootstrap.min.css">
<link rel="stylesheet" href="static/assets/css/main.min.css">
<link rel="stylesheet" href="static/assets/css/custom.css">
<link rel="stylesheet" href="static/common/da-angular-spinkit/angular-spinkit.min.css">
<!-- endbuild -->

Мне нужно сделать предварительную загрузку ресурса static/assets/css/combined.css, но в конце имени конечного файла стоит хэш, поэтому конечный путь похож на static/assets/css/combined.min-af5890ce41.css, поэтому я не знаю, как включить следующий тег:

<link rel="preload" href="static/assets/css/combined.min-af5890ce41.css"/>
 -------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^

Потому что я не знаю, каково окончательное имя сгенерированного мини-файла.

Как я могу получить вывод этого сгенерированного файла? Мне нужно только окончательное имя пути. Я ищу о grunt-usemin, но он кажется "минималистичным".

Спасибо.

РЕДАКТИРОВАТЬ

Я нашел на проекте несколько кусков кода grunt, если вы можете увидеть, какой модуль действует на хэши файлов:

/client/static/bower_components/bootstrap/Gruntfile.js:

Здесь я вижу:

  • джшинт
  • уродовать
  • меньше
  • csslint
  • cssmin
  • csscomb
  • htmlмин

Я не вижу, какой из этих модулей действует на build:js или build:css в index.html.

/client/static/bower_components/photoswipe/Gruntfile.js:

Здесь я вижу задачи npm:

  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-sass');
  grunt.loadNpmTasks('grunt-autoprefixer');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-jekyll');
  grunt.loadNpmTasks('grunt-contrib-cssmin');
  grunt.loadNpmTasks('grunt-aws-s3');
  grunt.loadNpmTasks('grunt-svgmin');

РЕДАКТИРОВАТЬ 2

В папке /dev/ есть файл gruntfile.js с этим кодом (вроде не связанный):

var src = "../src/client/";

module.exports = function (grunt) {
    grunt.loadNpmTasks("grunt-angular-gettext");

    // We extract translations with 'grunt nggettext_extract'. Those files go to '/dev/translations-extract' directory.
    grunt.initConfig({
        nggettext_extract: {
            pot: {
                files: {
                    'translations-extract/template.pot': [src + 'static/common/**/*.html', src + 'static/states/**/*.html', src + 'index.html', src + 'indexMobile.html']
                }
            },
        },
        // We compile those files (*.po) with 'grunt nggettext_compile. The translations.js file goes to /client/static/util/translations/ dir.
        nggettext_compile: {
            all: {
                options: {
                    module: 'alvarez',
                },
                files: {
                    '../src/client/static/common/translations/translations.js': ['translations-extract/*.po']
                }
            },
        },
    })
}

И потом, на /dev/bower_components/ есть куча плагинов, каждый со своим gruntfile.js внутри.

РЕДАКТИРОВАТЬ 3

Найдено на /ops/ файле gulpfile.js и, похоже, связано

/**
 * Crea una versión de distribución concatenada y minificada
 */

var gulp = require('gulp');
var run = require('gulp-run');
var gulpif = require('gulp-if');
var useref = require('gulp-useref');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var debug = require('gulp-debug');
var del = require('del');
var ngAnnotate = require('gulp-ng-annotate');
var minifyHTML = require('gulp-minify-html');
var cleanCSS = require('gulp-clean-css');
var rev = require('gulp-rev');
var revReplace = require('gulp-rev-replace');
var embedTemplates = require('./embed-templates/index.js');
var dist = './dist/';
var indexDist = dist + 'client/';
var HTMLDist = indexDist + 'static/';
var src = '../src/';
var assetsSrc = src + 'client/static/assets/'
var cssSrc = assetsSrc + 'css/';
var serverDist = dist + 'server/';
var libDist = dist + 'lib/';

// pm2
// Init-dist
gulp.task('pm2', function () {
    run('pm2 start ' + serverDist + 'alvarez.js').exec();
});

// Init-stop
gulp.task('pm2-stop', function () {
    run('pm2 stop ' + serverDist + 'alvarez.js').exec();
});

//Init-restart
gulp.task('pm2-restart', function () {
    run('pm2 restart ' + serverDist + 'alvarez.js').exec();
});

// npm-install on dist
gulp.task('npm-install-dist', function () {
    run('npm install --production --prefix ' + serverDist).exec();
})

// Dist subtasks

// Cleaning dist
gulp.task('del-dist', function () {
    del(dist, {
        force: true
    }, console.log('Files deleted'));
});

// Moving index.js
gulp.task('move-server-js', function () {
    return gulp.src([src + 'server/alvarez.js', src + 'server/package.json'])
        .pipe(gulp.dest(serverDist));
});

gulp.task('move-config-js', function () {
    return gulp.src([src + 'server/lib/**/*.js'])
        .pipe(gulp.dest(serverDist + 'lib/'))
})

//gulp.task('move-lib-js', function () {
//    return gulp.src(src + 'lib/config.js')
//        .pipe(gulp.dest(libDist));
//});
//
//gulp.task('move-boot-pro', function () {
//    return gulp.src(src + 'lib/boot.pro.js')
//        .pipe(rename('boot.js'))
//        .pipe(gulp.dest(libDist));
//})

// Moving html
gulp.task('move-html', function () {
    var opts = {
        empty: true
    };
    return gulp.src([src + 'client/static/**/**/*.html', src + 'client/static/**/**/*.swf'])
        .pipe(minifyHTML(opts))
        .pipe(gulp.dest(HTMLDist));
});

gulp.task('minify-css', ['move-assets', 'move-html-index', 'move-html-index-mobile'], function() {
    return gulp.src(HTMLDist + 'assets/css/*.css')
        .pipe(cleanCSS())
        .pipe(gulp.dest(HTMLDist + 'assets/css/'));
})

gulp.task('move-assets', function () {
    return gulp.src(src + '/client/static/assets/**/*.*')
        .pipe(gulp.dest(HTMLDist + 'assets/'));
});

// Moving html index
gulp.task('move-html-index', function () {
    var assets = useref.assets();
    //.pipe(gulpif('**\/da-*.js', embedTemplates()))
    return gulp.src(src + 'client/index.html')
        .pipe(assets)
        .pipe(gulpif('*.js', embedTemplates()))
        .pipe(gulpif('.*\.js', ngAnnotate()))
        .pipe(gulpif('.*\.js', uglify()))
        .pipe(rev())
        .pipe(assets.restore())
        .pipe(useref())
        .pipe(revReplace())
        .pipe(debug())
        .pipe(gulp.dest(indexDist));
});

gulp.task('move-html-index-mobile', function () {
    var assets = useref.assets();
    return gulp.src(src + 'client/indexMobile.html')
        .pipe(assets)
        .pipe(gulpif('*.js', embedTemplates()))
        .pipe(gulpif('.*\.js', ngAnnotate()))
        .pipe(gulpif('.*\.js', uglify()))
        .pipe(assets.restore())
        .pipe(useref())
        .pipe(gulp.dest(indexDist));
})

gulp.task('embed-templates', [], function () {
    return gulp.src([src + 'client/static/states/**/da*/*.js', src + 'client/static/common/**/da*/*.js'])
        .pipe(gulpif('*.js', embedTemplates()))
        .pipe(ngAnnotate())
        .pipe(uglify())
        .pipe(gulp.dest(indexDist))
});

// Build dist task
gulp.task('build-dist', ['move-html', 'move-server-js', 'move-config-js', 'minify-css'], function () {
    console.log('Dist ready...');
});

person Marcos Pérez Gude    schedule 09.05.2018    source источник
comment
Пожалуйста, опубликуйте содержание Gruntfile.js   -  person muecas    schedule 09.05.2018
comment
@muecas Готово, код обновлен, скажите, если вам нужно больше.   -  person Marcos Pérez Gude    schedule 09.05.2018
comment
Нет, это Gruntfile.js не имеет отношения к проблеме. Может быть, вы можете проверить все файлы Gruntfile.js в вашем проекте. Или просто опубликуйте содержимое этого /client/static/bower_components/photoswipe/Gruntfile.js. Возможно, у вас есть другие Gruntfile.js, которые контролируют этот вопрос.   -  person muecas    schedule 09.05.2018
comment
Да, моя главная проблема в том, что я не могу найти правильный gruntfile. У меня прошло два дня с поиском, это потому, что я решил спросить на stackoverflow, LOL. Я приложу усилия, чтобы найти правильный gruntfile.   -  person Marcos Pérez Gude    schedule 09.05.2018
comment
Ха-ха, это будет здорово. Найдите все Gruntfile.js во всем проекте. Вам нужно будет проверить все файлы.   -  person muecas    schedule 09.05.2018
comment
Вместо этого я нашел gulpfile.js и, похоже, связан. Возможно ли, что эта задача выполнялась gulp вместо grunt?   -  person Marcos Pérez Gude    schedule 09.05.2018
comment
Конечно! Разместите это!   -  person muecas    schedule 09.05.2018
comment
Я нашел var rev = require('gulp-rev'); var revReplace = require('gulp-rev-replace');, может быть, наконец-то это нужное место. Я предполагаю, что мне нужно удалить этот rev, чтобы имена файлов были без хэшей, да?   -  person Marcos Pérez Gude    schedule 09.05.2018
comment
Да, вы можете удалить .pipe(rev()) и .pipe(revReplace()), чтобы удалить замену версии. Но это повлияет на файловый кеш.   -  person muecas    schedule 09.05.2018
comment
Я придумаю что-нибудь другое для кеша. Возможно смесь из сервера и клиента, и не только по именам файлов. Задача предварительной загрузки более важна, чем кеширование javascript, потому что мы управляем кешем на стороне сервера, и теги expires прекрасно настроены. Тем не менее, спасибо, что поставили меня на правильный путь. Я потерял время на поиски хрюка, когда мне нужно глотнуть!! Я новичок в angular/grunt/node, поэтому мне нужно больше времени, чтобы научиться. Большое спасибо!!   -  person Marcos Pérez Gude    schedule 09.05.2018
comment
@muecas хорошо, я нашел это, это работает, и теперь я могу выполнить задачу, если глоток позволит мне ахахаха. Мне нужно ввести предварительную загрузку, но задача найти правильный файл (2 дня потеряна) выполнена! Спасибо. PD: Может быть, я обновлю этот вопрос или, может быть, открою новый.   -  person Marcos Pérez Gude    schedule 09.05.2018
comment
Хорошо, дай мне знать! Осталась задача заменить файл в preload?   -  person muecas    schedule 09.05.2018
comment
Да, я попробую, когда gulp введет тег <script src="combined.js">, я могу ввести перед тегом <link rel="preload" href="combined.js"> с правильным путем.   -  person Marcos Pérez Gude    schedule 10.05.2018


Ответы (1)


Ответ не в grunt-usemin, а в одной из зависимостей: grunt-filerev. Этот последний модуль используется для создания ревизий ваших файлов css, js и других файлов.

После выполнения grunt-filerev (выполняется как подзадача grunt-usemin) создается сводка (хранящаяся в вашей основной задаче под grunt.filerev.summary). Резюме содержит следующую информацию:

{
   “original.js” : “destination.59bcc35a.js”
}

Таким образом, вы можете использовать его позже в методе/модуле замены строки по вашему выбору.

Дополнительную информацию о grunt-filerev можно найти здесь.

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

person muecas    schedule 09.05.2018
comment
Что ж, кажется логичным, но я новичок в проекте, и люди, которые занимаются разработкой, больше не могут спросить. Я не нашел ничего о filerev, grunt-hash или grunt-file-hash во всем коде проекта. Где я могу найти файл grunt.filerev.summary, если он существует? - person Marcos Pérez Gude; 09.05.2018
comment
Предполагая, что хэшированное имя файла может быть получено таким образом, обновление комментария к блоку grunt-usemin (т.е. <!-- build:css static/assets/css/combined.css -->) на комментарий, отражающий новое хэшированное имя файла, остается проблемой. Для этого вы можете использовать регулярное выражение (например, это) с grunt-text-replace и настройте from и to в задаче следующим образом: replacements: [{ from: /(<!-- build:css static\/assets\/css\/)(.*?) -->/g, to: '$1' + hashedFileName + ' -->' }]- где hashedFileName – это полученная ссылка. . - person RobC; 09.05.2018
comment
Это не сам файл. Когда вы запускаете задачу grunt, данные временно сохраняются в самой задаче grunt. Поэтому вам следует использовать другую задачу, чтобы заменить хешированную версию имени вашего файла в каком-либо другом файле, который вы можете использовать. Где ссылка на предзагруженный css написана? - person muecas; 09.05.2018
comment
Мне нужно <link rel="preload"> в index.html, первом загруженном файле (для предварительной загрузки шрифтов, css и js). Есть включение angular, включение css и минимизация комментариев, которые я объяснил в основном посте. Я думаю, что результат в сводке задачи ворчания полезен, если я могу получить к нему доступ из html, но я думаю, что это будет невозможно/трудно достичь. - person Marcos Pérez Gude; 09.05.2018
comment
Вы можете использовать технику, подобную той, которую объяснил @RobC; позвольте мне привести вам рабочий пример того, как этого добиться. - person muecas; 09.05.2018
comment
@RobC звучит очень хорошо. Если я не запутался, мне нужно установить этот пакет npm, а затем заменить комментарий на ключ replacements. Но как я могу получить в файле HTML результат предложения to? - person Marcos Pérez Gude; 09.05.2018
comment
@muecas хорошо, большое спасибо. Я проголосовал за этот ответ, потому что вы правы насчет usemin и filerev - person Marcos Pérez Gude; 09.05.2018
comment
Маркос, акцент на предполагая был преднамеренным в моем предыдущем комментарии, насколько я понимаю, его нельзя получить (предостережение: я не использовал grunt-usemin и filerev). Совет: создавайте случайные хеши самостоятельно в своей сборке, выполнив что-то вроде мой ответ здесь". После того, как у вас есть ссылки на созданные хеши, вы получите больший контроль над другими частями сборки. Если вы добавите соответствующие части вашего Gruntfile.js в свой OP, я посмотрю, смогу ли я получить доступ к ссылкам на хеш. - person RobC; 09.05.2018