文件指纹
什么是文件指纹?
文件指纹指的是打包后输出的文件名的后缀。
文件指纹如何生成?
-
Hash:和整个项目的构建相关,只要项目文件有修改,整个项目构建的 hash 值就会更改。
-
Chunkhash:和 webpack 打包的 chunk 有关,不同的 entry 会生成不同的 chunkhash 值。
-
ContentHash:根据文件内容来定义 hash,文件内容不变,则 contenthash 不变。
JS的文件指纹设置
设置 output 的 filename,使用[chunkhash]
js使用 chunkhash
module.exports = {
entry: {
app: './src/app.js',
search: './src/search.js'
},
output: {
filename: '[name][chunkhash:8].js',
path: __dirname + '/dist'
}
}
CSS 的文件指纹设置
设置 MiniCssExtractPlugin 的 filename,使用 [contenthash]
CSS使用 contenthash
module.exports = {
entry: {
app: './src/app.js',
search: './src/search.js'
},
output: {
filename: '[name][chunkhash:8].js',
path: __dirname + '/dist'
},
plugins: [
new MiniCssExtractPlugin({
filename: `[name][contenthash:8].css`
});
]
};
图片的文件指纹设置
设置 file-loader 的 name
使用 hash
占位符名称 | 含义 |
---|---|
[ext] | 资源后缀名 |
[name] | 文件名称 |
[path] | 文件的相对路径 |
[folder] | 文件所在的文件夹 |
[contenthash] | 文件的内容 hash,默认是 md5 生成 |
[hash] | 文件内容的 hash,默认是 md5 生成 |
[emoji] | 一个随机的指代文件内容的 emoji |
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rule[
{
test: /.(png|svg|jpg|gif)$/,
use: [{
loader: 'file-loader',
options: {
name: 'img/[name][hash:8].[ext]'
}
}]
}
]
}
};
在这里要注意的是,这个时候我们要把 webpack 的配置文件分成两个:
-
webpack.dev.js
"use strict"; const path = require("path"); const webpack = require("webpack"); module.exports = { entry: "./src/search.js", output: { path: path.join(__dirname, "dist"), filename: "bundle.js", }, mode: "development", module: { rules: [ { test: /.js$/, use: "babel-loader", }, { test: /.css$/, use: ["style-loader", "css-loader"], // style-loader 的顺序必须在 css-loader 之前 }, { test: /.less$/, use: ["style-loader", "css-loader", "less-loader"], }, { test: /.(png|jpg|gif|jpeg)$/, use: [ { loader: "url-loader", options: { limit: 10240, }, }, ], }, { test: /.(woff|woff2|eot|ttf|otf)$/, use: "file-loader", }, ], }, plugins: [ // 热更新插件为 webpack 内置的 new webpack.HotModuleReplacementPlugin(), ], devServer: { // 设定 devServer 默认服务目录 dist contentBase: path.join(__dirname, "dist"), // 开启热更新 hot: true, }, };
-
webpack.prod.js
"use strict"; // 生成环境没有热更新,生产环境热更新没用 const path = require("path"); const webpack = require("webpack"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { entry: "./src/search.js", output: { path: path.join(__dirname, "dist"), // 输出路径 | 加入 js 文件指纹 filename: "[name]_[chunkhash:8].js", }, mode: "production", module: { rules: [ { test: /.js$/, use: "babel-loader", }, { test: /.css$/, use: [MiniCssExtractPlugin.loader, "css-loader"], // style-loader 的顺序必须在 css-loader 之前 }, { test: /.less$/, use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"], }, { test: /.(png|jpg|gif|jpeg)$/, use: [ { loader: "file-loader", options: { name: "[name]_[hash:8].[ext]", }, }, ], }, { test: /.(woff|woff2|eot|ttf|otf)$/, use: [ { loader: "file-loader", options: { name: "[name]_[hash:8].[ext]", }, }, ], }, ], }, plugins: [ // 注意 // 这个插件和 style-loader 插件互斥 // 只能选择一个 // 我们要把 CSS 提取出来成为一个单独的文件,然后引入.css new MiniCssExtractPlugin({ filename: "[name]_[contenthash:8].css", }), ], };
而且,还要修改一下package.json,调整下启动的命令。
"scripts": { "test": "echo "Error: no test specified" && exit 1", "dev": "webpack-dev-server --config webpack.dev.js --open", "build": "webpack --config webpack.prod.js", "watch": "webpack --watch" },