
webpack是一个模块打包器,将一切资源(代码资源及非代码资源)进行打包,即根据入口文件找到依赖,会形成一颗依赖树。
Entry
用来指定webpack的打包入口
- 单入口:entry是一个字符串
module.exports = {
entry: './path/entry/file.js'
}
- 多入口:entry是一个对象
module.exports = {
entry: {
app: './src/app.js',
home: './src/home.js'
}
}
Output
用来指定打包的输出,即告诉webpack如何将编译后的文件输出到磁盘
- 单入口配置
module.exports = {
output: {
filename: 'bundle.js',
path: __dirname + '/dist'
}
}
- 多入口配置(通过占位符确保文件名称的唯一)
module.exports = {
output: {
filename: '[name].js',
path: __dirname + '/dist'
}
}
Loaders
webpack开箱即用只支持JS和JSON两种文件类型,通过Loaders去支持其它文件类型并把它们转化成有效的模块,并且可以添加到依赖图中。
本身是一个函数,接受源文件作为参数,返回转换的结果。
| 名称 | 描述 |
|---|---|
| babel-loader |
转换ES6、ES7等JS新特性语法 |
| css-loader | 支持.css文件的加载和解析 |
| less-loader | 将less文件转换为css |
| ts-loader | 将TS转换成JS |
| file-loader | 进行图片、字体等的打包(富媒体) |
| raw-loader | 将文件以字符串的形式导入 |
| thread-loader | 多进程打包JS和CSS |
test指定匹配规则,use指定使用的loader名称
module.exports = {
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader'}
]
}
}
Plugins
用来增强webpack的功能,通常用于打包输出文件的优化,资源管理和环境变量注入,作用于整个构建过程。
常见的Plugins有哪些?
| 名称 | 描述 |
|---|---|
| CommonsChunkPlugin | 将Chunks相同的模块代码提取成公共js |
| CleanWebpackPlugin | 清理构建目录 |
| ExtractTextWebpackPlugin | 将CSS从bundle文件里提取成一个独立的CSS文件 |
| CopyWebpackPlugin | 将文件或者文件夹拷贝到构建的输出目录 |
| HtmlWebpackPlugin | 创建html文件去承载输出的bundle |
| UglifyjsWebpackPlugin | 压缩JS |
| ZipWebpackPlugin |
将打包出的资源生成一个zi |
放到plugins数组里
module.exports = {
plugins: [
new HtmlWebpackPlugin({ template: './src/index.html' })
]
}
Mode
用来指定当前的构建环境:production、development、none,设置mode可以使用webpack内置的函数,默认值是production。
| 选项 | 描述 |
|---|---|
| development | 设置process.env.NODE_ENV的值为development,开启NamedChunkPlugin和NamedModulesPlugin. |
| production | 设置process.env.NODE_ENV的值为production,开启FlagDependencyUsagePlugin,FlagIncludedChunksPlugin,ModuleConcatenationPlugin,NoEmitOnErrorsPlugin,OccurrenceOrderPlugin,SideEffectsFlagPlugin和TerserPlugin |
| none | 不开启任何优化选项 |
解析ES6
使用babel-loader,npm i @babel/core @babel/preset-env babel-loader -D
babel的配置文件是:.babelrc
module.exports = {
rules: [
{
test: /\.js$/,
use: 'babel-loader'
}
]
}
增加ES6的babel preset设置
.babelrc文件
{
"presets": [
"@babel/preset-env"
],
"plugins": [
"@babel/proposal-class-properties"
]
}
注:一个plugins对应一个功能,presets是一系列babel的集合
解析React JSX
presets中增加 @babel/preset-react
npm i react react-dom @babel/preset-react -D
解析CSS、Less和Sass
css-loader 用于加载 .css 文件,并且转换成 commonjs 对象
style-loader 将样式通过 <style> 标签插入到 head 中
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
}
]
}
}
注:loader调用是链式调用,执行顺序从右到左
npm i style-loader css-loader -D
less-loader 用于将less转换成css
module.exports = {
module: {
rules: [
{
test: /\.less$/,
use: [
'style-loader',
'css-loader',
'less-loader'
]
}
]
}
}
npm i less less-loader -D
解析图片和字体
file-loader 用于处理文件
module.exports = {
module: {
rules: [
{
test: /\.(png|svg|jpg|gif)$/, // 针对图片
test: /\.(woff|woff2|eot|ttf|otf)$/, // 针对字体
use: [
'file-loader'
]
}
]
}
}
引入字体方式:
@font-face {
font-family: 'SourceHanSerifSC-Heavy';
src: url('./images/SourceHanSerifSC-Heavy.otf');
}
npm i file-loader -D
url-loader 也可以处理图片和字体,可以设置较小资源自动base64
module.exports = {
module: {
rules: [
{
test: /\.(png|svg|jpg|gif)$/,
use: [{
loader: 'url-loader',
options: {
limit: 10240
}
}]
}
]
}
}
文件监听
在源代码发生变化时,自动重新构建出新的输出文件。
webpack开启监听模式有两种方式:
- 启动webpack命令时,带上 --watch 参数
- 在配置webpack.config.js 中设置 watch:true
package.json
{
...,
"nain": "index.js",
"scripts": {
"build": "webpack",
"watch": "webpack --watch"
}
}
唯一缺陷:每次需要手动刷新浏览器
原理:轮询判断文件的最后编辑时间是否变化,某个文件发生了变化,并不会立刻告诉监听者,而是先缓存起来,等aggregateTimeout
module.exports = {
// 默认false,也就是不开启
watch: true,
// 只有开启监听模式时,watchOptions才有意义
watchOptions: {
// 默认为空,不监听的文件或文件夹,支持正则匹配
ignored: /node_modules/,
// 监听到变化发生后会等300ms再去执行,默认300ms
aggregateTimeout: 300,
// 判断文件是否发生变化是通过不停询问系统指定文件有没有变化实现的,默认每秒问1000次
poll: 1000
}
}
webpack中热更新及原理分析
热更新:webpack-dev-server
- WDS 不刷新浏览器
- WDS 不输出文件,而是放在内存中
- 使用 HotModuleReplacementPlugin插件
package.json
{
...,
"scripts": {
"build": "wabpack",
"dev": "webpack-dev-server --open" // --open是每次构建完成后自动开启浏览器
}
}
module.exports = {
...,
plugins: [
new webpack.HotModuleReplacementPlugin()
],
devServer: {
contentBase: './dist',
hot: true
}
}
使用webpack-dev-middleware
- WDM 将webpack输出的文件传输给服务器,适用于灵活的定制场景
文件指纹 chunkhash、contenthash、hash
打包后输出的文件名的后缀,可以进行版本管理
- Hash:和整个项目的构建相关,只要项目文件有修改,整个项目构建的hash值就会更改
- Chunkhash:和webpack打包的chunk有关,不同的entry会生成不同的chunkhash值
- Contenthash:根据文件内容来定义hash,文件内容不变,则contenthash不变
(1)JS的文件指纹设置:设置 output 的 filename,使用 [chunkhash]
module.exports = {
...,
output: {
filename: '[name][chunkhash:8].js',
path: __dirname + '/dist'
}
}
(2)CSS的文件指纹设置:设置 MiniCssExtractPlugin 的 filename,使用 [contenthash]
module.exports = {
...,
plugins: [
new MiniCssExtractPlugin({
filename: '[name][contenthash:8].css'
});
]
}
npm i mini-css-extract-plugin -D
(3)图片的文件指纹设置:设置 file-loader 的 name,使用 [hash]
| 占位符名称 |
含义 |
|---|---|
| [ext] | 资源后缀名 |
| [name] | 文件名称 |
| [path] | 文件的相对路径 |
| [folder] | 文件所在的文件夹 |
| [contenthash] | 文件的内容hash,默认是md5生成 |
| [hash] | 文件内容的Hash,默认是md5生成 |
| [emoji] | 一个随机的指代文件内容的emoj |
module.exports = {
module: {
rules: [
{
test: /\.(png|svg|jpg|gif)$/,
use: [{
loader: 'file-loader',
options: {
name: 'img/[name][hash:8].[ext]'
}
}]
}
]
}
}
代码压缩
(1)JS文件的压缩
内置了 uglifyjs-webpack-plugin
(2)CSS文件的压缩
使用optimize-css-assets-webpack-plugin,同时使用css预处理器 cssnano
module.exports = {
...,
plugins: [
new OptimizeCSSAssetsPlugin({
assetNameRegExp: /\.css$/g/,
cssProcessor: require('cssnano')
})
]
}
npm i optimize-css-assets-webpack-plugin cssnano -D
(3)Html文件的压缩
修改html-webpack-plugin,设置压缩参数
module.exports = {
...,
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, 'src/search.html'),
filename: 'search.html',
chunks: ['search'],
inject: true, // 打包后的js css等会自动注入到html中来
minify: {
html5: true,
collapseWhitespace: true,
preserveLineBreaks: false,
minifyCSS: true,
minifyJS: true,
removeComments: false
}
})
]
}
本文介绍了webpack的基础知识,包括Entry、Output、Loaders、Plugins的配置。讲解了如何解析ES6、React JSX、CSS、Less、Sass和图片字体,以及文件监听和热更新。同时,阐述了文件指纹的作用和代码压缩的实现方法。

702

被折叠的 条评论
为什么被折叠?



