usemin revved filenames and requirejs dependencies

喜欢而已 提交于 2019-12-03 14:36:31

It's a tricky problem and I'm sure somebody else fixed in in a more elegant way, but the following works for me.

I might publish this as a grunt plugin once it's a little more robust.

Taken from my Gruntfile:

"regex-replace": {
  rjsmodules: { // we'll build on this configuration later, inside the 'userevd-rjsmodules' task
    src: ['build/**/*.js'],
    actions: []
  }
},


grunt.registerTask('userevd-rjsmodules', 'Make sure RequireJS modules are loaded by their revved module name', function() {
// scheduled search n replace actions
var actions = grunt.config("regex-replace").rjsmodules.actions;

// action object
var o = {
  search: '',
  replace: '', //<%= grunt.filerev.summary["build/js/app/detailsController.js"] %>
  flags: 'g'
};

// read the requirejs config and look for optimized modules
var modules = grunt.config("requirejs.compile.options.modules");
var baseDir = grunt.config("requirejs.compile.options.dir");

var i, mod;
for (i in modules) {
  mod = modules[i].name;
  revvedMod = grunt.filerev.summary[baseDir + "/" + mod + ".js"];
  revvedMod = revvedMod.replace('.js', '').replace(baseDir+'/','');

  o.name = mod;
  o.search = "'"+mod+"'";
  // use the moduleid, and the grunt.filerev.summary object to find the revved file on disk
  o.replace = "'"+revvedMod+"'";
  // update the require(["xxx/yyy"]) declarations by scheduling a search/replace action
  actions.push(o);
}

grunt.config.set('regex-replace.rjsmodules.actions', actions);
grunt.log.writeln('%j', grunt.config("regex-replace.rjsmodules"));

grunt.task.run("regex-replace:rjsmodules");
}),

You can also use requirejs' map config to specify a mapping between your original module and your revved one. Filerev outputs a summary object containing a mapping of all the modules that were versioned and their original names. Use grunt file write feature to write a file in AMD way with the contents being the summary object:

// Default task(s).
grunt.registerTask('default', ['uglify', 'filerev', 'writeSummary']);

grunt.registerTask('writeSummary', 'Writes the summary output of filerev task to a file', function() {
    grunt.file.write('filerevSummary.js', 'define([], function(){ return ' + JSON.stringify(grunt.filerev.summary) + '; })');
})

and use this file in your require config so that the new revved modules are used instead of old ones:

require(['../filerevSummary'], function(fileRev) {

var filerevMap = {};
for (var key in fileRev) {
    var moduleID = key.split('/').pop().replace('.js', '');
    var revvedModule = '../' + fileRev[key].replace('.js', '');

    filerevMap[moduleID] = revvedModule;
}

require.config({
    map: {
        '*': filerevMap
    }
});

The filerevMap object that I created above is specific to my folder structure. You can tweak it as per yours. It just loops through the filerev summary and makes sure the keys are modified as per your module names and values as per your folder structure.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!