gulp实现前端非覆盖式发布
近期参与了公司的重构项目,交付给测试同事做测试时,发现修改了bug测试还是报出来。 然后清理了缓存或者过一段时间就好了。幸好是用于测试,如果在发布版本的过程中,由于浏览器缓存问题导致用户访问页面时访问了原来的旧资源就比较麻烦了。
之后就搜索了各种资料,看了下大公司的各种方案,看完发现太复杂。对于公司这种不算大的项目,采用gulp就可以解决了。
在写如下非覆盖式静态资源发布,首先需要了解一下什么是覆盖式静态资源发布。
覆盖式静态资源发布:
从下面页面看到,页面引用了一个base.css的文件,里面引用了一张图片。正常情况下,浏览器使用缓存来防止用户每次访问页面都需要加载大量的静态资源。 这个过程是,浏览器使用协商缓存,在加载同一个资源时,会问服务器有没有更新过这个资源,没有的话就返回一个304状态,然后读取本地静态资源。
然后,这也造成了另外一个问题,在每次发布新的版本时,已经修改了另外一张图片,但由于缓存用户并没有感知到图片更新。如果避免这种情况发生,我们有一种办法,就是在每次发布版本时,在静态资源的名称上打一个版本号,类似下面这样:
<link rel="stylesheet" type="text/css" href="base.css?v=1.0.1"/>
<link rel="stylesheet" type="text/css" href="a.css?v=1.0.1"/>
棒棒哒,这样就解决了上面头疼的问题。但真的这么快就解决了么,可没有那么容易呀。这样又出现了一个问题,项目比较大的话,那么那么多的资源文件,全部都要更新一遍,就要重新下载一次,这就麻烦了。 如果某个版本的修改内容只有一个文件,那就只更新这个文件好了。那文件后缀要怎么办呢?查找了一下方案,给后面的文件后缀打个戳就好,生成MD5码就OK了。简而言之,就是可以根据不同文件内容生成不同hash。
非覆盖式静态资源发布:
然后文件命名就开心的被改成下面的样子啦。
<link rel="stylesheet" type="text/css" href="base.css?v=j9sofj"/>
<link rel="stylesheet" type="text/css" href="a.css?v=d98jfk"/>
到这里还是没有大功告成,因为有一个问题,如果html页面和静态资源不是同一打包发布的话,又来了一个问题。 先发布页面还是静态资源呢?先发布页面,静态资源还没有更新,那用户就找不到新的资源,要报错啦^^^先发布静态资源,再发布页面,原来的文件被新的覆盖掉了,又混乱了。然后程序猿和程序媛们又要愉快的在夜深人静的时候上新的版本啦。
不过,还好我们没有大公司那么健全,每次发版全部打包丢上去。直接一起改掉就好了,然而,我是个追求完美的人嘿嘿。继续看资料,那就不要把后缀加上戳了,直接在文件名上修改吧。然后就变成了下图最后的样子。
这样每次修改了文件,不会覆盖掉原来的,两个都保留了。 而且还有一个好处,跟据内容生产的MD5戳,加上一段内容,新的文件是这样子的:base-3fead09019.css, 恢复到原来,变成了这样子:base-5jdkg08679.css。 重新加上刚刚的内容,变成这样子:base-3fead09019.css,删掉内容,又变回这样子:base-5jdkg08679.css。 非常好,跟据内容生成的戳,相同的文件不会产生命名的变化,就不会产生过多各种戳的文件了。看起来,现在比较完美的解决了用户浏览器缓存更新的问题。
gulp用到的插件:
最后整理了一下,gulp用到的插件,看看gulpfile.js: 晕乎乎,实在太多了,其实相关的就是 gulp-rev和gulp-rev-collector。
原本也尝试了很多其他的插件,就这俩最合适了。 正常gulp-rev就可以,但项目里有各种文件引用了其他的静态资源文件,手动改要累坏,所以每次有文件更新了名称之后,需要用到gulp-rev-collector把引用的路径直接替换掉。
这样整体上看,问题就解决了。