javascript 用于资产版本控制的 Grunt 插件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21969422/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 22:06:53  来源:igfitidea点击:

Grunt plugin for assets versioning

javascriptcssversiongruntjs

提问by Andreas

I'm looking for a grunt plugin that will automatically change the references to static assets (js/css) inside an html file like this:

我正在寻找一个 grunt 插件,它会自动更改对 html 文件中的静态资产(js/css)的引用,如下所示:

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

I searched at the gruntjs.com/plugins -> "version", but it seems that all of them change the actual version of the files instead of references to them.

我在 gruntjs.com/plugins -> "version" 上搜索,但似乎所有这些都更改了文件的实际版本,而不是对它们的引用。

Am I missing it? Is there a plugin that can perform this task?

我错过了吗?是否有可以执行此任务的插件?

回答by Cétia

For this I use grunt-filerevfor the versionning and grunt-useminfor the automatic update of the references in source files.

为此,我使用grunt-filerev进行版本控制,使用grunt-usemin自动更新源文件中的引用。

These two modules works well together (usemin replacing references with a mapping provided by filerev)

这两个模块可以很好地协同工作(usemin 用 filerev 提供的映射替换引用)

Hope this helps

希望这可以帮助

edit:a few code examples (only showing you what's interesting in your case):

编辑:一些代码示例(仅向您展示您的案例中有趣的内容):

I use usemin & filerev only when packaging my app (for deployment) :

我只在打包我的应用程序时使用 usemin 和 filerev(用于部署):

In the head of my index.html, the following code tell usemin to take all the files between the buildtag and agregate it into one named ie-shims.js

在我的 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 -->
[...]

Next, in my gruntfile.js, i have two node :

接下来,在我的 gruntfile.js 中,我有两个节点:

[...]
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']
            ]
        }
    }
} [...]

Finally, I have a grunt task that put all that together :

最后,我有一个繁重的任务,将所有这些放在一起:

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

Then, the generated HTML is like that :

然后,生成的 HTML 是这样的:

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

回答by Wraithers

I found a neat post about keeping Grunt clean, that walks through an entire folder structure, Gruntfile.js config and task running, over at http://www.jayway.com/2014/01/20/clean-grunt/. Your comment on the earlier answer is about folder structure, so it should also help with that, since the structure there doesn't have index.html file in the root either.

我在http://www.jayway.com/2014/01/20/clean-grunt/ 上找到了一篇关于保持 Grunt 干净整洁的帖子,介绍了整个文件夹结构、Gruntfile.js 配置和任务运行。您对先前答案的评论是关于文件夹结构的,因此它也应该对此有所帮助,因为根目录中也没有 index.html 文件。

  1. Prep your html file as per the docs of grunt-usemin(and/or the post I linked)
  2. You need to add grunt-contrib-copy, so you can copy index_src.html and rename it to index.html (used this for inspiration), and proceed with the 'usemin' task on that.
  3. Change references to your assets to relative paths (ex. ../js/controller.js)
  4. Then configure your Gruntfile.jslike this:

    [...]
    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']
        }
    } [...]
    

    I'm not a 100% sure about the regex to rename the file, but make a backup of the folder and give it a try. Also, I'm answering as per the pastebin link you gave, which did not include any css files. If there are any, things get a bit complicated, so let me know.

  5. You could then use the grunt task Bixi suggested, but include your copy step (and concat & uglify)

    grunt.registerTask('build', 'Build task, does everything', [
    'useminPrepare',
    'concat',
    'uglify',
    'copy:rename',
    'filerev',
    'usemin'
    ]);
    
  1. 根据grunt-usemin(和/或我链接的帖子)的文档准备您的 html 文件
  2. 您需要添加grunt-contrib-copy,以便您可以复制 index_src.html 并将其重命名为 index.html(用于灵感),然后继续执行“usemin”任务。
  3. 将您的资产的引用更改为相对路径(例如../js/controller.js
  4. 然后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 文件。如果有的话,事情会变得有点复杂,所以让我知道。

  5. 然后您可以使用 Bixi 建议的 grunt 任务,但包括您的复制步骤(以及 concat & uglify)

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