Git Product home page Git Product logo

Comments (22)

creeperyang avatar creeperyang commented on August 23, 2024 7

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")。

下面是我改业务代码后的两次编译:

2017-08-28 12 56 56

2017-08-28 12 57 34

可以看到 vendor 的 chunkhash 没有变化。很好,终于可以愉快的利用浏览器缓存了!

from blog.

creeperyang avatar creeperyang commented on August 23, 2024 1

@hanxiansen https://github.com/webpack-contrib/webpack-bundle-analyzer

from blog.

creeperyang avatar creeperyang commented on August 23, 2024 1

主要是因为需求太多样化了,前端也越来越复杂了。

而插件越来越多,说明生态繁荣,同时能满足的场景也各式各样。

感觉号称0配置的比如 parcel 这些只能满足一部分需求,但如果没有特殊需求的可以一试。

from blog.

dickenslian avatar dickenslian commented on August 23, 2024 1

总结得很好,children部分的例子对我很有帮助

from blog.

henry-fun avatar henry-fun commented on August 23, 2024


问下博主,上面这种图片是通过什么生成的?

from blog.

qingmingsang avatar qingmingsang commented on August 23, 2024

现在webpack的配置越来越复杂,插件越来越多,越来越累赘了

from blog.

lz-lee avatar lz-lee commented on August 23, 2024

多页配置webpack,需要将每个页面对应的css/less单独打包成对应的css,为什么设置minChunks >=2 就可以,而设置为 1 就只打包成一个css文件。

from blog.

creeperyang avatar creeperyang commented on August 23, 2024

@lz-lee minChunks 指定 1 相当于命中所有chunks(每个chunk必然出现 >= 1 次),即所有 chunk 打包为一个文件。

建议提问前可以先阅读官方文档

from blog.

creeperyang avatar creeperyang commented on August 23, 2024

3. 命令行里输出详细错误原因

合格的程序员碰到错误的第一反应一定是自己先找原因,而不是去问别人。

0配置打包工具的火爆说明webpack某种程度上比较繁琐,尤其当你碰到错误时。排除错误的前提是可以找到原因,查找原因的前提是错误信息详细输出——善用stats配置。

具体的配置官方文档都有,不再细述,这里主要强调怎么防止配置不起作用:

  1. 使用 webpack-dev-server 时需要把statsdevServer里。

  2. 使用 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.

kunsun avatar kunsun commented on August 23, 2024

关于chunks的分类,讲的特别好,赞

from blog.

kunsun avatar kunsun commented on August 23, 2024

不过webpack4.0.1 好像取消了children chunks的配置,不知道是不是理解有误

from blog.

creeperyang avatar creeperyang commented on August 23, 2024

@kunsun 对。4.0 去除CommonsChunkPlugin,使用 optimization.splitChunks/optimization.runtimeChunk 代替。

可以参考阅读:

from blog.

qingmingsang avatar qingmingsang commented on August 23, 2024
new webpack.optimize.CommonsChunkPlugin({
  name: 'client',
  async: 'chunk-vendor',
  children: true,
  minChunks: (module, count) => {
    // 被 3 个及以上 chunk 使用的共用模块提取出来
    return count >= 3
  }
})

请问这个配置里的client是一个单独的entry的name吗,我试着直接用似乎没有效果

from blog.

nlffeng avatar nlffeng commented on August 23, 2024

@creeperyang 关于webpack.optimize.CommonsChunkPlugin 与优化浏览器端缓存
在项目中静态导入本地模块时(import),vendor(公共模块)的chunkhash不会发生变化,但当我在项目中动态导入时(dynamic import),vendor的chunkhash会发生变化,不知原因是为何?
假如项目较大,就需要按需加载(dynamic import),vendor的chunkhash每次都发生变化,如何做到缓存呢?

from blog.

creeperyang avatar creeperyang commented on August 23, 2024

@nlffeng 可以给个repo或者其它例子实际查看下吗?

from blog.

nlffeng avatar nlffeng commented on August 23, 2024

@creeperyang 首先感谢回答,以下是我的webapck配置
image
1、当我在js文件动态导入2个(模块/js文件),构建打包后如下:
image
2、当我在js文件动态导入1个时,构建打包后,这时vendor的chunkhash发生了变化,如下:
image
vendor是公共库,是没有发生变化的,此处由于动态导入模块,引起了vendor的chunkId发生了变化,即vendor内容中chunkId值发生了变化,导致chunkhash变化,这样,在一个项目中,每次添加一个动态导入时,它的公共库的chunkhash都会发生变化,如何做到缓存呢?

from blog.

creeperyang avatar creeperyang commented on August 23, 2024

@nlffeng 考虑下搭配 NamedModulesPlugin/HashedModuleIdsPlugin 使用。

https://webpack.js.org/guides/caching/#src/components/Sidebar/Sidebar.jsx

from blog.

nlffeng avatar nlffeng commented on August 23, 2024

@creeperyang 我的配置中是有HashedModuleIdsPlugin这个,这个插件是可以保持node_modules当中的模块的id不变,但是生成vendor后这个模块的id会和受其它动态导入的模块的影响,才会产生这种chunkhash变化的情况,楼主可以试一试,目前还没找到如何保持这个vendor的moduleId保持不变的方法!

from blog.

cqq626 avatar cqq626 commented on August 23, 2024

@creeperyang
2018-08-08 11 34 21
我是使用了vue-router的懒加载,这样改完后,异步加载组件里的类库仍没被抽离出来,chunk-vendor文件没有生成,求指点..
webpack版本是3.3.0

from blog.

creeperyang avatar creeperyang commented on August 23, 2024

@cqq626 可以设置stats.chunks/stats.children等,查看webpack实际是怎么为你处理的。

from blog.

yy6597988 avatar yy6597988 commented on August 23, 2024

@creeperyang 我的配置中是有HashedModuleIdsPlugin这个,这个插件是可以保持node_modules当中的模块的id不变,但是生成vendor后这个模块的id会和受其它动态导入的模块的影响,才会产生这种chunkhash变化的情况,楼主可以试一试,目前还没找到如何保持这个vendor的moduleId保持不变的方法!

https://segmentfault.com/a/1190000015919928

from blog.

lz-lee avatar lz-lee commented on August 23, 2024

from blog.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.