什么是长缓存优化,webpack如何做到
浏览器在用户访问页面的时候,为了加快加载速度,会对用户访问的静态资源进行存储,但是每一次代码升级或者更新,都需要浏览器去下载新的代码,最方便和简单的更新方式就是引入新的文件名称。
在webpack中,可以在output给输出的文件指定chunkhash,并且分离经常更新的代码和框架代码,通过NamedModulesPlugin和NamedChunksPlugin使再次打包的文件名字不变。
循序渐进
场景一: 改变app(业务代码)时,vendor变化
1 | // foo.js |
1 | // webpack.config.js |
打包产物:

然后改变代码:
1 | // foo.js |
再看产物:

对于一个项目来说,第三方库一般是不会变化的,如何做到改变app,vendor版本不变化?
其实提取vendor即可。
改变配置如下:
1 | // webpack.config.js |
产物:

变化代码1
2
3// foo.js
import react from 'react'
console.log('This is foo.js~!!!')
再看产物:

诶。。。怎么还是变化了,大小差不多
别忘了配置plugin: commonChunkPlugin把公用的代码提取出来
1 | // webpack.config.js |
打包前后变化:

二者版本一样,此时使用chunkHash试试
1 | // webpack.config.js |
对比:
此时还差一步:提取runtime
1 | new Webpack.optimize.CommonsChunkPlugin({ |

至此 场景一解决
场景二: 引入新的模块,模块顺序变化,vendor hash发生变化
1 | // foo.js |
1 | // module.js |
对比图

解决方案:
NamedChunksPlugin chunkId => name
NamedModulesPlugin moduleId => moduleName
1 | new Webpack.NamedChunksPlugin() |

隐藏的modules也来给指定一个名字:
1 | new Webpack.NamedModulesPlugin() |

场景二顺利解决!!!
场景三: 动态引入,hash变化
1 | import('./async').then(function(a) { |

解决方案动态模块给定模块名称:
1 | import(/* webpackChunkName: 'async' */'./async').then(function(a) { |

ok,场景三也搞定了~
最后五步走
1、独立打包vendor、commonChunksPlugin、hash=>chunkHash
2、抽取出manifest,inline到html
3、NamedChunksPlugin chunkId => name
4、NamedModulesPlugin moduleId => moduleName
5、动态模块给定模块名称
最终配置拿走不谢
1 | var path = require('path') |
1 | import(/* webpackChunkName: 'async' */'./async').then(function(a) { |