美文网首页webapck 4.x
webpack 浏览器缓存(16)

webpack 浏览器缓存(16)

作者: 瓦力博客 | 来源:发表于2019-06-12 10:44 被阅读6次

    获取全套webpack 4.x教程,请访问瓦力博客

    小菜之前写过关于浏览器是如何缓存的nginx 缓存{:target="_blank"},感兴趣的小伙伴们可以看看。在前面小菜写的配置都是如何去缓存

    //build/output.js
    
    const srcPath = require('./base/path');
    const config = require('./base/config');
    
    let output = {
        path: srcPath.dist,
        filename: '[name].[hash].js',
        publicPath: config.publicPath
    }
    
    module.exports = output;
    

    如果output.js中这样写filename:'[name].[hash].js',每次打包都会重新生成js文件(文件名不重名),上传到服务器,用户在客户端上刷新都会重新从服务器上拉取js文件,这样就会造成请求资源浪费。

    1.演示

    安装loadsh

    之前没有安装过loadsh库伙伴需要安装一下

    yarn add loadsh
    

    index.js

    import _ from 'loadsh';
    
    let arr = ['hello','world'];
    
    let str = _.join(arr,'--');
    console.log(str)
    

    编译webpack

    yarn run prod
    
    ssl

    修改index.js

    import _ from 'loadsh';
    
    +  let arr = ['hello','wali'];
    
    let str = _.join(arr,'--');
    console.log(str)
    

    编译webpack

    yarn run prod
    
    ssl

    从上面两个截图可以发现,当我们修改index.js文件的代码后,重新打包生成main.jsvendors~main后面的hash值变了。因为我们修改index.js文件的代码,在index.js中引用的第三方库文件,loadsh是不需修改的,所以打包后我们希望mian.js的hash值变,而vendors~main的hash值不变。

    2.配置webpack

    为了实现上面的功能,我们需要对webpack配置做一些改变

    build/output.js

    const dirPath = require('./base/path');
    const config = require('./base/config');
    
    let output = {
        path:dirPath.dist,
    +   filename: config.NODE_ENV == 'development'?'[name].js':'[name].[contenthash].js',
    +   chunkFilename: config.NODE_ENV == 'development'?'[name].js':'[name].[contenthash].js',
        publicPath: config.publicPath
    }
    
    module.exports = output
    

    build/optimization.js

    let optimization = {
        usedExports: true,
        splitChunks: {
            chunks: 'all',
            minSize: 30000,
            maxSize: 0,
            minChunks: 1,
            maxAsyncRequests: 5,
            maxInitialRequests: 3,
            automaticNameDelimiter: '~',
            name: true,
            cacheGroups: {
                vendors: {
                    test: /[\\/]node_modules[\\/]/,
                    priority: -10
                },
                default: {
                    minChunks: 2,
                    priority: -20,
                    reuseExistingChunk: true
                }
            }
        },
    +   runtimeChunk:{
    +       name: entrypoint => `runtimechunk~${entrypoint.name}`
    +   }
    }
    
    module.exports = optimization
    

    build/plugins.js

    const dirpath = require('./base/path');
    const config = require('./base/config');
    
    const webpack = require('webpack');
    const HtmlWebpackPlugin = require('html-webpack-plugin');    //生成html文件
    const { CleanWebpackPlugin } = require('clean-webpack-plugin');  //清除
    const MiniCssExtractPlugin = require("mini-css-extract-plugin");  //css样式提取
    
    
    let plugins = [
        new HtmlWebpackPlugin({
            title: '瓦力博客',
            template: dirpath.src + '/index.html'   //以src/index.html为编译模板
        }),
        new  MiniCssExtractPlugin({
            filename: config.NODE_ENV == 'development'?'[name.css]': `${dirpath.css}/[name].[hash].css`,
            chunkFilename: config.NODE_ENV == 'development'?'[id].css': `${dirpath.css}/[id].[hash].css`
        }),   //css提取
        new CleanWebpackPlugin(),
    -   new webpack.HotModuleReplacementPlugin()    
    ]
    
    + if('development' == config.NODE_ENV){
    +   plugins.push(new webpack.HotModuleReplacementPlugin());
    + }
    
    module.exports = plugins;
    

    index.js

    import _ from 'loadsh';
    
    let arr = ['hello','world'];
    
    let str = _.join(arr,'--');
    console.log(str)
    

    运行webpack

    yarn run prod
    
    ssl

    修改index.js

    import _ from 'loadsh';
    
    + let arr = ['hello','wali'];
    
    let str = _.join(arr,'--');
    console.log(str)
    

    运行webpack

    yarn run prod
    
    ssl

    从上面两张截图中可以看出来,当我们修改index.js文件内容。main.js后面的hash值发生改变,vendors~main.js后面hash值保持不变。当用户在浏览页面时,我们修改本地代码,打包上传后,用户刷新浏览器,浏览器只会请求hash改变的js文件,而hash值没变的文件依旧从浏览器缓存读取。

    3.总结

    写本小节的时候,小菜遇到了两个问题,分享给大家

    [contenthash]打包报错

    小菜在调式时,直接在build/output.js文件中这样写

    let output = {
        path:dirPath.dist,
    +   filename: '[name].[contenthash].js',
    +   chunkFilename: '[name].[contenthash].js',
        publicPath: config.publicPath
    }
    

    在运行yarn run prod报错,报错信息

    ERROR in chunk runtimechunk~main [entry]
    [name].[contenthash].js
    Cannot use [chunkhash] or [contenthash] for chunk in '[name].[contenthash].js' (use[hash] instead)
    

    不能使用[chunkhash][contenthash]在网上找到资料解决连接{:target="_blank"}。在用new webpack.HotModuleReplacementPlugin()热更新插件的时候是不能使用[chunkhash][contenthash],所以小菜build/plugins.js中修改配置,添加了判断,只有在development模式下才在使用new webpack.HotModuleReplacementPlugin(),然后在output.js中添加判断,问题就解决了

    const dirPath = require('./base/path');
    const config = require('./base/config');
    
    let output = {
        path:dirPath.dist,
    +   filename: config.NODE_ENV == 'development'?'[name].js':'[name].[contenthash].js',
    +   chunkFilename: config.NODE_ENV == 'development'?'[name].js':'[name].[contenthash].js',
        publicPath: config.publicPath
    }
    
    module.exports = output
    

    运行yarn run dev命令本地服务器不来

    说起来很搞笑,按道理到上面配置基本都没问题了,小菜就运行yarn run dev启动本地服务,发现页面起不来

    ssl ssl

    这个问题排查了很久,最终发现小菜在build/base/config.js中将

    let _mode = process.argv[process.argv.length - 1];
    let env = _mode.replace(/--mode=(.+)/g,"$1");
    
    let config = {
        NODE_ENV: env == 'development'?'development':'production',  //development 开发 production 线上
    -   publicPath: env == 'development'?'./':'http://www.waliblog.com',
    +   publicPath: env == 'development'?'/':'http://www.waliblog.com',
        apiUrl:'http://www.waliblog.com',
        port: 9999
    }
    
    module.exports = config;
    

    本地服务路径./弄错了,所以服务起起来但是一直找不到根路径,页面也无法访问。当时这么写是因为想在生成index.html查看路径,后面一直没有改才会碰到这个问题。这个问题找到后,小菜将webpack-14{:target="_blank"}这节配置重新写了一遍,之后又重新跑了一遍,所以小伙伴们可能遇不到我这个问题。

    相关文章

      网友评论

        本文标题:webpack 浏览器缓存(16)

        本文链接:https://www.haomeiwen.com/subject/mqekfctx.html