我们常常需要在浏览器缓存一些稳定的资源,如第三方库等。要达到这个目标,只需要两步:

1、提取出“稳定的资源”;

2、提供稳定的文件hash 。

处理后的出的文件就像这样子: app.1w3ad4q4.js,然后,我们设置它的缓存规则为永不过期。这样,当文件没有改动时,浏览器将一直沿用第一次下载的缓存,不会浪费流量了。

详细说明:张云龙的知乎回答

webpack中提取公共模块一般使用 webpack 内置的  CommonsChunkPlugin 插件,他可以提取出 入口chunk中 的公共模块:

1、minChunks 参数 是指  至少有minChunks个入口引用的模块才会提取出来,“infinity“ 等价于入口数量,即所有入口都引用的模块才会提取出来;

上面的例子是一个SPA,入口是main.js。为了提取出第三方库,我们新增一个vendors入口中,并引入所有用到的第三方库,就像这样:

里面并没有业务代码,vendors文件只是为了引导CommonsChunkPlugin插件提取出 第三方库。

这样,我们就能将稳定的第三方库 与 不稳定的业务代码分开缓存了!~

另:看了vue-cli的源码后,发现她是这样做的:

entry: {
app: './src/main.js'
}
... new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks (module, count) { // 插件会遍历所有引入的模块,传入此函数的module参数,而count是当前module的引用次数
// any required modules inside node_modules are extracted to vendor
return ( // 返回true则打包进vendor,否则不打包
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0 // 从node_module引入的返回true
)
}
}),

还有这种操作!!

2、names 参数 传入数组的话(names: ['vendors', 'manifest']),等效于 :

 文档的描述是:" 一个字符串数组被传入,这相当于插件针对每个 chunk 名被多次调用"

其中,从vendors中提取manifest 的操作,我查看vue-cli的配置,里面的注释是这样的 :

“extract webpack runtime and module manifest to its own file in order to prevent vendor hash from being updated whenever app bundle is updated”,

文档解释:

但是,如果我们改变应用的代码并且再次运行 webpack,可以看到 vendor 文件的 hash 改变了。即使我们把 vendor 和 main 的 bundle 分开了,也会发现 vendor bundle 会随着应用代码改变。这意味着我们任然无法从浏览器缓存机制中受益,因为 vendor 的 hash 在每次构建中都会改变,浏览器也必须重新加载文件。 这里的问题在于,每次构建时,webpack 生成了一些 webpack runtime 代码,用来帮助 webpack 完成其工作。当只有一个 bundle 的时候,runtime 代码驻留在其中。但是当生成多个 bundle 的时候,运行时代码被提取到了公共模块中,在这里就是 vendor 文件。为了防止这种情况,我们需要将运行时代码提取到一个单独的 manifest 文件中。尽管我们又创建了另一个 bundle,其开销也被我们在 vendor 文件的长期缓存中获得的好处所抵消。"

,大意就是,如果不把manifest(运行时代码和模块清单)提取出来,只要业务代码有改动,vendors(存放提取出来的第三方库)文件的内容也会变化,也就是它的chunkhash也会改变,这不是我们想要的!

3、hash 与 chunkhash:

[ hash ]是webpack编译的hash值,每次编译都不一样;[ chunkhash ]则是根据文件内容计算所得的hash值,文件内容不变的话,这个值是固定的。用webpack构建时,默认是css  in  js的,即css包含在js内,webpack计算chunkhash时,整个chunk的内容会将css的内容也计算在内。所以,不论是修改了js代码还是css代码,整个chunk的内容都改变了,计算所得的chunkhash随之改变。但理想情况下是想css或js内容改变时仅影响自身文件的chunkhash,这样客户端只需更新css 或 js文件。

要解决此问题,首先要将css单独编译输出文件,并给他一个独立的extracttextplugin插件提供的 [ contenthash ] -- 根据文本内容生成的hash值

把css提取出来并加上hash后,就可以令css单独缓存了!

