Comments (22)
2. webpack.optimize.CommonsChunkPlugin
与优化浏览器端缓存
浏览器下载静态文件是非常耗时的,所以为了提高性能,浏览器尽一切可能来使用缓存。通常情况下,
- 对同名的静态文件,浏览器根据之前的 response header 使用 协商缓存 或 强缓存;
- 想要资源更新后浏览器可以正确获取新的资源,一般更新文件名。
所以生产中,我们一般在文件名中加入 hash,即文件内容变化,则文件名变化。这样自动利用浏览器缓存且不会妨碍文件更新。
hash vs chunkhash
在 webpack 里,我们可以通过 hash/chunkhash 来自动更新文件名:
output: {
filename: '[name].[chunkhash:8].js'
},
其中:
- hash 是 build-specific ,即每次编译都不同——适用于开发阶段。
- chunkhash 是 chunk-specific,是根据每个 chunk 的内容计算出的 hash——适用于生产。
怎么最大化利用浏览器缓存?(怎么保证 vendor 的有效缓存?)
有了 chunkhash,看起来我们已经可以正常利用浏览器缓存了。但 webpack 有个已知问题:
webpack 自身的 boilerplate 和 manifest 代码可能在每次编译时都会变化。
这导致我们只是在 入口文件 改了一行代码,但编译出的 vendor 和 entry chunk 都变了,因为它们自身都包含这部分代码。
这是不合理的,因为我们的依赖(node_modules)没变,vendor 不应该在我们业务代码变化时发生变化!而 vendor 通常 size 很大,每次发布业务代码导致 vendor 变化无法利用缓存是不可接受的。
很直接的解决方案:为什么不把 webpack 自身的这部分代码分离出来呢?
new webpack.optimize.CommonsChunkPlugin({
name: "runtime",
minChunks: Infinity
}),
配置很简单,如上即可。(name 只要不在 entry 里出现过即可,但通常使用 "runtime"/"manifest"
)。
下面是我改业务代码后的两次编译:
可以看到 vendor 的 chunkhash 没有变化。很好,终于可以愉快的利用浏览器缓存了!
from blog.
@hanxiansen https://github.com/webpack-contrib/webpack-bundle-analyzer
from blog.
主要是因为需求太多样化了,前端也越来越复杂了。
而插件越来越多,说明生态繁荣,同时能满足的场景也各式各样。
感觉号称0配置的比如 parcel 这些只能满足一部分需求,但如果没有特殊需求的可以一试。
from blog.
总结得很好,children部分的例子对我很有帮助
from blog.
from blog.
现在webpack的配置越来越复杂,插件越来越多,越来越累赘了
from blog.
多页配置webpack,需要将每个页面对应的css/less单独打包成对应的css,为什么设置minChunks >=2 就可以,而设置为 1 就只打包成一个css文件。
from blog.
@lz-lee minChunks
指定 1 相当于命中所有chunks(每个chunk必然出现 >= 1 次),即所有 chunk 打包为一个文件。
建议提问前可以先阅读官方文档
from blog.
3. 命令行里输出详细错误原因
合格的程序员碰到错误的第一反应一定是自己先找原因,而不是去问别人。
0配置打包工具的火爆说明webpack某种程度上比较繁琐,尤其当你碰到错误时。排除错误的前提是可以找到原因,查找原因的前提是错误信息详细输出——善用stats
配置。
具体的配置官方文档都有,不再细述,这里主要强调怎么防止配置不起作用:
-
使用 webpack-dev-server 时需要把
stats
放devServer
里。 -
使用 Node.js API 时
stats
不起作用,但可以使用webpack-dev-middleware的配置:const devMiddleware = require('webpack-dev-middleware')(compiler, { publicPath: webpackConfig.output.publicPath, stats: { warnings: true, reasons: true, errors: true, errorDetails: true, colors: true, } // quiet: true });
from blog.
关于chunks的分类,讲的特别好,赞
from blog.
不过webpack4.0.1 好像取消了children chunks的配置,不知道是不是理解有误
from blog.
@kunsun 对。4.0 去除 了 CommonsChunkPlugin
,使用 optimization.splitChunks/optimization.runtimeChunk
代替。
可以参考阅读:
- https://medium.com/webpack/webpack-4-beta-try-it-today-6b1d27d7d7e2
- https://gist.github.com/sokra/1522d586b8e5c0f5072d7565c2bee693
from blog.
new webpack.optimize.CommonsChunkPlugin({
name: 'client',
async: 'chunk-vendor',
children: true,
minChunks: (module, count) => {
// 被 3 个及以上 chunk 使用的共用模块提取出来
return count >= 3
}
})
请问这个配置里的client是一个单独的entry的name吗,我试着直接用似乎没有效果
from blog.
@creeperyang 关于webpack.optimize.CommonsChunkPlugin 与优化浏览器端缓存
在项目中静态导入本地模块时(import),vendor(公共模块)的chunkhash不会发生变化,但当我在项目中动态导入时(dynamic import),vendor的chunkhash会发生变化,不知原因是为何?
假如项目较大,就需要按需加载(dynamic import),vendor的chunkhash每次都发生变化,如何做到缓存呢?
from blog.
@nlffeng 可以给个repo或者其它例子实际查看下吗?
from blog.
@creeperyang 首先感谢回答,以下是我的webapck配置
1、当我在js文件动态导入2个(模块/js文件),构建打包后如下:
2、当我在js文件动态导入1个时,构建打包后,这时vendor的chunkhash发生了变化,如下:
vendor是公共库,是没有发生变化的,此处由于动态导入模块,引起了vendor的chunkId发生了变化,即vendor内容中chunkId值发生了变化,导致chunkhash变化,这样,在一个项目中,每次添加一个动态导入时,它的公共库的chunkhash都会发生变化,如何做到缓存呢?
from blog.
@nlffeng 考虑下搭配 NamedModulesPlugin/HashedModuleIdsPlugin
使用。
https://webpack.js.org/guides/caching/#src/components/Sidebar/Sidebar.jsx
from blog.
@creeperyang 我的配置中是有HashedModuleIdsPlugin这个,这个插件是可以保持node_modules当中的模块的id不变,但是生成vendor后这个模块的id会和受其它动态导入的模块的影响,才会产生这种chunkhash变化的情况,楼主可以试一试,目前还没找到如何保持这个vendor的moduleId保持不变的方法!
from blog.
@creeperyang
我是使用了vue-router的懒加载,这样改完后,异步加载组件里的类库仍没被抽离出来,chunk-vendor文件没有生成,求指点..
webpack版本是3.3.0
from blog.
@cqq626 可以设置stats.chunks/stats.children
等,查看webpack实际是怎么为你处理的。
from blog.
@creeperyang 我的配置中是有HashedModuleIdsPlugin这个,这个插件是可以保持node_modules当中的模块的id不变,但是生成vendor后这个模块的id会和受其它动态导入的模块的影响,才会产生这种chunkhash变化的情况,楼主可以试一试,目前还没找到如何保持这个vendor的moduleId保持不变的方法!
https://segmentfault.com/a/1190000015919928
from blog.
from blog.
Related Issues (20)
- JavaScript问题集锦(二) HOT 5
- mark
- 怎么用Vue.js改造(大型)传统PHP网站? HOT 12
- wrong
- 学习与理解 React Fiber HOT 3
- Vue源码解析
- 浏览器的工作原理 HOT 2
- 从零开始学习 Android (笔记) HOT 2
- 三元 vs if else HOT 1
- 每周一读(高质量文章/视频浏览记录) HOT 2
- 算法学习(JavaScript实现) HOT 6
- mobx 学习笔记
- 了解 JavaScript 中的事件循环
- 牛逼 HOT 2
- __proto__
- Web性能指标与相关优化
- webpack runtime 源码分析
- webpack 核心概念和优化指南 HOT 2
- 从浏览器关键渲染路径聊起
- 日常问题记录 HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from blog.