webpack是什么:
webpack是一种前端资源构建工具,一个静态模块打包器
在webpack看来,前端的所有资源文件(js/json/img/less…)都会作为模块处理
它将根据模块的依赖关系进行静态分析,打包生成对应的静态资源
webpack五个核心概念:
1.Entry
入口(Entry)指示webpack以哪个文件为入口起点开始打包,分析构建内部依赖图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l2Uf59vE-1617326248838)(D:\webpack笔记\1.PNG)]
2.output
输出指示webpack打包之后的资源bundles输出到哪里去,以及如何命名
3.Loader
Loader让webpack能够去处理那些非JavaScript文件,css/img文件webpack看不清,loader负责去处理这些文件
4.Plugins
插件(Plugins)可以用于执行范围更广的任务,插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量等等
5.Mode
(1)development----------开发模式:能让代码在本地进行调试,配置简单
启动插件:NamedChunkPlugin和NamedModulesPlugin
(2)production----------生产模式:能让代码优化上线运行的环境,要考虑各种优化措施还有兼容,配置复杂
启动插件:FlagDependencyUsagePlugin,FlagIncludedChunksPlugin,ModuleConcatenationPlugin,NoEmitOnErrorsPlugin,OccurrenceOrderPlugin,SideEffectsFlagPlugin和UglifyJsPlugin
webpack基本安装过程:
(1)npm init----------全局初始化
(2)一直按enter键
(3)全局安装:
npm i webpack webpack-cli -g
(4)本地安装
npm i webpack webpack-cli -D
打包样式资源:
各个插件的版本控制:
{
"name": "webpack_test",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"@babel/core": "^7.13.10",
"@babel/polyfill": "^7.12.1",
"@babel/preset-env": "^7.13.10",
"babel-loader": "^8.2.2",
"core.js": "^0.4.2",
"css-loader": "^5.1.2",
"eslint": "^7.22.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-loader": "^4.0.2",
"eslint-plugin-import": "^2.22.1",
"file-loader": "^6.2.0",
"html-loader": "^2.1.2",
"html-webpack-plugin": "^5.3.1",
"less": "^4.1.1",
"less-loader": "^8.0.0",
"mini-css-extract-plugin": "^1.3.9",
"optimize-css-assets-webpack-plugin": "^5.0.4",
"postcss-loader": "^5.2.0",
"postcss-preset-env": "^6.7.0",
"style-loader": "^2.0.0",
"url-loader": "^4.1.1",
"webpack": "^5.19.0",
"webpack-cli": "^4.5.0"
},
"devDependencies": {
"@webpack-cli/serve": "^1.3.0",
"webpack-dev-server": "^3.11.2"
},
"browserslist": {
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
"production": [
">0.2%",
"not dead",
"not op_mini all"
]
},
"eslintConfig": {
"extends": "airbnb-base"
},
"sideEffects":["*.css"]
}
一定要注意webpack.config.js文件所放置的位置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-astiwT8Y-1617326304394)(D:\webpack笔记\捕获.PNG)]
需要安装的包:css-loader,
1.在src目录下创建名称为webpack.config.js的文件名称
3.安装下载webpack,webpack-cli
演示的文件夹之前执行过一次npm i webpack webpack-cli -g
npm i webpack webpack-cli -D
6.如何查看效果
在打包好的build文件夹下新建一个inxex.html文件,然后右键浏览器打开文件就可以了
7.打包less、css文件
npm i css-loader style-loader less-loader -D
在index.js文件中
import 'style-loader!css-loader!less-loader!./index.less'
如果上述写法报错的话,按照下述写法
import './index.less'
打包html资源:
npm i html-webpack-plugin -D
打包图片资源(背景图片)
npm i url-loader file-loader
打包HTML中的图片资源
npm i html-loader
打包其他资源(字体图标)不需要做优化,不需要压缩的资源
通过file-loader处理
开发服务器derServer:用来实现自动化(自动编译,自动打开浏览器,自动刷新浏览器)
下载包
npm i webpack-dev-server
热更新启动命令:
npx webpack serve
打包命令
npx webpack
代码示例:
// 这个文件是webpack的配置文件
// 作用:指示webpack干活,干那些活(当你运行webpack指令的时候,会加载其中的配置
// module.exports暴露一个对象
// resolve用来拼接绝对路径的方法
const {resolve} = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { Template } = require('webpack')
var webpack = require('webpack')
module.exports = {
// webpack配置
// 入口起点,指示webpack以哪个文件为起点
entry:'./src/index.js',
// 输出:打包好之后输出到哪里
output:{
// 输出文件名
filename:'built.js',
// 输出的路径
// __dirname是node.js的一个变量代表当前文件的目录的绝对路径
// webpack.config.js的绝对路径是03.打包样式资源,下述代码的意思就是03.打包样式资源文件夹下面的build文件夹
// 目的是防止各系统的文件符号不出问题
path:resolve(__dirname,'build')
},
// module里边写的就是loader的配置
module:{
rules:[
// loader的详细配置
{
// test是正则表达式,用来进行匹配哪些文件
// 一旦检测到css文件,通过use里边规定好的插件去处理
test:/\.css$/,
use:[
// 执行顺序:先执行'css-loader',再执行'style-loader'
// 创建style标签,将js中的样式资源插入进行,添加到head中生效
'style-loader',
// 将css文件以字符串的形式变成一个commonjs模块,加载到js中,里面内容是样式字符串
'css-loader'
]
},
{
test:/\.less$/,
use:[
'style-loader',
'css-loader',
// 将less文件编译成css文件
'less-loader'
]
},
{
test:/\.(jpg|png|gif)$/,
loader:'url-loader',
options:{
limit:8*1024
}
},
{
test:/\.html$/,
loader:'html-loader',
options:{
esModule:false
}
},
{
exclude:/\.(css|js|less|html)$/,
loader:'file-loader'
}
]
},
plugins: [
new HtmlWebpackPlugin({
// 作用就是复制'./src/index.html'文件,并自动引入打包输出的所有资源
template:'./src/index.html'
}),
new webpack.LoaderOptionsPlugin({
// test: /\.xxx$/, // may apply this only for some modules
options: {
derServer: {
contentBase:resolve(__dirname,'build'),
//启动代码压缩
conpress:true,
//端口号是3000
port:3000,
//自动打开浏览器
open:true
}
}
})
],
// 模式
mode:'development'
}
生产环境的配置:
(1)提取css成单独文件:src目录下的所有css文件都会被打包到main.css中,减少打包js文件的体积,以link标签的方式插入html文件中,防止闪屏
npm i mini-css-extract-plugin
要将webpack.config.js中的style-loader给注释掉
(2)css兼容处理–使用库postcss,依赖postcss-loader,postcss-preset-env(帮助识别环境,能够让浏览器兼容到每个版本)
npm i postcss-loader postcss-preset-env
在package.json中要加上以下代码:
意思是开发环境该怎么兼容,生产环境该怎么兼容:postcss如果你不指明的话,它默认的就是生产环境,想要在开发环境中使用,需要在webpack.config.js中加上代码process.env.NODE_ENV = ‘development’
"browserslist": {
"development":[
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
"production":[
">0.2%",
"not dead",
"not op_mini all"
]
}
(3)压缩css:请求速度快,加载速度快,代码上线之前一定要压缩
npm i optimize-css-assets-webpack-plugin
(4)js语法检查eslint,只检查用户自己写的代码,第三方库不检查
设置检查规则,在package.json中eslintConfig中设置
"eslintConfig": {
"extends": "airbnb-base"
}
安装包:
npm i eslint-loader eslint eslint-config-airbnb-base eslint-plugin-import
(5)js兼容性处理:babel-loader
1.这三个包只能解决一些基本的兼容问题
npm i babel-loader @babel/preset-env @babel/core
2.全部js兼容处理:这个库将js所有有关兼容性的问题全部纳入了进来
问题:我只要解决部分兼容性问题,但是将所有兼容的代码都给引进来了
npm i @babel/polyfill
还需要在index.js中引入
import '@babel/polyfill'
3.按需加载----core.js,与方法2是冲突的,将方法2中index.js中的代码给注释掉
npm i core.js
(6)压缩js:生产环境下会自动压缩js
(7)压缩html:在new HtmlWebpackPlugin插件里边加上两句代码即可
具体代码:
// 这个文件是webpack的配置文件
// 作用:指示webpack干活,干那些活(当你运行webpack指令的时候,会加载其中的配置
// module.exports暴露一个对象
// resolve用来拼接绝对路径的方法
const {resolve} = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { Template } = require('webpack')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
var webpack = require('webpack')
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
process.env.NODE_ENV = 'development'
module.exports = {
// webpack配置
// 入口起点,指示webpack以哪个文件为起点
entry:['./src/index.js','./src/index.html'],
// 输出:打包好之后输出到哪里
output:{
// 输出文件名
filename:'built.[chunkhash:10].js',
// 输出的路径
// __dirname是node.js的一个变量代表当前文件的目录的绝对路径
// webpack.config.js的绝对路径是03.打包样式资源,下述代码的意思就是03.打包样式资源文件夹下面的build文件夹
// 目的是防止各系统的文件符号不出问题
path:resolve(__dirname,'build')
},
// module里边写的就是loader的配置
module:{
rules:[
// loader的详细配置
{
// test是正则表达式,用来进行匹配哪些文件
// 一旦检测到css文件,通过use里边规定好的插件去处理
test:/\.css$/,
use:[
// 执行顺序:先执行'css-loader',再执行'style-loader'
// 创建style标签,将js中的样式资源插入进行,添加到head中生效
// 'style-loader',
MiniCssExtractPlugin.loader,
// 将css文件以字符串的形式变成一个commonjs模块,加载到js中,里面内容是样式字符串
'css-loader',
// "browserslist": {
// "development":[
// "last 1 chrome version",
// "last 1 firefox version",
// "last 1 safari version"
// ],
// "production":[
// ">0.2%",
// "not dead",
// "not op_mini all"
// ]
// },
{
loader:'postcss-loader',
ident:'postcss',
options:{
postcssOptions:{
plugins:[
require('postcss-preset-env')()
]
}
}
}
]
},
{
test:/\.less$/,
use:[
// 创建style标签,将样式放进去
// 'style-loader',
MiniCssExtractPlugin.loader,
// 将css文件整合到js文件
'css-loader',
// 将less文件编译成css文件
'less-loader',
{
loader:'postcss-loader',
options:{
ident:'postcss',
postcssOptions:{
plugins:[
require('postcss-preset-env')()
]
}
}
}
]
},
{
test:/\.(jpg|png|gif)$/,
loader:'url-loader',
options:{
limit:8*1024
}
},
{
test:/\.html$/,
loader:'html-loader',
options:{
esModule:false
}
},
{
exclude:/\.(css|js|less|html)$/,
loader:'file-loader'
},
{
// 设置检查规则,在package.json中eslintConfig中设置
test:/\.js$/,
// 不检查第三方库
exclude:/node_modules/,
loader:'eslint-loader',
options:{
// 帮我们自动修改错误
fix:true
}
},
{
test:/\.js/,
exclude:/node_modules/,
loader:'babel-loader',
options:{
// 指示babel做怎样的兼容处理
// 非常基本的兼容处理
presets:[
[
'@babel/preset-env',
{
useBuiltIns:'usage',
corejs:{
version:3
},
// 通过targets制定兼容做到哪个版本
targets:{
chrome:'60',
firefox:'60',
ie:'9',
safari:'10',
edge:'17'
}
}
]
],
cacheDirectory:true
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
// 作用就是复制'./src/index.html'文件,并自动引入打包输出的所有资源
template:'./src/index.html',
minify:{
// 移除空格
collapseWhitespace:true,
// 移除注释
removeComments:true
}
}),
new webpack.LoaderOptionsPlugin({
// test: /\.xxx$/, // may apply this only for some modules
options: {
derServer: {
contentBase:resolve(__dirname,'build'),
conpress:true,
port:3000,
// 开启HMR
hot:true
}
}
}),
new MiniCssExtractPlugin({
filename:'css/built.[chunkhash:10].css'
}),
new OptimizeCssAssetsWebpackPlugin()
],
// plugins数组里边写上详细的插件配置
// plugins:[
// // 插件的功能是默认会创建一个空的html文件,自动引入打包输出所有的资源(JS/CSS)
// // 问题:需要有结构的html文件
// new HtmlWebpackPlugin({
// // 作用就是复制'./src/index.html'文件,并自动引入打包输出的所有资源
// template:'./src/index.html'
// })
// ],
// 模式
mode:'development',
// derServer:{
// contentBase:resolve(__dirname,'build'),
// conpress:true,
// port:3000
// }
devtool:'inline-source-map'
}
webpack性能优化介绍:
1.开发环境性能优化
实际问题,你的代码发生一点点的变化,捎带着把那些没有变化的代码都进行打包了
(1)优化打包建构速度
生产环境是不需要HMR的,HMR是针对的开发环境
HMR功能:hot module replacement热模块替换。作用:一个模块发生变化,只会打包这一个模块(而不是打包所有模块)
derServer中新增一个属性:
以下是用来处理css热更新:
hot:true
以下是用来处理html热更新:
entry:['./src/index.js','./src/index.html'],
(2)针对开发环境:优化代码调试----------source-map:提供一种源代码到构建代码的映射技术(如果构建代码出错了,通过映射关系追踪源代码错误,在webpack.config.js中添加以下代码
devtool:'source-map'
属性:
【1】inline-source-map:内联,和打包js文件放在一块
错误代码准确信息和源代码的错误位置
【2】hidden-source-map:外部
【3】eval-source-map:内部
【4】cheap-source-map:外部
【5】nosources-source-map:外部
【6】cheap-module-source-map:外部
【7】source-map:外部
(推荐使用eval-cheap-souce-map)
2.生产环境性能优化
(1)优化打包建构速度
缓存
1.babel缓存:直接配置就好了
cacheDirectory:true
{
test:/\.js/,
exclude:/node_modules/,
loader:'babel-loader',
options:{
// 指示babel做怎样的兼容处理
// 非常基本的兼容处理
presets:[
[
'@babel/preset-env',
{
useBuiltIns:'usage',
corejs:{
version:3
},
// 通过targets制定兼容做到哪个版本
targets:{
chrome:'60',
firefox:'60',
ie:'9',
safari:'10',
edge:'17'
}
}
]
],
cacheDirectory:true
}
}
2.文件资源缓存
给打包的css和js文件添加chunkhash值
hash:
chunkhash:
contenthash:根据文件的内容生成hash值,不同文件hash值一定不一样
tree shaking:忽略代码中没有被使用的代码,让代码的体积更小
使用的前提条件:
1.必须使用ES6模块化
2.开启production环境
在package.json配置,标记哪些问价不需要被tree shaking
"sideEffects":["*.css"]
code split:代码分割,非常重要的,主要研究的是js代码,在生产环境production中使用
比如你有两个js文件,webpack默认会将文件打包成一个js文件,针对的是多入口
方式1:以下代码的作用:放在plugins之后
1.对于单页面应用,可以将node_modules中代码单独打包一个chunk最终输出,
optimization:{
splitChunks:{
chunks:'all'
}
}
懒加载:针对的是js,不是图片的懒加载(跳过)
PWA:渐进式网络开发应用程序,因为兼容性问题,一般 大厂在使用,即使没有网络,也可以访问网站(跳过)
多进程打包:优化打包速度,和babel-loader放在一块
缺点:这个多进程打包启动时间需要600ms
npm i thread-loader
{
test:/\.js/,
exclude:/node_modules/,
use:[
'thread-loader',
{
loader:'babel-loader',
options:{
// 指示babel做怎样的兼容处理
// 非常基本的兼容处理
presets:[
[
'@babel/preset-env',
{
useBuiltIns:'usage',
corejs:{
version:3
},
// 通过targets制定兼容做到哪个版本
targets:{
chrome:'60',
firefox:'60',
ie:'9',
safari:'10',
edge:'17'
}
}
]
],
cacheDirectory:true
}
}
],
}
externals:防止将某些包作用输出到我们的bundle中,比如 在使用jquery的CDN链接,这个时候可以通过externals将其禁止打包
比如你想使用jquery,用的cdn链接,放在了index.html中,可以这样配置:
externals;{
//库名----npm的包名
jquery:'jQuery'
}