Gulp 定制专属提速“外挂”(下)

时间:2022-05-04
本文章向大家介绍Gulp 定制专属提速“外挂”(下),主要内容包括本文内容概要、静态资源缓存更新的问题、基于文件内容的hash版本控制、使用Gulp对静态资源的处理、package.json的作用、Gulp小结、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。

友情提示:推荐阅读时间10分钟 + 练习时间10分钟

上一期给大家分享了Gulp插件的安装与使用,只要掌握了Gulp插件安装的流程与配置,对于其他Gulp插件的使用基本上就没有太大的问题。毕竟Gulp的插件太丰富了,大家也没有太多的精力把所有的插件都去研究一遍。当一个网站进行改版升级的时候,会遇到静态资源版本更新的问题,那么对于前端开发工程师来说,该如何解决这个问题?所以今天要和大家一起探讨如何解决静态资源版本更新的问题和package.json的作用。

相关阅读:前端工程化 | 定制专属提速“外挂”(上)| 前端工程化 | 揭秘程序员的提速“外挂”

本文内容概要

  • Gulp解决静态资源版本更新的问题
  • package.json的作用
  • Gulp的小结

静态资源缓存更新的问题

为了让用户能够快速的访问网站,开发人员会对网站的静态资源做缓存处理,这样可以减少网站静态资源的加载。但是,又出现了一个新问题,当我们需要对网站做改版升级的时候,如何让缓存的静态资源失效。换句话说,只要把静态资源缓存下来,在缓存有效的时间内,用户访问网站时静态资源是从浏览器缓存里面加载而不是从服务器加载过来。如果想进一步了解“网站缓存”,可以发送关键字缓存到HTML5学堂公众号。如果网站的静态资源做了修改,如何保证用户访问的是最新的静态资源而不是缓存起来的静态资源?具体先来看看下面的几种解决方案。

为静态资源请求添加Query

这个理解起来比较简单,就是在静态资源请求后面添加参数,这个参数的值是时间戳和版本号的结合,当然也可以使用其它方式来计算该参数的值。

修改前

<!-- 代表结构 -->
<h2>梦幻雪冰</h2>


<!-- 代表静态资源 -->
<script type="text/javascript" src="index.js?v=201611131388" charset="utf-8"></script>
<script type="text/javascript" src="main.js?v=201611131388" charset="utf-8"></script>
<script type="text/javascript" src="list.js?v=201611131388" charset="utf-8"></script>

修改后

<!-- 代表结构 -->
<h2>HTML5学堂 - 码匠</h2>


<!-- 代表静态资源 -->
<script type="text/javascript" src="index.js?v=201611131389" charset="utf-8"></script>
<script type="text/javascript" src="main.js?v=201611131389" charset="utf-8"></script>
<script type="text/javascript" src="list.js?v=201611131389" charset="utf-8"></script>

这样看起来好像是可以解决掉静态资源缓存的问题,因为静态资源请求发生了变化。但是又出现了一个新问题,修改前后的静态资源文件名都是没有变化的,当开发人员把线下(本地)的文件覆盖掉线上(服务器)的文件,会出现一定的问题。因为在覆盖的过程中,静态资源和页面文件的部署有一定的时间间隔,对于一个大型网站来说即使时间间隔很小,都有可能出现新的用户访问。那在这个时间间隔内,用户访问网站会发生什么情况呢?

1、如果先覆盖index.html,后覆盖index.js,用户在这个时间间隔访问,会得到新的index.html引用旧的index.js的情况,从而出现错误的页面。

2、如果先覆盖index.js,后覆盖index.html,用户在这个时间间隔访问,会得到旧的index.html引用新的index.js的情况,从而也出现了错误的页面。

这也是一些互联网公司选择半夜这段时间等待访问低峰期再上线的原因之一。

基于文件内容的hash版本控制

对于静态资源缓存更新的问题,目前来说最优方案就是基于文件内容的hash版本控制了。

项目源代码

<!-- 代表结构 -->
<h2>梦幻雪冰</h2>


<!-- 代表静态资源 -->
<script type="text/javascript" src="index.js" charset="utf-8"></script>
<script type="text/javascript" src="main.js" charset="utf-8"></script>
<script type="text/javascript" src="list.js" charset="utf-8"></script>

发布的代码

<!-- 代表结构 -->
<h2>HTML5学堂 - 码匠</h2>


<!-- 代表静态资源 -->
<script type="text/javascript" src="index-46a6d95.js" charset="utf-8"></script>
<script type="text/javascript" src="main-367d728.js" charset="utf-8"></script>
<script type="text/javascript" src="list-e56e8e2.js" charset="utf-8"></script>

