# 缓存

浏览器和服务器为了提高访问速度,都会分别实现自己的缓存机制。在这里我们将通过变化输出的文件名来防止缓存。

# 输出文件的文件名

[name] 会被真正的文件名所替换, 其他的含义看下面表格

module.exports = {
    entry:{
        app: './src/index.js'
    },
    output: {
        filename: '[name].bundle.[chunkhash:8].js',
        chunkFilename: '[name].[contenthash].bundle.js',
        path: path.resolve(__dirname, '..', 'dist')
    }
}
模板 描述
[fullhash] 编译的所有 hash 值
[hash] 同上,弃用
[id] chunk 的 ID
[name] chunk 的名称, 如果未设置则使用 id
[chunkhash] chunk 的 hash 值, 包含所有元素
[contenthash] chunk 的 hash 值, 只包含内容类型的元素

只包含部分内容, 所有内容见 https://webpack.js.org/configuration/output/#outputfilename (opens new window)

# 提取样板

形如 import('abc').then(res=>{}) 这种动态导入的代码,在webpack中即为运行时代码。在代码分离中知道,这种代码会被分离出来。那么还有什么问题呢?

缓存问题,加入 abc 模块有更改,那么引用 abc 的代码,编译后的 hash 值也会跟随发生变化,这样的话,明明没有修改的代码,缓存却不能用了,因此,我们需要将包含 chunks 映射关系的list 单独分离出来。

module.exports = {
    entry:{
        app: './src/index.js'
    },
    output: {
        filename: '[name].bundle.[chunkhash:8].js',
        path: path.resolve(__dirname, '..', 'dist')
    },
    optimization: {
        runtimeChunk: 'single'
    },
};

代码

window.addEventListener("click", function () {
    import(/* webpackChunkName: "lodash" */ "lodash").then(function({default: _}) {
        console.log(_.ceil(1.24));
    })
})

生成的文件

app.bundle.15803dd9.js
runtime.bundle.32130354.js
lodash.bundle.731c7c29.js

# 将第三方库提出出来

像 lodash 等三方的模块,我们几乎不会去修改,那么单独提取出来,会是一个很好的做法

module.exports = {
    entry:{
        app: './src/index.js'
    },
    output: {
        filename: '[name].bundle.[chunkhash:8].js',
        path: path.resolve(__dirname, '..', 'dist')
    },
    optimization: {
        runtimeChunk: 'single',
        splitChunks: {
            cacheGroups: {
                vendor: {
                    test:/[\\/]node_modules[\\/]/,
                    name: 'vendors',
                    chunks: 'all'
                }
            }
        }
    }
}

生成文件

app.bundle.e5ad9d35.js
runtime.bundle.d92c5453.js
vendors.bundle.b6ca0ed5.js

# 模块标识符

因为每个 module.id 会基于默认的解析顺序(resolve order)进行增量。也就是说,当解析顺序发生变化,ID 也会随之改变, hash 也会改变

module.exports = {
    entry:{
        app: './src/index.js'
    },
    output: {
        filename: '[name].bundle.[chunkhash:8].js',
        path: path.resolve(__dirname, '..', 'dist')
    },
    optimization: {
        moduleIds: 'hashed',
        runtimeChunk: 'single',
        splitChunks: {
            cacheGroups: {
                vendor: {
                    test:/[\\/]node_modules[\\/]/,
                    name: 'vendors',
                    chunks: 'all'
                }
            }
        }
    }
}

用 hash 值来代替模块的引用顺序