使用usemin重命名文件和requirejs依赖项

6
我在使用requirejs和usemin时遇到了以下问题:
我想设置一个多页面应用程序,在其中动态加载仅包含特定页面功能的模块(例如about -> about.js,home -> home.js)。我可以继续打包所有内容到单个文件中,但这只会导致文件大小变大,并且会增加不必要的功能开销! (例如,为什么我需要在没有旋转木马的页面上加载旋转木马插件!)
我查看了示例https://github.com/requirejs/example-multipage-shim 这实际上是一种很好的处理方法,直到我将usemin引入游戏。在更改文件名后,每个脚本标记的src路径都会更新,但依赖关系呢?
<script src="scripts/vendor/1cdhj2.require.js"></script>
<script type="text/javascript">
   require(['scripts/common'], function (common) {
      require(['app'], function(App) {
          App.initialize();
      });
   });
</script>

在这种情况下,require.js被版本化文件1cdhj2.require.js替换了。太好了!

但是所需的模块"common"和"app"不再起作用,因为common变成了4jsh3b.common.js,而app变成了23jda3.app.js!

我该怎么办?谢谢你的帮助!(顺便说一句,我也在使用Yeoman)


r.js 会为你压缩依赖关系,那你为什么还需要使用 usemin 呢? - ddotsenko
2个回答

4

这是一个棘手的问题,我相信其他人可能会用更优雅的方法来解决它,但以下方法对我有效。

一旦变得更加健壮,我可能会将其发布为grunt插件。

取自我的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");
}),

1
您还可以使用requirejs的map配置来指定原始模块和版本化模块之间的映射关系。 Filerev输出一个概述对象,其中包含所有已版本化模块及其原始名称的映射。使用grunt文件写入功能以AMD方式编写文件,并将内容设置为概述对象。
// 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) + '; })');
})

将此文件用于您的require配置中,以便使用新版本的模块而不是旧版本:

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

我上面创建的filerevMap对象是特定于我的文件夹结构的。您可以根据自己的需要进行调整。它只是循环遍历filerev摘要,并确保键根据您的模块名称进行修改,值根据您的文件夹结构进行修改。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接