一、webpack是什么
核心概念
webpack是一种前端资源构建工具,一个静态模块打包器。
在webpack看来,前端所有资源文件(js/json/css/img/less)等都会作为模块处理
他根据模块依赖关系进行静态分析,打包生成对应静态资源
webpack 五个核心概念
- Entry
入口指示,webpack以哪个文件为入口起点进行开始打包,分析构建依赖关系图
- Output
输出指示,webpack打包后资源输出到哪里去,以及怎么命名
- Loader
在module文件下,让webpack能够去处理那些非js文件(webpack自身只理解js文件),主要是翻译作用,比如css和img
- Plugins
插件可以用于执行范围更广得任务,插件范围包括,从打包和压缩,一直到重新定义环境中得变量等
- Mode
模式指示webpack使用相应模式得配置
开发环境打包不会压缩代码,生产环境会压缩
**注意:**webpack只能处理js/json,不能处理css/img等其他资源
二、webpack配置开发环境
配置文件
webpack.config.js 是webpack配置文件
作用:指示webpack 干哪些活(当你运行 webpack 指令时,会加载那些配置)
所有构建工具都是基于node.js平台运行的~模块化默认采用commonjs.
Loader配置
- 把less文件转为css文件并且压缩
const {resolve} = require('path') //绝对路径写法
module.exports ={
entry:'./src/index.js', //入口
output:{
filename:'build.js', //输出文件名
// __dirname nodejs的变量,代表当前文件绝对路径
path:resolve(__dirname,'build') //输出到当前目录build目录下
},
module:{
rules:[
// 详细的loader配置,不同文件配置不同loader
{
test:/\.css$/, //匹配那些文件
use:[ //使用哪些loader进行处理,use数组中顺序:从右到左,从上到下依次执行
'style-loader', //创建style标签,将js中的样式资源插入进行,添加到head中生效
'css-loader' //将css文件变成commonjs模块加载js中,里面内容是样式字符串
]
},
{
test:/\.less$/,
use:[
'style-loader',
'css-loader',
'less-loader' //将less文件编译成css文件,需要下载less-loader和less
]
}
]
},
plugins:[ //详细的plugins配置
],
mode:'development', //开发环境
}
-
压缩图片
下载
url-loader file-loader html-loader
...
module:{
rules:[
{
test:/\.(jpg|png|gif)$/, // 处理图片资源
loader:'url-loader', // 使用一个loader可以用loader多个用use数组
options:{
limit:9*1024, // 图片大小小于9kb,就会被base64处理
esModule:false,
nmae:'[hash:10].[ext]', //[hash:10]取hash的前10位,[ext]取原先扩展名
outputPath:'imgs' // 把所有打包图片放到imgs文件夹
},
// v5 版本已经废弃url-loader方法需要添加type: 'javascript/auto',才可以使用
type: 'javascript/auto',
},
{
test:/\.html$/,
loader:'html-loader' //处理html文件的img图片(负责引入img,从而被url-loader处理)
}
],
},
...
-
打包其他资源
下载
file-loader
{
exclude:/\.(css|js|html|less|jpg|png|gif)$/, //排除css|js|html|less|jpg|png|gif资源,不然会报错,打包其他的资源
loader:'file-loader',
options:{
name:'[hash:10].[ext]', //[hash:10]取hash的前10位,[ext]取原先扩展名
outputPath:'media' //把所有其他打包文件放到media文件夹
},
}
plugins配置
下载 ==》引入 ==> 使用
- 打包html文件,html-webpack-plugin插件
功能:会默认创建一个空的html,自动引入打包的所有资源(css,js)
需求:需要有结构的html文件
const HtmlWebpackPlugin = require('html-webpack-plugin') //引入
...
plugins:[ //详细的plugins配置
new HtmlWebpackPlugin({
template:'./src/2.html' //复制'./src/2.html'文件,并自动引入打包输出的所有资源(css,js),原文件如果引入,就引了2次,注意
})
],
...
开发服务器 devServer
开发服务器用来自动化(自动编译,自动打开浏览器,自动刷新浏览器)
特点:只会在内存中编译打包,不会有任何输出,所以压缩的文件我们看不到,只会出现在内存中
启动 devserver 指令:npx webpack server
module.exports ={
entry:'./src/index.js', //入口
output:{
filename:'build.js', //输出文件名
// __dirname nodejs的变量,代表当前文件绝对路径
path:resolve(__dirname,'build') //输出到当前目录build目录下
},
module:{
rules:[
...
],
},
plugins:[ //详细的plugins配置
...
],
mode:'development', //开发环境
devServer:{
static:resolve(__dirname,'build'), //项目构建后路径,__dirname nodejs的变量,代表当前文件绝对路径
compress:true, //启动gzip压缩
port:8080, //端口号3000
open:true, // 自动打开浏览器
}
}
三、webpack配置生产环境
css配置
- 提取css为单独文件
安装 mini-css-extract-plugin
插件
const miniCssExtractPlugin = require('mini-css-extract-plugin') //导入
...
rules:[
// 详细的loader配置,不同文件配置不同loader
{
test:/\.css$/, //匹配那些文件
use:[ //使用哪些loader进行处理,use数组中顺序:从右到左,从上到下依次执行
// 'style-loader', //创建style标签,将js中的样式资源插入进行,添加到head中生效
miniCssExtractPlugin.loader, //取代style-loader,提取css生产单独文件
'css-loader' //将css文件变成commonjs模块加载js中,里面内容是样式字符串
]
},
],
...
plugins:[ //详细的plugins配置
new miniCssExtractPlugin({
filename:'css/built.css' //输出到指定目录下
})
],
-
css兼容性处理
下载
postcss-loader postcss-preset-env
process.env.NODE_ENV='development' //兼容默认生产环境,在当前文件目录配置,node环境变量,可以变为开发环境
...
rules:[
// 详细的loader配置,不同文件配置不同loader
{
test:/\.css$/, //匹配那些文件
use:[ //使用哪些loader进行处理,use数组中顺序:从右到左,从上到下依次执行
// 'style-loader', //创建style标签,将js中的样式资源插入进行,添加到head中生效
miniCssExtractPlugin.loader, //取代style-loader,提取css生产单独文件
'css-loader', //将css文件变成commonjs模块加载js中,里面内容是样式字符串
{
loader:'postcss-loader', //postcss-preset-env帮助postcss-loader找postcss.json中的browserslist里面配置,通过配置找到指定css兼容样式
options:{
postcssOptions:{
plugins:[['postcss-preset-env',{}]] //postcss-loader插件
}
}
}
]
},
{
test:/\.less$/,
use:[ //使用哪些loader进行处理,use数组中顺序:从右到左,从上到下依次执行
// 'style-loader', //创建style标签,将js中的样式资源插入进行,添加到head中生效
miniCssExtractPlugin.loader, //取代style-loader,提取css生产单独文件
'css-loader', //将css文件变成commonjs模块加载js中,里面内容是样式字符串
{
loader:'postcss-loader', //postcss-preset-env帮助postcss-loader找postcss.json中的browserslist里面配置,通过配置找到指定css兼容样式
options:{
postcssOptions:{
plugins:[['postcss-preset-env',{}]] //postcss-loader插件
}
}
}
]
},
...
//在package.json文件配置兼容的浏览器
...
"webpack": "^5.69.1",
"webpack-cli": "^4.9.2"
},
"browserslist":{
"development":[ //开发环境
"last 1 chrome version", //兼容谷歌浏览器最近版本,下面3个同理
"last 1 firefox version",
"last 1 safari version"
],
"production":[ //生产环境
">0.02%", //兼容百分98浏览器
"not dead", //出去丢弃的ie10浏览器
"not op_mini all" //出去不在使用的op浏览器
]
}
...
- 压缩css
下载插件css-minimizer-webpack-plugin
const cssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin') //导入
plugins:[ //详细的plugins配置
new cssMinimizerWebpackPlugin() //压缩插件使用
],
js位置
- 语法检查eslint
下载eslint-loader
eslint
检查基本配置
下载eslint-config-airbnb-base
eslint-plugin-import
检查的规范,可以自己选择
...
rules: [
{
test:/\.js$/,
exclude:/node_modules/, //不检查node_modules里面js文件
loader:'eslint-loader',
options:{
fix:true //自动格式化
}
},
...
// package.json 里配置
...
"webpack": "^5.69.1",
"webpack-cli": "^4.9.2"
},
"eslintConfig": {
"extends": "airbnb-base" // 配置eslink规则
}
}
- js兼容性处理
下载 babel-loader
@babel/core
@babel/preset-env
@babel/polyfill
rules: [
...
{
test:/\.js$/,
exclude:/node_modules/, //不检查node_modules里面js文件
use: [{
loader: 'eslint-loader',
options: {
fix:true, //自动格式化
}
},{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'] //只能把部门高级语法转为低级语法,兼容浏览器
}
}]
},
...
],
// 可以把剩下高级语法转为低级语法,兼容浏览器,在js入口文件文件导入,如main.js
import '@babel/polyfill';
压缩html与js
把环境变为生产环境自动压缩js和html,还得配置minify
plugins: [ // 详细的plugins配置
new HtmlWebpackPlugin({
template: './src/2.html', // 复制'./src/2.html'文件,并自动引入打包输出的所有资源(css,js)
minify:{ //压缩html配置项
collapseWhitespace:true, // 移除空格
removeComments:true // 移除注释
}
}),
],
mode: 'production', // 生产环境
devServer: {
static: resolve(__dirname, 'build'), // 项目构建后路径,__dirname nodejs的变量,代表当前文件绝对路径
...
四、webpack 性能优化
开发环境:优化打包构建速度;优化代码调试
生产环境:优化打包构建速度;优化代码运行性能
HMR:热模块替换
作用:一个模块发生变化,只会重新打包这一个模块(而不是打包所有模块),极大提升构建速度
样式文件:可以使用HMR功能:因为style-loader内部实现了
js文件:默认不能使用HMR功能–》需要修改js代码,添加支持HMR功能的代码
注意:HMR功能对js处理,只能处理非入口js文件其他文件
html文件:默认不能使用HMR功能,同时会导致问题:html文件不能热更新了(不用做HMR功能)
解决:修改entry入口,将html文件引入
entry: ['./src/index.js','./src/2.html'], // 入口,导致问题:html文件不能热更新了,将html文件引入
devServer: {
static: resolve(__dirname, 'build'), // 项目构建后路径,__dirname nodejs的变量,代表当前文件绝对路径
compress: true, // 启动gzip压缩
port: 8080, // 端口号3000
open: true, // 自动打开浏览器
//开启HMR功能//当修改了webpack配置,新配置要想生效,必须重新webpack服务
hot:true
},
source-map优化代码调试
作用:提供源代码到构建后代码映射技术(如构建后代码出错,通过映射关系可以追踪到源代码)
...
devServer: {
static: resolve(__dirname, 'build'), // 项目构建后路径,__dirname nodejs的变量,代表当前文件绝对路径
compress: true, // 启动gzip压缩
port: 8080, // 端口号3000
open: true, // 自动打开浏览器
//开启HMR功能//当修改了webpack配置,新配置要想生效,必须重新webpack服务
hot:true
},
devtool:'eval-source-map' // 优化代码调试配置
};
oneOf
以下loader只会匹配一个,注意:不能有两个配置处理同一种类型文件
module: {
rules: [
...
{
//以下loader只会匹配一个//注意:不能有两个配置处理同一种类型文件
oneOf:[
// 详细的loader配置,不同文件配置不同loader
{
test: /\.css$/, // 匹配那些文件
use: [...commonCssLoader],// 使用哪些loader进行处理,use数组中顺序:从右到左,从上到下依次执行
},
]
}
],
},
...
缓存优化
use: [{
loader: 'eslint-loader',
options: {
fix:true, //自动格式化
}
},{
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
],
],
cacheDirectory:true // 加在打包html和js的loader里面
},
}],
},
output: {
filename: 'build.[contenthash:10].js', // 输出文件名
// __dirname nodejs的变量,代表当前文件绝对路径
path: resolve(__dirname, 'build'), // 输出到当前目录build目录下
},
new miniCssExtractPlugin({
filename: 'css/built.[contenthash:10].css', // 输出到指定目录下
}),
通过哈希命名,使更改的文件才会更新,不会刷新缓存
tree shaking:去除无用代码
前提:1. 必须使用es6 模块化 2. 开始production 生产环境
作用:减少代码体积
在package.json中配置
“sideEffects”:false 所有代码都没有副作用(都可以进行tree shaking,把引入进来没用使用的都不会打包,比如css)
问题:可能会把css/@babel/polyfill (副作用)文件干掉
"sideEffects":["*.css","*.less"]
css和less结尾文件不进行tree shaking
code split 代码分割
entry:
{ // 多入口,每一组生成单独文件,单入口只生成一个文件
index:'./src/index.js',
test:'./src/index.less',
index:'./src/2.html'
},
// 入口
output: {
filename: '[name].[contenthash:10].js', // 输出文件名,[name]多入口属性名作为文件名
// __dirname nodejs的变量,代表当前文件绝对路径
path: resolve(__dirname, 'build'), // 输出到当前目录build目录下
},
...
plugins: [ // 详细的plugins配置
...
],
optimization:{ //可以将node_modeules中代码单独打包一个chunk最终输出,自动分析多入口chunk中,有没有公共依赖,有打包一个chunk
splitChunks:{
chunks:'all'
}
},
mode: 'production', // 开发环境
...
PWA渐进式网络开发应用程序
多进程打包
下载:thread-loader
进程启动大概为600ms,进程通信也有开销
只有工作消耗时间比较长,才需要多进程打包
externals拒绝打包
...
},
mode: 'production', // 开发环境
externals:{
jquery:'jQuery' //拒绝jquery被打包进来,但是要手动引入cdn
},
devServer: {
static: resolve(__dirname, 'build'), // 项目构建后路径,__dirname nodejs的变
...
dll技术
作用:对某些库(第三方库,jquery、react、vue。。。)进行单独打包,只用打包一次,下次不用打包
resolve解析模块
’
}
},
mode: ‘production’, // 开发环境
…
###### PWA渐进式网络开发应用程序
###### 多进程打包
下载:`thread-loader`
进程启动大概为600ms,进程通信也有开销
只有工作消耗时间比较长,才需要多进程打包
###### externals拒绝打包
```js
...
},
mode: 'production', // 开发环境
externals:{
jquery:'jQuery' //拒绝jquery被打包进来,但是要手动引入cdn
},
devServer: {
static: resolve(__dirname, 'build'), // 项目构建后路径,__dirname nodejs的变
...
dll技术
作用:对某些库(第三方库,jquery、react、vue。。。)进行单独打包,只用打包一次,下次不用打包
resolve解析模块
[外链图片转存中…(img-ETQhVbME-1645966040848)]