zoukankan      html  css  js  c++  java
  • Webpack 三种文件指纹策略 js、css、图片字体资源的指纹设置

    文件指纹

    是什么?
    文件指纹就是打包输出后文件名的后缀

    有什么用?
    文件指纹通常可以用来做一些版本管理,在发布的时候,有修改的文件就发布上去,没有修改的文件还可以继续用浏览器本地缓存,这样可以加速页面访问

    文件指纹类型以及如何生成

    文件指纹有三种类型

    • Hash
    • Chunkhash
    • Contenthash

    Hash

    和整个项目的构建有关,只要项目文件有修改,整个项目构建的hash就会修改

    Compiler 和 Compilation
    Compiler: webpack启动的那一次创建的对象
    Compilation: 只要有一个文件发生了变化,Compilation就会发生改变。 hash受到Compilation的影响而改变

    ChunkHash

    ChunkHash和webpack打包的chunk有关,不同的entry入口会生成不同的chunkhash值,使得chunk保持独立

    如果a页面变化,那么b页面也会变化,这其实是没必要的,因此需要chunkhash
    chunkhash只能用于生产环境,在热更新的时候不会生成

    Contenthash

    根据文件内容定义hash指纹,文件内容不变,则contentHash不变

    如果修改了js,css没有变,如果css也采用chunkhash,导致css内容没有变化但是上传的css chunkhash发生了变化
    因此对于css内容,一般都是根据文件内容来生成css指纹

    配置指纹

    将webpack.config.js拆分为两份
    webpack.dev.config
    webpack.prod.config

    对于生产环境的配置应该去掉热更新相关插件,同时将mode改为production
    同时将package.json中的build脚本指定为webpack.prod.config

    "build":"webpack --config webpack.prod.js"
    "dev":"webpack-dev-server --config webpack.dev.js --open"
    

    设置js文件指纹

    直接在output下修改chunkhash
    仅当entry入口文件内容有变化时,打包生成的chunkhash值才会变化

    配置之前输出:
    app.js
    react-comp.js

    配置之后输出:
    app_76762735.js
    reactComp_456cec63.js

    module.exports = {
        output:{
            path:path.join(__dirname,'./dist'),
            filename:'[name]_[chunkhash:8].js'
        }
    }
    

    完整版

    'use strict';
    const path = require('path');
    module.exports = {
        // 生产模式还是开发模式
        mode: 'production',
        // 入口 指定入口文件
        entry: {
            app:'./src/index.js', 
            // search:'./src/search.js',
            reactComp: './src/react-comp.js'
        },
        // 出口 
        output: {
            // 指定输出目录
            path: path.join(__dirname, 'dist'),
            filename: '[name]_[chunkhash:8].js'
        },
        // 配置loader
        module: {
            rules: [
                {
                    test: /.js$/,
                    use: 'babel-loader'
                },
                {
                    test:/.css$/,
                    use:[
                        'style-loader', // 再将样式插入到style标签中
                        'css-loader' // 将css转换成commonjs
                    ]
                },
                {
                    test: /.less$/,
                    use: [
                        'style-loader', // 再将样式插入到style标签中
                        'css-loader', // 将css转换成commonjs
                        'less-loader' // 将less文件转换成css文件
                    ]
                },
                {
                    test: /.(png|jpg|gif|jpeg)$/,
                    use: [
                        {
                            loader: 'url-loader',
                            options: {
                                limit: 40 * 1024 // 40k
                            }
                        }
                    ]
                },
                {
                    test: /.(woff|woff2|eot|ttf|otf|otf)$/,
                    use: [
                        'file-loader'
                    ]
                }
            ]
        }
    }
    

    设置图片字体等文件指纹

    设置file-loader或url-loader的name,使用[hash]
    此处的hash和前面提到的js hash不一样,这里指的也是文件内容的hash,默认采用md5生成

    如果转换成base64则无法查看hash效果,因此先将url-loader改成file-loader,然后给图片设置文件指纹

    module.exports = {
        module:{
        rules:[
            {
                test:/.(png|svg|jpg|gif)$/,
                use:[
                    loader:'file-loader',
                    options:{
                        name:'/img/[name]-[hash:8].[ext]' 
                    }
                ]
            }
        ]
    }
    }
    

    占位符名称
    [ext] 资源后缀名
    [name] 名称
    [path] 相对路径
    [folder] 文件所在的文件夹
    [contenthash] 文件内容hash,默认由md5生成
    [hash] 文件内容hash,默认由md5生成
    [emoji] 一个随机指代文件内容的emoji

    完整版配置

    'use strict';
    
    const path = require('path');
    
    module.exports = {
        // 生产模式还是开发模式
        mode: 'production',
        // 入口 指定入口文件
        entry: {
            app: './src/index.js',
            reactComp: './src/react-comp.js'
        },
        // 出口 
        output: {
            // 指定输出目录
            path: path.join(__dirname, 'dist'),
            filename: '[name]_[chunkhash:8].js'
        },
        // 配置loader
        module: {
            rules: [
                {
                    test: /.js$/,
                    use: 'babel-loader'
                },
                {
                    test: /.css$/,
                    use: [
                        'style-loader', // 再将样式插入到style标签中
                        'css-loader' // 将css转换成commonjs
                    ]
                },
                {
                    test: /.less$/,
                    use: [
                        'style-loader', // 再将样式插入到style标签中
                        'css-loader', // 将css转换成commonjs
                        'less-loader' // 将less文件转换成css文件
                    ]
                },
                {
                    test: /.(png|jpg|gif|jpeg)$/,
                    use: [
                        {
                            loader:'file-loader',
                            // 图片指纹
                            options:{
                                name:'[name]_[hash:8].[ext]'
                            }
                        }
                    ]
                },
                {
                    test: /.(woff|woff2|eot|ttf|otf|otf)$/,
                    use: [
                        {
                            loader:'file-loader',
                            options:{
                                name:'[name]_[hash:8].[ext]'
                            }
                        }
                    ]
                }
            ]
        }
    }
    

    设置css文件指纹

    避免css没变js变化的时候,css的chunkhash值也随着打包一起变化,因此css应该使用contenthash,

    目前css是以style标签存在于页面中,因此需要使用MiniCssExtractPlugin来抽取成文件再设置文件指纹
    因此这个插件和style-loader是互斥的

    npm i mini-css-Extract-plugin@0.6.0 -D
    

    配置webpack
    除了配置插件外,还需要把插件的loader加进去, 并且这个插件和style-loader是互斥的,因此需要将style-loader替换成MiniCssExtractPlugin.loader

    module.exports = {
        loader:{
            rules:[
                {
                    test:/.css$/,
                    use:[
                        MiniCssExtractPlugin.loader,
                        'css-loader',
                    ]
                },
                {
                    test:/.less$/,
                    use:[
                        MiniCssExtractPlugin.loader,
                        'css-loader',
                        'less-loader'
                    ]
                }
            ]
        }
        plugins:[
            new MiniCssExtractPlugin({
                filename:'[name]_[contenthash:8].css'
            })
        ]
    }
    
  • 相关阅读:
    jquery 不支持$.browser
    js 双向绑定
    css3 省略号
    js生成txt文件
    Browser-sync
    Generator & yield write in sync way
    Charles
    缓动函数与动画
    让Safari使用Chrome的代理
    React 同构
  • 原文地址:https://www.cnblogs.com/ltfxy/p/15328214.html
Copyright © 2011-2022 走看看