发布出来后JS被修改了文件名,产生了一个新文件,并不是覆盖已有的文件。其中“46a6d95”这串字符是根据js的文件内容进行hash计算出来的,只有文件内容发生变化了才会更改。由于这种不是采用同名文件覆盖,因此不存在上述说的那些问题。

因为它无法通过手工的形式来进行维护,所以需要借助工具来处理,在这边我们采用Gulp的插件来做处理。

使用Gulp对静态资源的处理

安装:gulp-asset-rev和gulp-rev插件

命令行:cnpm install gulp-asset-rev和cnpm install gulp-rev

提醒:gulp-asset-rev用于更改HTML文件引用静态资源的路径;gulp-rev用于修改静态资源的文件名。

在gulpfile.js中引入gulp-asset-rev和gulp-rev插件

  1. var assetRev = require('gulp-asset-rev');
  2. var rev = require('gulp-rev');

配置插件的功能

// 静态资源处理
gulp.task('revJS', function() {
    gulp.src('js/*.js') // 源文件下的所有js
    .pipe(rev()) // 修改静态资源的文件名
    .pipe(assetRev()) // 更改HTML文件引用静态资源的路径
    .pipe(gulp.dest('dist/js'));// 复制到目标文件路径
});


gulp.task('rev',['revJS'],function() {
    gulp.src("./**/*.html") // 源文件下的所有HTML
    .pipe(assetRev()) // 更改HTML文件引用静态资源的路径
    .pipe(gulp.dest('dist'));// 复制到目标文件路径
});

完整的配置代码

// 引入Gulp安装好的插件 require('模块名称')
var gulp = require('gulp');
var browserSync = require('browser-sync').create();
var reload = browserSync.reload;
var concat = require('gulp-concat');
var cleanCSS = require('gulp-clean-css');
var assetRev = require('gulp-asset-rev');
var rev = require('gulp-rev');


// 定义一个f5任务,名称自定义即可
// 浏览器自动刷新
gulp.task('f5', function(){
    browserSync.init({
        server:{
            baseDir:'./'
        }
    });


    gulp.watch(['./**/*.html']).on('change', reload);
});


// 文件合并
gulp.task('concatFile', function () {
    // 需要合并的文件
    gulp.src('css/*.css')
    //合并后的文件名
    .pipe(concat('common.css'))
    // 合并后的文件所在的文件夹
    .pipe(gulp.dest('dist/css'));
});


// CSS文件压缩
gulp.task('cssMin', function() {
    // 需要压缩的CSS文件
    gulp.src('css/*.css')
    // CSS文件压缩
    .pipe(cleanCSS())
    // 压缩后的C文件所在的文件夹
    .pipe(gulp.dest('dist/css'));
});


// 静态资源处理
gulp.task('revJS', function() {
    gulp.src('js/*.js') // 源文件下的所有js
    .pipe(rev()) // 修改静态资源的文件名
    .pipe(assetRev()) // 更改HTML文件引用静态资源的路径
    .pipe(gulp.dest('dist/js'));// 复制到目标文件路径
});


gulp.task('rev',['revJS'],function() {
    gulp.src("./**/*.html") // 源文件下的所有HTML
    .pipe(assetRev()) // 更改HTML文件引用静态资源的路径
    .pipe(gulp.dest('dist'));// 复制到目标文件路径
});

查看处理效果

package.json的作用

安装插件的时候为何要将配置信息保存至package.json(package.json是nodejs项目配置文件)。

因为node插件包相对来说比较庞大,所以不加入版本管理,将配置信息写入package.json来进行版本管理,团队合作的时候方便成员下载所需要的包。(使用命令行:npm install,将会根据package.json下载所有需要的包)。另外,在其他项目也要使用Gulp的时候只要把gulpfile.js和package.json拷贝过去,再初始化Gulp就行了,而不用命令行来安装Gulp插件。

Gulp小结

到这边为止,对Gulp的分享算是告一段落了。合理的使用工具能够帮助我们提高开发效率,而不是把时间花在重复操作上面。最后,简单回顾Gulp的使用流程。

  1. ——>安装NodeJS
  2. ——>全局安装Gulp
  3. ——>项目安装Gulp
  4. ——>插件安装
  5. ——>配置gulpfile.js文件
  6. ——>运行Gulp任务

参考资料:

  • https://www.npmjs.com/package;
  • https://www.zhihu.com/question/28072766/answer/40642578

本文系HTML5学堂独家内容,转载请在文章开头显眼处注明作者和出处“HTML5学堂(http://www.h5course.com/)”