webpack中的文件监听
文件监听是在发现源码发生变化的时候,自动重新构建出新的输出文件。
webpack开启监听模式的两种模式:
- 启动
webpack
命令时候,带上--watch
参数
package.json
中配置如下:
"scripts": {
"build": "webpack --watch"
},
复制代码
上面方式有个缺陷,就是每次webpack更新代码,都要手动刷新浏览器!
- 在配置
webpack.config.js
中设置watch:true
通过轮询判断文件的最后编辑时间,是否发生变化,当某个文件发生变化,并不会立即告诉监听者,而是先缓存起来,等aggregateTimeout。
module.exports = {
// 默认是false ,不开启状态
watch: true,
// 只有开启监听模式watchOptions才有意义
watchOptions: {
// 不监听的文件或者文件夹,默认为空,支持正则匹配。
ignored: /node_modules/,
// 监听到变化发生后,会等300ms再去执行更新,默认是300ms
aggregateTimeout: 300,
// 判断文件是否发生变化,是通过不停的询问系统指定文件有没有发生变化实现的,默认每秒问1000次。
poll: 1000
},
}
复制代码
webpack中的热更新:webpack-dev-server及其原理
首先安装: npm i webpack-dev-server -D
在package.json
中配置如下:
"scripts": {
"dev": "webpack-dev-server --open"
},
复制代码
在webpack.config.js
中配置:
const webpack = require('webpack');
module.exports = {
mode: 'development', // 开发环境
plugins: [
// webpack 自带的热更新插件
new webpack.HotModuleReplacementPlugin()
],
devServer: {
contentBase: './dist', // webpack服务的基础目录
hot: true
}
}
复制代码
webpack中的热更新:webpack-dev-middleware(WDM)及其原理。
WDM将webpack输出的文件传输服务器,适用于灵活的应用场景。
const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-devmiddleware');
const app = express();
const config = require('./webpack.config.js'); const compiler = webpack(config);
app.use(webpackDevMiddleware(compiler, { publicPath: config.output.publicPath
}));
app.listen(3000, function () {
console.log('Example app listening on port 3000!\n');
});
复制代码
原理分析
webpack compile: 将js编译成,bundle.js
HMR Server:将热更新的文件输出给 HMR Runtime
Bundle server: 提供文件在浏览器的访问
HMR runtime: 会被注入到浏览器,更新文件的变化。
bundle.js:构建输出的文件
原理图如下所示:
文件指纹策略
打包后输出的文件名的后缀
文件指纹如何生成?
- hash:整个项目的构建相关,只要项目文件有修改,整个项目的构建的hash就会改变。
- Chunkhash:和webpack打包的chunk有关,不同的entry会生成不同的chunkhash值。
- contenthash:根据文件内容来定义hash,文件内容不变,则contenthash不变。
js的文件指纹的设置
设置 output 的 filename,使用 [chunkhash]
module.exports = {
output: {
filename: '[name]_[chunkhash:8].js',
path: path.join(__dirname, 'dist')
},
}
复制代码
css的文件指纹的设置
设置MiniCssExtractPlugin
的filename,使用[contenthash]
占位符名称 | 含义 |
---|---|
[ext] |
资源后缀名 |
[name] |
文件名称 |
[path] |
文件的相对路径 |
[folder] |
文件所在的文件夹 |
[contenthash] |
文件的内容hash,默认是md5生成 |
[hash] |
文件的内容hash,默认是md5生成 |
[emoji] |
一个随机的指代文件内容的emoji |
首先安装插件 npm install mini-css-extract-plugin -D
在新建的 webpack.prod.js
文件中配置:
module: {
rules: [
{
test: /\.js$/, // 匹配js文件
use: 'babel-loader' // 用于将ES6等高级语法解析成ES5语法
},
{
test: /\.css$/,
use: [ // 注意 解析顺序是从右往左的,先解析css-loader 后解析style-loader将css插入dom中。
// 'style-loader',
MiniCssExtractPlugin.loader, // MiniCssExtractPlugin是将css代码提取出来,这两个loader不能同时使用。
'css-loader'
]
},
{
test: /\.less$/,
use: [
// 'style-loader',
MiniCssExtractPlugin.loader, // MiniCssExtractPlugin是将css代码提取出来,这两个loader不能同时使用。
'css-loader',
'less-loader' // 用于解析less
]
},
{
test: /\.(png|jpg|gif|svg|jpeg)$/,
use: [
{
loader: 'file-loader', // file-loader 和url-loader都行
options: {
name: '[name]_[hash:8][ext]'
}
}
]
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
{
loader: 'file-loader', // file-loader 和url-loader都行
options: {
name: '[name]_[hash:8][ext]'
}
}
]
}
]
},
复制代码
webpack 的代码的压缩
js文件的压缩
webpack 内置了,uglifyjs-webpack-plugin
在打包代码的时候,会自动压缩js代码。
css 文件的压缩
使用optimize-css-assets-webpack-plugin
,同时使用需要依赖 cssnano
预处理器
安装 npm i optimize-css-assets-webpack-plugin cssnano -D
在webpack.prod.js
中配置plugins:
const OptimizeCssAssetsWebpackPlugin = requir('optimize-css-assets-webpack-plugin')
plugins: [
new OptimizeCssAssetsWebpackPlugin({
assetNameRegExp:/.css$/g,
cssProcessor: require('cssnano')
})
],
复制代码
执行 npm run build
查看压缩效果
html文件的压缩
首先安装插件: npm i html-webpack-plugin -D
在webpack.prod.js
配置文件中配置:
const HtmlWebpackPlugin = require('html-webpack-plugin')
plugins: [
new MiniCssExtractPlugin({
filename: `[name]_[contenthash:8].css`
}),
new OptimizeCssAssetsWebpackPlugin({
assetNameRegExp: /.css$/g,
cssProcessor: require('cssnano')
}),
new HtmlWebpackPlugin({ // 通常一个html页面用一个HtmlWebpackPlugin,如果有两那就写两个
template: path.join(__dirname, 'src/index.html'), //html模板所在的位置
filename: 'index.html',// 指定打包出来的html文件名称
chunks: ['index'],// chunk名称 指定生成的html要使用哪些chunk
inject: true,// 是否将打包出来的js或者css将自动注入到index.html中
minify: {
html5: true,
collapseWhitespace: true,
preserveLineBreaks: false,
minifyCSS: true,
minifyJS: true,
removeComments: false
}
}),
new HtmlWebpackPlugin({ // 通常一个html页面用一个HtmlWebpackPlugin,如果有两那就写两个
template: path.join(__dirname, 'src/search.html'), //html模板所在的位置
filename: 'search.html',// 指定打包出来的html文件名称
chunks: ['search'],// chunk名称 指定生成的html要使用哪些chunk
inject: true,// 是否将打包出来的js或者css将自动注入到search.html中
minify: {
html5: true,
collapseWhitespace: true,
preserveLineBreaks: false,
minifyCSS: true,
minifyJS: true,
removeComments: false
}
}),
],
复制代码
执行 npm run build
查看压缩效果