源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

详解使用grunt完成requirejs的合并压缩和js文件的版本控制

  • 时间:2021-01-25 20:30 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:详解使用grunt完成requirejs的合并压缩和js文件的版本控制
最近有一个项目使用了[code] requirejs [/code]来解决前端的模块化,但是随着页面和模块的越来越多,我发现我快要hold不住这些可爱的js文件了,具体表现在每个页面都要设置一堆[code] requirejs [/code]的配置( [code]baseUrl [/code],[code] paths [/code]之类的)。 不知谁说过,一些事重复做了三次,就该考虑一下自动化了,于是我小心翼翼的掏出了我的[code] grunt [/code]。 我们得使用[code] grunt-contrib-requirejs [/code]这个插件来实现如上所说的自动化功能,这个就是根据 [code]r.js[/code] 封装的[code] grunt [/code]插件。 安装[code] grunt-contrib-requirejs[/code]
npm i --save-dev grunt-contrib-requirejs
配置[code] Grantfile[/code] 首先我们来看下项目目录 [img]http://files.jb51.net/file_images/article/201703/2017030209555511.png?20172295734[/img] [code]src [/code]是每个页面的依赖文件 [code]modules[/code] 和 [code]lib[/code] 是一些模块和库 [code]dist [/code]是合并压缩后的文件 在[code] Gruntfile [/code]中首先得到需要处理的文件列表,并创建一个空对象,用来装requirejs的配置
var files = grunt.file.expand('static/js/src/*.js');
var requireOptions = {};
然后遍历这个文件列表数组,得到js文件的名称:
files.forEach(function (file) {
  var filenamelist = file.split('/');
  var num = filenamelist.length;
  var filename = filenamelist[num - 1].replace(/\.js$/,'');
}
接下来为每个js文件配置一个任务,任务名称就是js的文件名称:
files.forEach(function (file) {
  requireOptions[filename] = {
    options: {
      baseUrl: 'static/js',
      paths: {
        jquery: 'lib/jquery.min',
        lrz: 'lib/lrz.all.bundle',
        zepto: 'lib/zepto.min',
        ajax: 'modules/ajax',
        validators: 'modules/validators',
        page: 'modules/mixins/to_page',
        dialog: 'modules/mixins/toggle_login_dialog',
      },
      optimizeAllPluginResources: true,
      name: 'src/' + filename,
      out: 'static/js/dist/' + filename + '.js'
    }
  };
}
接着初始化[code] grunt [/code]配置并加载并注册任务
grunt.initConfig({
  requirejs: requireOptions
})

grunt.loadNpmTasks('grunt-contrib-requirejs');
grunt.registerTask('require', ['requirejs']);
到这里[code] requirejs [/code]的配置部分就结束了,在命令行输入[code] grunt require [/code]就会看到 [code]static/js/dist[/code] 目录下面有东西蹦出来了,而且全部都是合并后并压缩好的。 在html页面中只需要:
<script src="static/js/require.js"></script>
<script src="static/js/dist/index.js"></script>
就能成功加载了。 [b]增加js文件的版本号[/b] 浏览器有时会对加载过的js或css进行缓存,如果你的某些js依赖发生改变,那么就可能发生错误,解决办法是在文件后面增加查询字符串,例如[code] a.js?v=dsd712sd[/code] 那么如何控制版本,首先我们肯定想到用[code] new Date() [/code],但是如果每次发布都让浏览器重新加载(尽管有些文件根本就没有改变),难免会造成浪费。正确的方案是根据文件内容生成MD5值来作为版本号,这样当文件没有改变时,hash就不会变。 那么如何自动解决版本号的问题,我们可以用到[code] asset-cache-control [/code]这个grunt插件 首先安装:
npm i --save-dev asset-cache-control
[code]asset-cache-control [/code]的用法个很简单,只要设置一个源文件,再设置html文件的路径就可以了
grunt.initConfig({
  cache: {
    demo: {
      assetUrl: 'js/demo.js',
      tmp: ['demo.html']
    }
  }
})
注意的是:html文件中需要引入[code] js/demo.js[/code]
<script src='js/demo.js'></script>
然后加载和注册[code] asset-cache-control [/code]插件
grunt.loadNpmTasks('asset-cache-control');
grunt.registerTask('cache', ['cache']);
接着在命令行敲[code] grunt cache[/code] 就会发现[code] index.html[/code] 中的[code] script [/code]标签加上了查询字符串。
<script src='js/demo.js?t=92e26c5d'></script>
对每个js文件配置[code] cache [/code]的任务:
var files = grunt.file.expand('static/js/src/*.js');
var cacheOptions ={};
files.forEach(function (file) {
  var filenamelist = file.split('/');
  var num = filenamelist.length;
  var filename = filenamelist[num - 1].replace(/\.js$/,'');
  cacheOptions[filename] = {
    assetUrl: 'static/js/dist/' + filename +'.js',
    files: {
      'tmp': [filename+'.php']
    }
  }
});

[b]检测每个文件的变化,自动执行任务[/b] 用到[code] grunt-contrib-watch [/code]这个官方组件 在[code] grunt.initConfig [/code]中配置:
watch: {
  files: ['static/js/src/*.js','static/js/modules/*.js'],
  tasks: ['requirejs', 'cache'],
  options: {
    spawn: false
  }
}
这样,当你修改[code] static/js/src/ [/code]和[code] static/js/modules/ [/code]下的所有js文件时,就会执行[code] requirejs [/code]和[code] cache [/code]任务。 [b]完整配置清单[/b]
module.exports = function (grunt) {
  var files = grunt.file.expand('static/js/src/*.js');
  var requireOptions = {};
  var cacheOptions ={};
  files.forEach(function (file) {
    var filenamelist = file.split('/');
    var num = filenamelist.length;
    var filename = filenamelist[num - 1].replace(/\.js$/,'');
    requireOptions[filename] = {
      options: {
        baseUrl: 'static/js',
        paths: {
          jquery: 'lib/jquery.min',
          lrz: 'lib/lrz.all.bundle',
          zepto: 'lib/zepto.min',
          ajax: 'modules/ajax',
          validators: 'modules/validators',
          page: 'modules/mixins/to_page',
          dialog: 'modules/mixins/toggle_login_dialog',
        },
        optimizeAllPluginResources: true,
        name: 'src/' + filename,
        out: 'static/js/dist/' + filename + '.js'
      }
    };
    cacheOptions[filename] = {
      assetUrl: 'static/js/dist/' + filename +'.js',
      files: {
        'tmp': [filename+'.php']
      }
    }
  });

  grunt.initConfig({
    requirejs: requireOptions,
    cache: cacheOptions,
    watch: {
      files: ['static/js/src/*.js','static/js/modules/*.js'],
      tasks: ['requirejs', 'cache'],
      options: {
        spawn: false
      }
    }
  });

  grunt.loadNpmTasks('asset-cache-control'); 
  grunt.loadNpmTasks('grunt-contrib-requirejs');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.registerTask('require', ['requirejs','cache'])
};

另外,浏览器加载一个大文件比加载n个小文件的效率要高很多,所以模块的合并对性能也有很大的提高。 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程素材网。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部