js文件的版本控制
使用grunt完成requirejs的合并压缩和js文件的版本控制
最近有一个项目使用了 requirejs
来解决前端的模块化,但是随着页面和模块的越来越多,我发现我快要hold不住这些可爱的js文件了,具体表现在每个页面都要设置一堆 requirejs
的配置( baseUrl
, paths
之类的)。
不知谁说过,一些事重复做了三次,就该考虑一下自动化了,于是我小心翼翼的掏出了我的 grunt
。
我们得使用 grunt-contrib-requirejs
这个插件来实现如上所说的自动化功能,这个就是根据 r.js
封装的 grunt
插件。
安装 grunt-contrib-requirejs
npm i --save-dev grunt-contrib-requirejs
配置 Grantfile
首先我们来看下项目目录
src
是每个页面的依赖文件
modules
和 lib
是一些模块和库
dist
是合并压缩后的文件
在 Gruntfile
中首先得到需要处理的文件列表,并创建一个空对象,用来装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'
}
};
}
接着初始化 grunt
配置并加载并注册任务
grunt.initConfig({
requirejs: requireOptions
})
grunt.loadNpmTasks('grunt-contrib-requirejs');
grunt.registerTask('require', ['requirejs']);
到这里 requirejs
的配置部分就结束了,在命令行输入 grunt require
就会看到 static/js/dist
目录下面有东西蹦出来了,而且全部都是合并后并压缩好的。
在html页面中只需要:
<script src="static/js/require.js"></script>
<script src="static/js/dist/index.js"></script>
就能成功加载了。
增加js文件的版本号
浏览器有时会对加载过的js或css进行缓存,如果你的某些js依赖发生改变,那么就可能发生错误,解决办法是在文件后面增加查询字符串,例如 a.js?v=dsd712sd
那么如何控制版本,首先我们肯定想到用 new Date()
,但是如果每次发布都让浏览器重新加载(尽管有些文件根本就没有改变),难免会造成浪费。正确的方案是根据文件内容生成MD5值来作为版本号,这样当文件没有改变时,hash就不会变。
那么如何自动解决版本号的问题,我们可以用到 asset-cache-control
这个grunt插件
首先安装:
npm i --save-dev asset-cache-control
asset-cache-control
的用法个很简单,只要设置一个源文件,再设置html文件的路径就可以了
grunt.initConfig({
cache: {
demo: {
assetUrl: 'js/demo.js',
tmp: ['demo.html']
}
}
})
注意的是:html文件中需要引入 js/demo.js
<script src='js/demo.js'></script>
然后加载和注册 asset-cache-control
插件
grunt.loadNpmTasks('asset-cache-control');
grunt.registerTask('cache', ['cache']);
接着在命令行敲 grunt cache
就会发现 index.html
中的 script
标签加上了查询字符串。
<script src='js/demo.js?t=92e26c5d'></script>
对每个js文件配置 cache
的任务:
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']
}
}
});
检测每个文件的变化,自动执行任务
用到 grunt-contrib-watch
这个官方组件
在 grunt.initConfig
中配置:
watch: {
files: ['static/js/src/*.js','static/js/modules/*.js'],
tasks: ['requirejs', 'cache'],
options: {
spawn: false
}
}
这样,当你修改 static/js/src/
和 static/js/modules/
下的所有js文件时,就会执行 requirejs
和 cache
任务。
完整配置清单
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个小文件的效率要高很多,所以模块的合并对性能也有很大的提高。
js文件的版本控制的更多相关文章
- 使用grunt完成requirejs的合并压缩和js文件的版本控制
最近有一个项目使用了 requirejs 来解决前端的模块化,但是随着页面和模块的越来越多,我发现我快要hold不住这些可爱的js文件了,具体表现在每个页面都要设置一堆 requirejs 的配置( ...
- [工具配置]requirejs 多页面,多入口js文件打包总结
需要明确以下几点: 1.本地前端调试代码肯定是调用原始的路径以及代码,但是线上运行的肯定是通过打包后的另一个路径,这儿就是生成的dist文件夹了. 2.requirejs的引入,线上跟线下的路径怎么控 ...
- 前端开发环境之GRUNT自动WATCH压缩JS文件与编译SASS文件环境下Ruby安装sass常见错误分析
前言: 1.sass编译为css文件,早先时刻写css,后来看了sass挺不错的,于是在新的项目中开始使用上了sass.(grunt需要ruby环境,所以需要先安装ruby,sass环境) ①安装ru ...
- 小小改动帮你减少bundle.js文件体积(翻译)
我已经从事过好多年的SPA开发工作,我发现很多的程序猿都从来不往 bundle.js 文件的体积上动脑筋,这让我有点懵逼. “安心洗路,等俺把代码混淆压缩后就一切666了”,若是有人这么说,我会翻白眼 ...
- JQuery 加载 CSS、JS 文件
JS 方式加载 CSS.JS 文件: //加载 css 文件 function includeCss(filename) { var head = document.getElementsByTagN ...
- 两个js文件之间函数互调问题
按照常理来说,在<body>标签结束之前以下面的方式引入两个js文件 <script src="a.js"></script> <scri ...
- 延迟加载外部js文件,延迟加载图片(jquery.lazyload.js和echo,js)
js里一说到延迟加载,大都离不开两种情形,即外部Js文件的延迟加载,以及网页图片的延迟加载: 1.首先简单说一下js文件的3种延迟加载方式: (1)<script type="text ...
- js文件中函数前加分号和感叹号是什么意思?
本文转自:http://blog.csdn.net/h_o_w_e/article/details/51388500 !function(){}(); !有什么用? 从语法上来开,JavaScri ...
- 在thinkphp中js文件添加路径
JS文件不认识__URL__这些tp独特的链接,所以要自己重新定义url,才能使用这些路径. 在js对于的模板上定义url 然后在js文件中引用
随机推荐
- NOI备战总结ing……
持续做题ing…… 已完成: 树套树 点分治 博弈论 凸包 杜教筛 反演 FFT 数位DP DP专栏 网络流 数学专栏 正在进行中: waiting: SAM Kd-tree 矩阵树 分治 FWT B ...
- java基础知识疑难点
1.“static”关键字是什么意思?Java中是否可以覆盖(override)一个private或者是static的方法? “static”关键字表明一个成员变量或者是成员方法可以在没有所属的类的实 ...
- CODE FESTIVAL 2017 qual A 题解
补一发A的题解. A - Snuke's favorite YAKINIKU 题意: 输入字符串S,如果以YAKI开头输出Yes,否则输出No. #include<bits/stdc++.h&g ...
- 特别翔实的adaboost分类算法讲解 转的
转https://www.cnblogs.com/litthorse/p/9332370.html 作为(曾)被认为两大最好的监督分类算法之一的adaboost元算法(另一个为前几节介绍过的SVM算法 ...
- php错误日志
php错误日志 /usr/local/php/var/log/php-fpm.log」—————————
- centos7+mysql5.7.11实现主从复制
1 首先检测当前的系统是否已经安装了MySQL yum list installed | grep mysql 如果有的话,删除 2 下载rpm库资源,在网页 https://dev.mysql. ...
- 人生效率手册:如何卓有成效地过好每一天--By张萌姐姐--读书笔记
读书笔记:<人生效率手册>:如何卓有成效地过好每一天--By张萌姐姐... 整本书看完的感受: 这本书主要讲的是生活中我们需要给自己一个目标,然后通过自己的努力去实现这个目标,书中说的很多 ...
- Flink入门训练--以New York City Taxi为例
最近在学Flink,准备用Flink搭建一个实时的推荐系统.找到一个好的网站(也算作是flink创始者的官方网站),上面有关于Flink的上手教程,用来练练手,熟悉熟悉,下文仅仅是我的笔记. 1. 数 ...
- 了解Linux操作系统的引导过程
原文地址:http://os.51cto.com/art/200706/49690.htm 1.简介 Linux启动过程指的是从加电到看到shell提示的这一段时间. Linux启动的过程可以大概分为 ...
- 转:我是否该放弃VB.Net?
我是否该放弃VB.Net呢?这个问题一次次的出现在我的脑海里,而且这种想法越来越强烈.放弃VB.Net至少能让我的生活变得轻松些.如果你是个C#程序员,那拷贝粘贴代码会很容易,因为可以找到的例子代码如 ...