Плагин Grunt для управления версиями активов

Я ищу плагин grunt, который автоматически изменит ссылки на статические ресурсы (js/css) внутри html файла следующим образом:

<link rel="stylesheet" type="text/css" href="style.css?v=12345678" />
<script src="script.js?v=12345678"></script>

Я искал на странице gruntjs.com/plugins → "version", но кажется, что все они меняют фактическую версию файлов вместо ссылок на них.

Мне это не хватает? Есть ли плагин, который может выполнить эту задачу?

Ответы

Ответ 1

Для этого я использую grunt-filerev для версий и grunt-usemin для автоматического обновления ссылок в исходных файлах.

Эти два модуля хорошо работают (usemin заменяет ссылки на отображение, предоставленное filerev)

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

изменить: несколько примеров кода (только показывая вам, что интересно в вашем случае):

Я использую usemin и filerev только при упаковке моего приложения (для развертывания):

В заголовке моего index.html следующий код сообщает usemin, чтобы взять все файлы между тегом build и агрегировать его в один из названных ie-shims.js

[...]
<!-- build:js /js/ie-shims.js -->
    <script src="/vendor/html5shiv/dist/html5shiv.js"></script>
    <script src="/vendor/respond/dest/respond.src.js"></script>
<!-- endbuild -->
[...]

Далее, в моем файле gruntfile.js у меня есть два node:

[...]
filerev: {
    options: {
        encoding: 'utf8',
        algorithm: 'md5',
        length: 8
    },
    source: {
        files: [{
            src: [
                'www/js/**/*.js',
                'www/assets/**/*.{jpg,jpeg,gif,png,ico}'
            ]
        }]
    }
},
useminPrepare: {
    html: 'src/index.html',
    options: {
        dest: 'www'
    }
},

// usemin has access to the revved files mapping through grunt.filerev.summary
usemin: {
    html: ['www/*.html'],
    css: ['www/css/**/*.css'],
    js: ['www/js/**/*.js'],
    options: {
        dirs: ['www'],
        assetsDirs: ['www'],
        patterns: {
            js: [
                [/["']([^:"']+\.(?:png|gif|jpe?g))["']/img, 'Image replacement in js files']
            ]
        }
    }
} [...]

Наконец, у меня есть задача, которая объединяет все это:

grunt.registerTask('build', 'Build task, does everything', ['useminPrepare', 'filerev', 'usemin']);

Затем сгенерированный HTML выглядит так:

[...]
<script src="/js/ie-shims.9f790592.js"></script>
[...]

Ответ 2

Я нашел аккуратную запись о том, как сохранить Grunt в чистоте, которая просматривает всю структуру папок, конфигурацию и задачу Gruntfile.js, выполняемую в http://www.jayway.com/2014/01/20/clean-grunt/. Ваш комментарий к более раннему ответу касается структуры папок, поэтому он также должен помочь в этом, так как структура там также не имеет файла index.html в корне.

  • Подготовьте свой html файл в соответствии с документами grunt-usemin (и/или сообщением, которое я связал)
  • Вам нужно добавить grunt-contrib-copy, чтобы вы могли скопировать index_src.html и переименовать его в index.html(использовали это для вдохновения), и приступить к этой задаче "usemin".
  • Измените ссылки на свои активы на относительные пути (например, ../js/controller.js)
  • Затем настройте свой Gruntfile.js следующим образом:

    [...]
    useminPrepare: {
        html: 'templates/index.html',
        options: {
            dest: 'js'
        }
    },
    
    // Concat - best to implement it this way for useminPrepare to inject the config
    concat: {
        options: {
            separator: ';'
        },
        // dist configuration is provided by useminPrepare
        dist: {}
    },
    
    // Uglify - best to implement it this way for useminPrepare to inject the config
    uglify: {
        // dist configuration is provided by useminPrepare
        dist: {}
    },
    
    filerev: {
        options: {
            encoding: 'utf8',
            algorithm: 'md5',
            length: 20
        },
        source: {
            files: [{
                src: [
                    'js/**/*.js'
                ]
            }]
        }
    },
    
    copy: {
      rename: {
        files: [
          {
            cwd: 'templates',
            src: ['**/index_src.html'],
            dest: 'templates',
            rename: function(dest, src) {
              return dest + src.replace(/_src\.html$/i, '.html');
            }
          }
        ]
      }
    },
    
    // usemin has access to the revved files mapping through grunt.filerev.summary
    usemin: {
        html: ['templates/index.html'],
        options: {
            assetsDirs: ['js']
        }
    } [...]
    

    Я не уверен 100% о регулярном выражении, чтобы переименовать файл, но сделайте резервную копию папки и попробуйте. Кроме того, я отвечаю по ссылке pastebin, которую вы указали, которая не содержит никаких файлов css. Если они есть, все становится немного сложнее, поэтому дайте мне знать.

  • Затем вы можете использовать задание, которое предлагает Bixi, но включают ваш шаг копирования (и concat и uglify)

    grunt.registerTask('build', 'Build task, does everything', [
    'useminPrepare',
    'concat',
    'uglify',
    'copy:rename',
    'filerev',
    'usemin'
    ]);