webpack 的第三方库分离并持久化缓存的更多相关文章

  1. 仿B站项目(4)webpack打包第三方库jQuery

    概述 在项目中不可避免的会用到jquery等第三方库,来看看有什么问题,怎么解决. 遇到的问题 一般情况下,直接require第三方库,比如jquery,然后webpack会自动把第三方库打包进bun ...

  2. vue-cli、webpack提取第三方库-----DllPlugin、DllReferencePlugin

    需要安装的插件有 extract-text-webpack-plugin assets-webpack-plugin clean-webpack-plugin npm install extract- ...

  3. webpack分离第三方库(CommonsChunkPlugin并不是分离第三方库的好办法DllPlugin科学利用浏览器缓存)

    webpack算是个磨人的小妖精了.之前一直站在glup阵营,使用browserify打包,发现webpack已经火到爆炸,深怕被社区遗落,赶紧拿起来把玩一下.本来只想玩一下的.尝试打包了以后,就想启 ...

  4. CommonsChunkPlugin并不是分离第三方库的好办法(DllPlugin科学利用浏览器缓存)

    webpack算是个磨人的小妖精了.之前一直站在glup阵营,使用browserify打包,发现webpack已经火到爆炸,深怕被社区遗落,赶紧拿起来把玩一下.本来只想玩一下的.尝试打包了以后,就想启 ...

  5. Android 使用Retrofit2.0+OkHttp3.0实现缓存处理+Cookie持久化第三方库

    1.Retrofit+OkHttp的缓存机制 1.1.第一点 在响应请求之后在 data/data/<包名>/cache 下建立一个response 文件夹,保存缓存数据. 1.2.第二点 ...

  6. 用 webpack 实现持久化缓存

    什么是持久化缓存? 原文链接https://sebastianblade.com/using-webpack-to-achieve-long-term-cache/ 缓存(cache)一直是前端性能优 ...

  7. 基于webpack实现多html页面开发框架七 引入第三方库如jquery

    一.解决什么问题 1.如何引入第三方库,如jquery等 二.引入jquery方法 1.下载jquery.min.js放到assets/lib下面 2.安装copy-webpack-plugin,将已 ...

  8. 运用NodeJs环境并依赖第三方库,框架等实现网站前后端分离报错问题及处理方法

    运用NodeJs环境并依赖第三方库,框架等实现网站前后端分离报错问题及处理方法 问题一: SyntaxError: missing ) after argument list in .....\vie ...

  9. IOS数据持久化存储之SQLite3第三方库FMDB的使用

    SQLite是一种小型的轻量级的关系型数据库,在移动设备上使用是非常好的选择,无论是Android还是IOS,都内置了SQLite数据库,现在的版本都是SQLite3.在IOS中使用SQLite如果使 ...

随机推荐

  1. 【Android开发】 HttpURLConnection.getOutputStream() IO异常

    HttpURLConnection.getOutputStream()  IO异常百度下,没找到想要的答案.网上的解决方案几乎都是从权限考虑的~最后找到个国外网站上找到答案~ http://stack ...

  2. shell重温---基础篇(参数传递&echo命令)

    经过前两天的学习,关于shell的基础算是知道的一般般啦,最起码不算是小白了(纯属意淫).今天就来点干货哈.   首先是运行shell脚本时的参数传递.脚本内获取参数的格式为$n.n代表了一个数字,例 ...

  3. 第5模块闯关Bootstrap

    “行(row)”必须包含在 .container (固定宽度)或 .container-fluid (100% 宽度)中,以便为其赋予合适的排列(aligment)和内补(padding). 通过“行 ...

  4. hadoop与mysql数据库的那点事

        转眼间已经接触了hadoop两周了,从之前的极力排斥到如今的有点喜欢,刚开始被搭建hadoop开发环境搞得几乎要放弃,如今学会了编写小程序,每天都在成长一点挺好的,好好努力,为自己的装备库再填 ...

  5. Android TextView 单行文本的坑

    这是android系统的一个bug,描述如下:https://code.google.com/p/android/issues/detail?id=33868 具体来说就是当一个TextView设置了 ...

  6. Zabbix_agentd 启动报错

    C:\zabbix>c:\Zabbix\zabbix_agentd.exe -i -c c:\Zabbix\zabbix_agentd.conf zabbix_agentd.exe [1144] ...

  7. linux常用命令补充详细

    1.ls命令 就是list的缩写,通过ls 命令不仅可以查看linux文件夹包含的文件,而且可以查看文件权限(包括目录.文件夹.文件权限)查看目录信息等等 常用参数搭配: ls -a 列出目录所有文 ...

  8. 配置SSH无密钥登陆(三)

    配置SSH无密钥登陆 (1).关闭防火墙 对每个虚拟机进行如下操作:   su    chkconfig  iptables  off 执行之后重启虚拟机:reboot (2).关闭之后,在maste ...

  9. C++ 学习笔记之——输入和输出

    在 C++ 中,我们通过调用输入输出流库中的流对象 cin 和 cout 来实现输入和输出. #include <iostream> using namespace std; int ma ...

  10. 编译 TensorFlow 的 C/C++ 接口

    TensorFlow 的 Python 接口由于其方便性和实用性而大受欢迎,但实际应用中我们可能还需要其它编程语言的接口,本文将介绍如何编译 TensorFlow 的 C/C++ 接口. 安装环境: ...