zoukankan      html  css  js  c++  java
  • webpack 的第三方库分离并持久化缓存

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

    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单独缓存了!

  • 相关阅读:
    如何将javaweb项目部署到阿里云服务器上
    解决ueditor配置文件第一行报错及乱码问题
    解决web.xml中<async-supported>true</async-supported>报错问题
    解决建完Maven项目没有main文件夹问题
    CentOS常用命令之搜索文件
    CentOS常用命令之创建删除剪切链接
    Jupyter notebook: TypeError: __init__() got an unexpected keyword argument 'io_loop 问题
    编译分布式并行版caffe(Open MPI)教程
    树状数组
    马拉车算法
  • 原文地址:https://www.cnblogs.com/JRliu/p/7204671.html
Copyright © 2011-2022 走看看