前端工程化WebPack5️⃣
前置知识: 此文章属于前端——框架进阶篇,需要实现掌握:HTML+CSS+JS三件套
、Node...
😀推荐分享一波个人Blog文档: JavaScript、前端工程\模块化、邂逅Node.JS的那一夜
什么是WebPack❓
Webpack是一个强大的静态模块打包工具🧰
主要用于现代JavaScript
应用程序,它从一个或多个入口点开始,构建一个依赖图,
然后将项目中所需的每个模块打包成一个或多个bundle,这些bundle是静态资源,用于展示你的内容;
静态模块: 指的是编写代码过程中,html
、css
、js
、图片、文件🖺
等固定内容的资源;
打包: 把静态模块内容,压缩,整合,转译等… 🧊前端工程化;
- WebPack支持多种模块标准语法
- 把
less/sass
转成css
代码 - 把
ES6+
降级成ES5
什么是WebPack❓
Webpack是一个强大的静态模块打包工具🧰
主要用于现代JavaScript
应用程序,它从一个或多个入口点开始,构建一个依赖图,
然后将项目中所需的每个模块打包成一个或多个bundle,这些bundle是静态资源,用于展示你的内容;
静态模块: 指的是编写代码过程中,html
、css
、js
、图片、文件🖺
等固定内容的资源;
打包: 把静态模块内容,压缩,整合,转译等… 🧊前端工程化;
- WebPack支持多种模块标准语法
- 把
less/sass
转成css
代码 - 把
ES6+
降级成ES5
为什么要使用WebPack❓
Webpack的需求主要是为了解决在传统Web开发中遇到的一些问题:
-
多文件问题: 在没有模块打包工具的时代,一个项目通常有很多
JavaScript
文件🗃️;你需要在HTML中通过多个
<script>
标签引入它们,这会导致大量的HTTP请求,增加页面加载时间⏲️Webpack允许你将这些文件打包成:一个或几个bundle,减少了请求的数量,提高了加载效率📈
-
新技术兼容支持: 现代
JavaScript
应用程序越来越倾向于使用:ES6+
、TypeScript
、🖽框架特有的语法
这些新技术并不是所有浏览器都原生支持的: Webpack可以将这些现代代码转换为浏览器能够理解的格式;
-
资源管理: Webpack还可以处理其他类型的资源,如图片、字体和样式表,它提供了loader和插件系统
让你可以灵活地处理这些资源,并将它们包含在打包结果中;
-
模块依赖: Webpack自动处理应用程序的依赖关系图;
传统的构建工具要求你手动声明所有依赖,而Webpack会基于你的代码中的引用和导出来推断这些依赖;
-
性能优化: Webpack关注性能加载时间,提供代码分割、懒加载等功能,优化最终的bundle大小,提升应用性能;
Webpack是前端开发中非常重要的工具,特别是在处理大型复杂的JavaScript应用程序时
帮助开发者组织和优化他们的代码和资源,使得应用程序加载更快,运行更高效;
WebPack初体验:
准备工作:
Webpack是一个现代JavaScript
应用程序的静态模块打包工具: 也就是说,它本质是对一个已存在项目Project
进行工程化+打包的工具,本质属于一个NPM工具
,并对完整项目进行依赖管理;所以我们需要一个小Demo:
-
新建项目文件夹 Webpack_Project:
npm init -y
初始化包环境,得到 package.json 文件; -
新建 src 源代码文件夹: utils/check.js 封装用户名和密码长度函数、引入到 src/index.js 进行使用;
src/utils/check.js
封装并暴漏校验手机号长度和校验验证码长度的函数//封装并暴漏校验手机号长度和校验验证码长度的函数 export const checkPhone = phone => phone.length === 11 export const checkCode = code => code.length === 6
src/index.js
引入并使用 /utils/checkJS文件暴漏函数/**体验 webpack 打包过程 * indexJS中引入并使用 /utils/checkJS文件暴漏函数 */ import { checkPhone, checkCode } from '../utils/check.js' console.log(checkPhone('13900002020')) console.log(checkCode('123123123123'))
WebPack打包管理:
下载 webpack webpack-cli 到项目中,为了方便管理,不同项目版本,所以独立安装webPack⬇️
npm i webpack webpack-cli --save-dev
#webpack是NPM全局软件包:是命令工具,为了保证项目之间版本分别独立,通常安装在项目dev模块中;
#下载到项目环境下,并把webpack命令配置到 package.json的scripts自定义命令;
- 解释:
package.json
的scripts
属性,支持自定义命令方便开发者指向:"scripts": { "build": "webpack" },
项目中运行工具命令: WebPack自动产生 dist 文件夹: 压缩和优化后,最终运行的代码)
WebPack打包disc文件夹:
在使用Webpack进行打包时,通常会将打包后的文件输出到一个名为dist
的文件夹中:
通过观察发现,上述的WebPack_Project项目被翻译为:
main.JS
(()=>{"use strict";console.log(!0),console.log(!1)})();
- WebPack 通过一些配置生成,发现
WebPack_Projetc
最终的结果就是返回输出:true,false
- 于是在
disc文件夹——main.JS
中,直接将运行结果进行输出,大大节省了进一步函数运算、引用的消耗;
🆗,经过上述案例,大致了解到了WebPack基本使用,它就是对项目工程进行打包翻译使其更加简洁高效的进行部署运维
注意:Webpack 默认入口和出口分别为: src/index.js
、dist/main.js
但WebPack支持通过配置进行管理出入口等功能;
修改WebPack打包出入口:
要修改Webpack的打包出入口: 需要编辑webpack.config.js
文件;
这个文件是Webpack的配置文件,它告诉Webpack如何执行任务,设置入口文件、出口文件等配置;
根目录新建 webpack.config.js
配置文件📄:设置入口和出口: 更多配置请关注 WebPack 中文文档🔗
//为方便管理引入Node 文件资源管理模块;
const path = require('path');
//WebPack配置:
module.exports = {
entry: path.resolve(__dirname, 'src/index.js'),
output: {
clean: true, //打包之前清空输出目录webpack5.0版本新增;
path: path.resolve(__dirname, 'dist'), //resolve nodeJS中拼接路径的一个函数;
filename: './login/index.js' //__dirname 执行文件所在的绝对路径;
}
}
entry
属性定义了Webpack打包的入口文件路径;output
对象定义了打包后的输出路径path
和文件名filename
;
WebPack 自动生成 html 文件
WebPack本身并没有直接处理HTML文件的能力: 它主要是一个JavaScript模块打包工具,
所以: 如果想要将项目中的HTML文件,内自动的引入打包后的JS
,还需要手动的进行修改;
🆗,上述我们发现原生 登录页面.html
中直接引入index.JS
- 因为:内部引用
util包JS文件
,部分浏览器支持ES6+语法,导致报错!! - 后通过WebPack将JS进行打包,登录页面重新引入
dist/login/index.JS
,如此操作完成JS导入
那么WabPack 打包工具可以直接一键打包HTML,并根据HTML中的<script>块
,自动配置管理JS文件吗?
插件 html-webpack-plugin
HtmlWebpackPlugin | webpack 中文文档
html-webpack-plugin
是一个用于生成 HTML 文件的 Webpack 插件,
它简化了为 Webpack 打包的文件创建 HTML 文件的过程,特别适用于那些文件名中包含哈希值的情况
这个插件会自动将打包后的 JavaScript 文件引入到生成的 HTML 文件中,从而确保你的 HTML 文件始终引用最新的打包结果
NPM安装插件:
下载 html-webpack-plugin 本地软件包到项目中: npm i html-webpack-plugin --save-dev
配置 webpack.config.js
//为方便管理引入Node 文件资源管理模块;
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
//WebPack配置:
module.exports = {
entry: path.resolve(__dirname, 'src/index.js'),
output: {
clean: true,
path: path.resolve(__dirname, 'dist'),
filename: './login/index.js'
},
plugins: [ //插件:给Webpack提供更多功能;
new HtmlWebpackPlugin({
template: path.resolve(__dirname,'public/login.html'), // 模板文件
filename: path.resolve(__dirname,'dist/login.html'), // 输出文件
})
]
}
Webpack-打包 css 代码
要使用Webpack打包CSS代码,你需要配置一些loader加载器:
Webpack 默认只识别 JS 和 JSON 文件内容,所以想要让 Webpack 识别更多不同内容,需要使用加载器;
需要的 2 个加载器来辅助 Webpack 才能打包 css 代码: 使用时候要注意加载器版本,和WebPack的版本一致;
-
加载器 css-loader:解析 css 代码
-
加载器 style-loader:把解析后的 css 代码插入到 DOM(style 标签之间)
加载器和插件的区别: Webpack中,插件plugins、加载器loaders 是两个非常重要的概念:
-
加载器 的主要作用是转换文件,在Webpack配置文件的
module.rules
中配置:它们可以将不同类型的文件如:CSS、图片、TypeScript等,转换为Webpack可以理解和处理的模块;
-
插件 的作用更为广泛,它们可以扩展Webpack的功能,并在Webpack的整个构建过程中执行各种任务
插件可以用于打包优化、资源管理、环境变量注入等,在Webpack配置文件的
plugins
数组中配置;
准备工作: 定义login
页面的 .css
样式;
加载器css-loader、style-loader
①:NPM 安装加载器: 使用时候要注意加载器版本,和WebPack的版本一致,NPM默认情况安装最新版本;
#下载 css-loader 和 style-loader 本地软件包
npm i css-loader style-loader --save-dev
②:因为:WebPack主要是针对,JS的操作,所以如果需要管理CSS,需要在对应.JS
中引入CSS
③:最后配置: webpack.config.js
-
注意:
use:[]
中的顺序不能随意修改:WebPack是按
use:[]
顺序加载:css-loader -> style-loader
顺序错了会导致,编译错误;
//... 省略部分配置;
module:{ //加载器:
rules: [ //规则列表:
{
test: /\.css$/i, //匹配所有的 .css 文件
use: ['style-loader', "css-loader"], //使用从后到前的加载器来解析 css 代码和插入到 DOM
}
],
}
优化-提取 css 代码
上述我们实现了,将CSS进行WebPack管理:
but,好像效果并不是很满意,CSS和JS代码深度耦合在一起,虽然部署不受影响,但还可以优化: 将CSS、JS文件拆分;
- CSS 文件可以被浏览器缓存,减少 JS 文件体积,且浏览器并行下载JS、CSS文件,提高网页加载效率;
mini-css-extract-plugin 插件
mini-css-extract-plugin
是一个用于将CSS代码从JavaScript中分离出来,并生成单独CSS文件的Webpack插件;
它的主要作用是优化和管理CSS文件,使得CSS代码可以被浏览器缓存,从而提高页面加载速度和性能
安装插件: npm i --save-dev mini-css-extract-plugin
注意版本问题;
注意: mini-css-extract-plugin
不能和 style-loader
同时使用;
配置 webpack.config.js
- ①:引入定义
require('mini-css-extract-plugin')
模块; - ②:在
Plugins:[ new MiniCssExtractPlugin(),]
中定义插件; - ③:在
module:{ rules:[ {},{} ] }
中设置定义加载器、插件配置;
//为方便管理引入Node 文件资源管理模块;
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
//WebPack配置:
module.exports = {
plugins: [ //插件: 给Webpack提供更多功能;
//... 省略部分代码
new MiniCssExtractPlugin(),
],
module:{ //加载器:
rules: [ //规则列表:
//... 省略部分代码
//优化-提取 css 代码
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
//mini-css-extract-plugin不能和style-loader同时使用
}
],
}
}
关于HTML页面如何确认CSS文件:
因为HTML中固定了JS的文件引用,JS中有导入CSS的引用,
所以插件根据JS确认,CSS属于某个HTML页面进行渲染<link/>
引入;
优化压缩CSS:
🆗,上述成功的分离了CSS和JS,但CSS的文件并没有压缩,所以还可以优化: 当然也还需要添加插件
css-minimizer-webpack-plugin
css-minimizer-webpack-plugin: 是一个用于优化和压缩CSS代码的Webpack插件:
- 优化和压缩CSS:使用
cssnano
来优化和压缩CSS代码,减少文件大小,提高加载速度 - 支持source maps:能够生成和处理source maps,帮助调试压缩后的CSS代码
- 并行处理:支持多进程并行处理,提升构建速度
- 缓存:支持缓存机制,进一步提高构建效率
NPM下载插件:
npm i css-minimizer-webpack-plugin --save-dev
配置 webpack.config.js
在webpack.config.js
文件中引入并配置css-minimizer-webpack-plugin
optimization
配置项:用于自定义和控制打包过程中的各种优化策略;minimize:
启用或禁用代码压缩、指定压缩代码的插件;
//为方便管理引入Node 文件资源管理模块;
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
//WebPack配置:
module.exports = {
//... 省略部分代码
optimization:{ //优化
minimizer: [ //最小化配置
`...`,
new CssMinimizerPlugin(), //使用CssMinimizerPlugin进行CSS压缩
//在webpack@5中,你可以使用 `...` 扩展现有的 minimizer即terser-webpack-plugin)
//将下一行取消注释保证js代码还能压缩)
]
}
}
打包Less代码:
为了方便CSS编写,现在很多前端都使用Less了:什么是Less:
- Less
Leaner Style Sheets
的缩写,是一种CSS预处理语言,它扩展了CSS的功能,使得样式表的编写更加灵活和强大 - Less引入了变量、嵌套、混合(mixins)、函数等特性,简化了CSS的编写和维护,
- 本人并非纯前端就不过多介绍了
那么如何使用WebPack管理Less文件呢? 需要配置一些loader和插件….
加载器 less-loader
less-loader 是一个Webpack加载器,用于将Less文件编译为CSS:
支持Less特性:支持Less的变量、嵌套、混合、函数等特性,配置选项:可以通过lessOptions
配置Less编译的选项;
#NPM安装依赖:
npm i less less-loader --save-dev
#less-loader 需要配合 css-loader和style-loader一起使用:
npm i css-loader style-loader --save-dev
#因为实际开发很多场景,需要将文件进行分离mini-css-extract-plugin
npm i --save-dev mini-css-extract-plugin #不能和style-loader一起使用;
npm i css-minimizer-webpack-plugin --save-dev #进一步优化压缩翻译后的css文件;
编写Less、并引入JS:
login.less: 给登录页面添加背景图片的CSS样式;
html {
body {
background: url('./assets/login-bg.png') no-repeat center/cover;
}
}
在JS文件中引入less文件: import '../public/login.less';
WebPack也就是依赖这个找到对应CSS、Less;
配置 webpack.config.js
//为方便管理引入Node 文件资源管理模块;
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
//WebPack配置:
module.exports = {
//... 省略部分代码
module:{ //加载器:
rules: [ //规则列表:
//优化-提取 css 代码
{
test: /\.css$/i, //匹配所有的 .css 文件
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
//打包Less代码
{
test: /\.less$/i, //匹配所有的 .less 文件
use: [MiniCssExtractPlugin.loader, "css-loader","less-loader"], //按顺序加载器转换匹配文件类型
}
],
},
}
Webpack-打包 图片
关于WebPack打包图片,上述案例,并没有配置:我们发现WebPack自动进行了管理:
因为:WebPack5 内置了资源模块的打包,无需下载额外 loader: 可以更简单地处理图片等资源文件;
配置 webpack.config.js
//为方便管理引入Node 文件资源管理模块;
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
//WebPack配置:
module.exports = {
//... 省略部分代码
module:{ //加载器:
rules: [ //规则列表:
//优化-提取 css 代码
{
test: /\.css$/i, //匹配所有的 .css 文件
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
//打包Less代码
{
test: /\.less$/i, //匹配所有的 .less 文件
use: [MiniCssExtractPlugin.loader, "css-loader","less-loader"], //按顺序加载器转换匹配文件类型
}
//打包图片
{
type: 'asset', //资源模块类型(固定)
test: /\.(png|jpg|jpeg|gif)$/i, //匹配全类型图片文件
generator: {
filename: 'assets/[hash][ext][query]' //输出文件名及路径
}
}
],
},
}
资源模块类型:
资源模块类型Asset Module Type
是 webpack 5 引入的一种新特性
用于处理资源文件如图片
、字体
等,而无需额外配置 loader,它通过添加四种新的模块类型,替代了传统的 loader
-
asset/resource:将资源打包成一个单独的文件并导出该文件的 URL,之前通过使用 file-loader 实现
-
asset/inline:将资源打包成 data URI
base64
,之前通过使用 url-loader 实现 -
asset/source:导出资源的源代码,之前通过使用 raw-loader 实现
-
asset:可以根据资源大小自动选择将资源打包成:建议使用
判断临界值默认为 8KB:
>8转存图片地址
、<8将图片转换base64至JS中转储
单独的文件、还是data URI: 之前通过使用 url-loader,并通过配置限制资源体积实现;
输出文件名及路径(占位符): filename: 'assets/[hash][ext][query]'
表示输出在:assets目录下
/[...][...][...]
,占位符: 表示扩展额外的图片处理操作,操作可选,不同参数含义不同;
-
[hash]
使用文件内容的哈希值生成唯一的文件名,防止缓存问题;:多个相同图片名称不同,哈希之后成为一个图片节省磁盘空间;
:多个相同文件名,哈希之后避免重名冲突渲染问题;
-
[ext]
保留文件的原始扩展名,如:.png
、.jpg
、...
-
[query]
保留文件的查询参数,对于对象存储OSS服务器
可以通过参数进行图片的渲染;
WebPack4对于图片处理,还需安装插件、加载器,因为已经不经常使用就不介绍了/