模块化(js模块化,css模块化,其他资源的模块化)
组件化(复用现有的UI结构,样式,行为)
规范化(目录结构的划分,编码规范化,接口规范化,文档规范化,git分支管理)
自动化(自动化构建,自动部署,自动化测试)
前端工程化指的是:在企业级的前端项目开发中,把前端开发所需的工具,技术,流程,经验等进行规范化、标准化。
一、node.js
1.是什么?
基于chrome的v8引擎封装,独立执行javascript代码的环境
2.与浏览器环境的js区别?
node环境没有bom和dom
3.有什么用?
编写后端程序,提供网页和资源
前端工程化,继承各种开发中使用的工具和技术
4.如何执行代码
在终端输入node xxx.js回车即可执行代码
前端工程化
开发项目直到上线,过程中继承的所有工具和技术
(格式化工具,压缩工具,转换工具,脚手架工具,打包工具)
二、使用webpack
1.webpack是什么
webpack是一个静态模块打包工具,将项目中所需的每一个模块组合一个或多个 bundles,它们均为静态资源,用于展示内容。
打包:把静态模块内容压缩、整合、转译等。把less/sass转为css代码,把es6+降级成es5,支持多种模块标准语法
提供了前端模块画开发的支持,以及代码压缩混淆,处理浏览器端js的兼容性,性能优化等强大的处理。提高了前端开发效率和项目的可维护性。
https://webpack.docschina.org/
webpackhttps://webpack.docschina.org/
2.步骤
1.新建并初始化项目,编写业务源代码(准备项目和源代码npm init -y)
2.下载webpack webpack-cli到目前项目中,并配置局部自定义命令(准备webpack打包环境)
npm i webpack webpick-cli --save-dev
{
"name": "webpack",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build":"webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"devDependencies": {
"webpack": "^5.96.1",
"webpack-cli": "^5.1.4"
}
}
3.运行打包命令,自动产生dist文件夹,压缩和优化后,用于最终运行的代码(运行自定义命令打包npm run build)
3.修改入口和出口(entry和output)
entry默认是./src/index.js
output出口默认在./dist/main.js
1.项目根目录,新建webpack.config.js配置文件
2.导出路由配置对象,配置出口,出口文件的路径
3.重新打包观察
const path = require('path')
module.exports = {
entry: path.resolve(__dirname, 'src/login/index.js'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: './login/index.js',
clean:true//生成打包内容之前,清空输出内容
}
}
4.案例:用户登录长度判断
需求:点击登录按钮,判断手机号和验证码长度
步骤:
1.准备用户登录页面
2.编写核心js逻辑代码
3.打包并手动复制网页到dist下,引入打包后的js,运行
src\login\index.js
import { checkPhone, checkCode } from '../utils/check'
document.querySelector('.login-btn').addEventListener('click', () => {
let username = document.getElementById('username').value;
let password = document.getElementById('password').value;
console.log('username',username,'password',password);
if (!checkPhone(username)) {
console.log('手机号码必须是11位');
return
}
if (!checkCode(password)) {
console.log('验证码必须是6位');
return
}
console.log('登录');
})
public\login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="login-container">
<h2>Login</h2>
<form id="loginForm">
<!-- 用户名输入框 -->
<input type="text" id="username" class="input-field" placeholder="Username" required>
<div id="username-error" class="error-message"></div>
<!-- 密码输入框 -->
<input type="password" id="password" class="input-field" placeholder="Password" required>
<div id="password-error" class="error-message"></div>
<!-- 登录按钮 -->
<button type="button" class="login-btn">Login</button>
</form>
<div class="footer">
<p>Don't have an account? <a href="#">Sign up</a></p>
</div>
</div>
</body>
</html>
npm run build打包,然后把login.html文件 复制到dist目录下,引入打包后的js
<script src="./login/index.js"></script>,打开浏览器,http://localhost:8080/dist/login.html
5.自动生成html文件(plugins)
插件html-webpack-plugin在webpack打包时生成html文件
npm install --save-dev html-webpack-plugin
步骤:
1.下载html-webpack-pligin本地包
2.配置webpack.config.js让webpack拥有插件功能
3.重新打包观察
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: path.resolve(__dirname, 'src/login/index.js'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: './login/index.js',
clean:true//生成打包内容之前,清空输出内容
},
plugins: [new HtmlWebpackPlugin({
filename: path.resolve(__dirname,'dist/login/index.html'),
template:path.resolve(__dirname,'public/login.html')
})],
}
6.webpack打包css代码
加载器css-loader解析css代码
加载器style-loader把解析后的css代码插入到dom
步骤:
1.准备css文件代码引入到src/login/index.js中
2.下载css-loader和style-loader本地软件包
npm install --save-dev css-loader style-loader
3.配置webpack.config.js让webpack拥有该加载器功能
4.重新打包观察
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: path.resolve(__dirname, 'src/login/index.js'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: './login/index.js',
clean:true//生成打包内容之前,清空输出内容
},
plugins: [new HtmlWebpackPlugin({
filename: path.resolve(__dirname,'dist/login/index.html'),
template:path.resolve(__dirname,'public/login.html')
})],
module: {
rules: [
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
},
],
},
}
import './index.css'
import 'bootstrap/dist/css/bootstrap.min.css'
import { checkPhone, checkCode } from '../utils/check'
document.querySelector('.login-btn').addEventListener('click', () => {
let username = document.getElementById('username').value;
let password = document.getElementById('password').value;
console.log('username',username,'password',password);
if (!checkPhone(username)) {
console.log('手机号码必须是11位');
return
}
if (!checkCode(password)) {
console.log('验证码必须是6位');
return
}
console.log('登录');
})
7.优化提取css代码
好处:css文件可以被浏览器缓存,减少js文件的体积
插件mini-css-extract-plugin
Do not use style-loader
and mini-css-extract-plugin
together.
步骤:
1.下载mini-css-extract-plugin本地软件包
2.配置webpack.config.js让webpack拥有该插件功能
3.重新打包观察
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: path.resolve(__dirname, 'src/login/index.js'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: './login/index.js',
clean:true//生成打包内容之前,清空输出内容
},
plugins: [
new HtmlWebpackPlugin({
filename: path.resolve(__dirname,'dist/login/index.html'),
template:path.resolve(__dirname,'public/login.html')
}),
new MiniCssExtractPlugin()//生成css插件
],
module: {
rules: [
{
test: /\.css$/i,
// use: ['style-loader', 'css-loader'],
use: [
MiniCssExtractPlugin.loader,
"css-loader"
],
},
],
},
}
8.优化提取css代码压缩
npm install css-minimizer-webpack-plugin --save-dev
步骤:
1.下载css-minimizer-webpack-plugin插件
2.配置webpack.config.js让webpack拥有该功能
3.重新打包观察
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = {
entry: path.resolve(__dirname, 'src/login/index.js'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: './login/index.js',
clean:true//生成打包内容之前,清空输出内容
},
plugins: [
new HtmlWebpackPlugin({
filename: path.resolve(__dirname,'dist/login/index.html'),
template:path.resolve(__dirname,'public/login.html')
}),
new MiniCssExtractPlugin()//生成css插件
],
module: {
rules: [
{
test: /\.css$/i,
// use: ['style-loader', 'css-loader'],
use: [
MiniCssExtractPlugin.loader,
"css-loader"
],
},
],
},
//压缩css代码
optimization: {
minimizer: [
// 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
`...`,
new CssMinimizerPlugin(),
],
},
}
8.打包less代码
加载器less-loader:把less代码编译为css代码
步骤:
1.新建less代码并引入src/login.index.js中
2.下载less和less-loader本地软件包
3.配置webpack.config.js让webpack拥有该功能
4.重新打包观察
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = {
entry: path.resolve(__dirname, 'src/login/index.js'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: './login/index.js',
clean:true//生成打包内容之前,清空输出内容
},
plugins: [
new HtmlWebpackPlugin({
filename: path.resolve(__dirname,'dist/login/index.html'),
template:path.resolve(__dirname,'public/login.html')
}),
new MiniCssExtractPlugin()//生成css插件
],
module: {
rules: [
//'style-loader'不能和MiniCssExtractPlugin.loader混用
{
test: /\.css$/i,
// use: ['style-loader', 'css-loader'],
use: [
MiniCssExtractPlugin.loader,
"css-loader"
],
},
{
test: /\.less$/i,
use: [
// compiles Less to CSS
MiniCssExtractPlugin.loader,
'css-loader',
'less-loader',
],
},
],
},
//压缩css代码
optimization: {
minimizer: [
// 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
`...`,
new CssMinimizerPlugin(),
],
},
}
9.打包图片
资源模块:webpack5内置资源模块(字体,图片等)打包,无需额外的loader
占位符【hash】对模块内容做算法计算,得到映射的数字字母组合的字符串
占位符【ext】使用当前模块原本的占位符,例如:.png /.jpg等字符串
步骤:
1.配置webpack.config.js让webpack拥有打包图片功能
2.重新打包观察
注意:判断临界值默认8kb,大于8kb,发送一个单独的文件并导出url地址,小于8kb,导出一个dataURL(BASE64字符串)
js中引入本地图片资源要用import方式,如果是网络图片http地址可以直接写字符串
import './index.css'
import './index.less'
import 'bootstrap/dist/css/bootstrap.min.css'
import { checkPhone, checkCode } from '../utils/check'
document.querySelector('.login-btn').addEventListener('click', () => {
let username = document.getElementById('username').value;
let password = document.getElementById('password').value;
console.log('username',username,'password',password);
if (!checkPhone(username)) {
console.log('手机号码必须是11位');
return
}
if (!checkCode(password)) {
console.log('验证码必须是6位');
return
}
console.log('登录');
})
import imgObj from './assets/OIP-C.jpg'
const theImg = document.createElement('img')
theImg.src = imgObj
document.querySelector('.login-container').appendChild(theImg)
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = {
entry: path.resolve(__dirname, 'src/login/index.js'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: './login/index.js',
clean:true//生成打包内容之前,清空输出内容
},
plugins: [
new HtmlWebpackPlugin({
filename: path.resolve(__dirname,'dist/login/index.html'),
template:path.resolve(__dirname,'public/login.html')
}),
new MiniCssExtractPlugin()//生成css插件
],
module: {
rules: [
//'style-loader'不能和MiniCssExtractPlugin.loader混用
{
test: /\.css$/i,
// use: ['style-loader', 'css-loader'],
use: [
MiniCssExtractPlugin.loader,
"css-loader"
],
},
{
test: /\.less$/i,
use: [
// compiles Less to CSS
MiniCssExtractPlugin.loader,
'css-loader',
'less-loader',
],
},
{
test: /\.(png|jpg|jpeg|gif)$/i,
type: 'asset',
generator: {
filename: 'assets/[hash][ext][query]'
}
}
],
},
//压缩css代码
optimization: {
minimizer: [
// 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
`...`,
new CssMinimizerPlugin(),
],
},
}
10.用户登录完成功能
1.使用npm下载axios
2.准备并修改utils工具包源代码导出实现函数
3.导入并编写逻辑代码,打包后运行观察效果
三、开发环境和生产环境
1.搭建开发环境
问题:之前改代码,需要重新打包 才能运行查看,效率很低
开发环境:配置webpack-dev-server快速开发应用程序
作用:启动web服务,自动监测代码变化,热更新到网页
注意:dist目录和打包内容在内存里(更新快)
步骤:
1.下载webpack-dev-server软件包到当前项目
2.设置模式为开发模式,并配置自定义命令
3.使用npm run dev来启动开发服务器,试试热更新效果
npm i webpack-dev-server --save-dev
注意:
1.webpack-dev-server借助http模块创建8080默认web服务
2.默认以public文件夹作为根目录(public/index.html)
3.webpack-dev-server根据配置,打包相关代码在内存中,以output.path的值作为服务器根目录,所以可以直接自己拼接访问dist目录下内容
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = {
//打包环境
mode: 'development',
//入口
entry: path.resolve(__dirname, 'src/login/index.js'),
//出口
output: {
path: path.resolve(__dirname, 'dist'),
filename: './login/index.js',
clean:true//生成打包内容之前,清空输出内容
},
//插件
plugins: [
new HtmlWebpackPlugin({
filename: path.resolve(__dirname,'dist/login/index.html'),
template:path.resolve(__dirname,'public/login.html')
}),
new MiniCssExtractPlugin()//生成css插件
],
module: {
rules: [
//'style-loader'不能和MiniCssExtractPlugin.loader混用
{
test: /\.css$/i,
// use: ['style-loader', 'css-loader'],
use: [
MiniCssExtractPlugin.loader,
"css-loader"
],
},
{
test: /\.less$/i,
use: [
// compiles Less to CSS
MiniCssExtractPlugin.loader,
'css-loader',
'less-loader',
],
},
{
test: /\.(png|jpg|jpeg|gif)$/i,
type: 'asset',
generator: {
filename: 'assets/[hash][ext][query]'
}
}
],
},
//压缩css代码
optimization: {
minimizer: [
// 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
`...`,
new CssMinimizerPlugin(),
],
},
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
location.href='/login/index.html'
</script>
</body>
</html>
2.打包模式
打包模式:告知webpack使用相应模式的内置优化
模式名称 | 模式名字 | 特点 | 场景 |
开发模式 | development | 调试代码,实时加载,模块热替换等 | 本地开发 |
生产模式 | production | 压缩代码,资源优化,更轻量等 | 打包上线 |
设置:
方式1:在webpack.config.js配置文件设置mode选项
方式2:在package.json命令行设置mode参数
注意:命令行设置的优先级高于配置文件中的,推荐使用命令行设置
{
"name": "webpack",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --mode=production",
"dev":"webpack serve --mode=development --open"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"devDependencies": {
"css-loader": "^7.1.2",
"css-minimizer-webpack-plugin": "^7.0.0",
"html-webpack-plugin": "^5.6.3",
"less": "^4.2.0",
"less-loader": "^12.2.0",
"mini-css-extract-plugin": "^2.9.2",
"style-loader": "^4.0.0",
"webpack": "^5.96.1",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^5.1.0"
},
"dependencies": {
"axios": "^1.7.7",
"bootstrap": "^5.3.3"
}
}
3.打包模式的应用
需求:在开发模式下用style-loader内嵌更快,在生产模式下提取css代码
方案1:webpack.config.js配置导出函数,但是局限性大
方案2:借助cross-env(跨平台通用)包命令。设置参数区分环境
方案3:配置不同的webpack.config.js
步骤:
1.下载cross-env软件包到当前项目
2.配置自定义命令,传入参数名和值(会绑定到procrss.env对象下)
3.在webpack.config.js区分不同环境使用不同配置
4.重新打包观察两种配置区别
npm i cross-env --save-dev
{
"name": "webpack",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "cross-env NODE_ENV=production webpack --mode=production",
"dev": "cross-env NODE_ENV=development webpack serve --mode=development --open"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"devDependencies": {
"cross-env": "^7.0.3",
"css-loader": "^7.1.2",
"css-minimizer-webpack-plugin": "^7.0.0",
"html-webpack-plugin": "^5.6.3",
"less": "^4.2.0",
"less-loader": "^12.2.0",
"mini-css-extract-plugin": "^2.9.2",
"style-loader": "^4.0.0",
"webpack": "^5.96.1",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^5.1.0"
},
"dependencies": {
"axios": "^1.7.7",
"bootstrap": "^5.3.3"
}
}
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = {
//打包环境
mode: 'development',
//入口
entry: path.resolve(__dirname, 'src/login/index.js'),
//出口
output: {
path: path.resolve(__dirname, 'dist'),
filename: './login/index.js',
clean:true//生成打包内容之前,清空输出内容
},
//插件
plugins: [
new HtmlWebpackPlugin({
filename: path.resolve(__dirname,'dist/login/index.html'),
template:path.resolve(__dirname,'public/login.html')
}),
new MiniCssExtractPlugin({
filename:'./login/index.css'
})//生成css插件
],
module: {
rules: [
//'style-loader'不能和MiniCssExtractPlugin.loader混用
{
test: /\.css$/i,
// use: ['style-loader', 'css-loader'],
// use: [
// MiniCssExtractPlugin.loader,
// "css-loader"
// ],
use: [
process.env.NODE_ENV==="development"?"style-loader": MiniCssExtractPlugin.loader,"css-loader"
],
},
{
test: /\.less$/i,
// use: [
// // compiles Less to CSS
// MiniCssExtractPlugin.loader,
// 'css-loader',
// 'less-loader',
// ],
use: [
process.env.NODE_ENV==="development"?"style-loader":
MiniCssExtractPlugin.loader,
'css-loader',
'less-loader',
],
},
{
test: /\.(png|jpg|jpeg|gif)$/i,
type: 'asset',
generator: {
filename: 'assets/[hash][ext][query]'
}
}
],
},
//压缩css代码
optimization: {
minimizer: [
// 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
`...`,
new CssMinimizerPlugin(),
],
},
}
4.注入环境变量
需求:前端项目组,开发模式下打印语句生效,生产模式下打印语句失效
问题:cross-env设置的只在node.js环境生效,前端代码无法访问 process.env.NODE_ENV
解决:使用webpack内置的DefinePlugin插件
作用:在编译时,将前端代码中匹配的变量名,替换为值或表达式
运行npm run dev命令打开页面会有打印,运行npm run build命令打开页面没有打印
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const webpack=require('webpack')
module.exports = {
//打包环境
mode: 'development',
//入口
entry: path.resolve(__dirname, 'src/login/index.js'),
//出口
output: {
path: path.resolve(__dirname, 'dist'),
filename: './login/index.js',
clean:true//生成打包内容之前,清空输出内容
},
//插件
plugins: [
new HtmlWebpackPlugin({
filename: path.resolve(__dirname,'dist/login/index.html'),
template:path.resolve(__dirname,'public/login.html')
}),
new MiniCssExtractPlugin({
filename:'./login/index.css'
}),//生成css插件
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
})
],
module: {
rules: [
//'style-loader'不能和MiniCssExtractPlugin.loader混用
{
test: /\.css$/i,
use: [
process.env.NODE_ENV==="development"?"style-loader": MiniCssExtractPlugin.loader,"css-loader"
],
},
{
test: /\.less$/i,
use: [
process.env.NODE_ENV==="development"?"style-loader":
MiniCssExtractPlugin.loader,
'css-loader',
'less-loader',
],
},
{
test: /\.(png|jpg|jpeg|gif)$/i,
type: 'asset',
generator: {
filename: 'assets/[hash][ext][query]'
}
}
],
},
//压缩css代码
optimization: {
minimizer: [
// 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
`...`,
new CssMinimizerPlugin(),
],
},
}
import './index.css'
import './index.less'
import 'bootstrap/dist/css/bootstrap.min.css'
import { checkPhone, checkCode } from '../utils/check'
import request from '../utils/request'
document.querySelector('.login-btn').addEventListener('click', () => {
let username = document.getElementById('username').value;
let password = document.getElementById('password').value;
console.log('username',username,'password',password);
if (!checkPhone(username)) {
console.log('手机号码必须是11位');
return
}
if (!checkCode(password)) {
console.log('验证码必须是6位');
return
}
console.log('登录');
request({
url: '/v1_0/authorizations',
methods: 'post',
data: {
mobile: username,
code:password
}
}).then(() => {
console.log('登录成功');
return
}).catch(() => {
console.log('登录失败');
return
})
})
import imgObj from './assets/OIP-C.jpg'
const theImg = document.createElement('img')
theImg.src = imgObj
document.querySelector('.login-container').appendChild(theImg)
if (process.env.NODE_ENV === 'production') {
console.log = function () {
}
}
console.log('开发环境');
5.开发环境调错source map
问题:代码被压缩和混淆,无法正确定位源代码位置
可以准备追踪error和warning在原始代码的位置
设置:webpack.config.js配置devtol选项
inline-source-map选项把远啊的位置信息一起打包在js文件中
注意:source map仅适用于开发环境,不要在生产环境使用
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const webpack = require('webpack')
const config={
//打包环境
mode: 'development',
//入口
entry: path.resolve(__dirname, 'src/login/index.js'),
//出口
output: {
path: path.resolve(__dirname, 'dist'),
filename: './login/index.js',
clean:true//生成打包内容之前,清空输出内容
},
//插件
plugins: [
new HtmlWebpackPlugin({
filename: path.resolve(__dirname,'dist/login/index.html'),
template:path.resolve(__dirname,'public/login.html')
}),
new MiniCssExtractPlugin({
filename:'./login/index.css'
}),//生成css插件
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
})
],
module: {
rules: [
//'style-loader'不能和MiniCssExtractPlugin.loader混用
{
test: /\.css$/i,
use: [
process.env.NODE_ENV==="development"?"style-loader": MiniCssExtractPlugin.loader,"css-loader"
],
},
{
test: /\.less$/i,
use: [
process.env.NODE_ENV==="development"?"style-loader":
MiniCssExtractPlugin.loader,
'css-loader',
'less-loader',
],
},
{
test: /\.(png|jpg|jpeg|gif)$/i,
type: 'asset',
generator: {
filename: 'assets/[hash][ext][query]'
}
}
],
},
//压缩css代码
optimization: {
minimizer: [
// 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
`...`,
new CssMinimizerPlugin(),
],
},
}
//开发环境下使用sourcemap
if (process.env.NODE_ENV === 'development') {
config.devtool='inline-source-map'
}
module.exports = config
6.解析别名alias
解析别名:配置模块如何解析,创建import引入路径的别名,来确保模块引入变得简单
例如:原来路径长,而且相对路径不安全
解决:在webpack.config.js中配置解析别名@来代表src绝对路径
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const webpack = require('webpack')
const config={
//打包环境
mode: 'development',
//入口
entry: path.resolve(__dirname, 'src/login/index.js'),
//出口
output: {
path: path.resolve(__dirname, 'dist'),
filename: './login/index.js',
clean:true//生成打包内容之前,清空输出内容
},
//插件
plugins: [
new HtmlWebpackPlugin({
filename: path.resolve(__dirname,'dist/login/index.html'),
template:path.resolve(__dirname,'public/login.html')
}),
new MiniCssExtractPlugin({
filename:'./login/index.css'
}),//生成css插件
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
})
],
//加载器
module: {
rules: [
//'style-loader'不能和MiniCssExtractPlugin.loader混用
{
test: /\.css$/i,
use: [
process.env.NODE_ENV==="development"?"style-loader": MiniCssExtractPlugin.loader,"css-loader"
],
},
{
test: /\.less$/i,
use: [
process.env.NODE_ENV==="development"?"style-loader":
MiniCssExtractPlugin.loader,
'css-loader',
'less-loader',
],
},
{
test: /\.(png|jpg|jpeg|gif)$/i,
type: 'asset',
generator: {
filename: 'assets/[hash][ext][query]'
}
}
],
},
//压缩css代码
optimization: {
minimizer: [
// 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
`...`,
new CssMinimizerPlugin(),
],
},
//解析别名
resolve: {
alias: {
"@":path.resolve(__dirname,'src')
}
}
}
//开发环境下使用sourcemap
if (process.env.NODE_ENV === 'development') {
config.devtool='inline-source-map'
}
module.exports = config
7.优化CDN使用
BootCDN - Bootstrap 中文网开源项目免费 CDN 加速服务 铂特优选
CDN定义:内容分发网络,指的是一组分布在各个地区的服务器
作用:把静态资源文件、第三方库放到CDN网络中的各个服务器中,供用户就近请求获取
好处:减轻服务器请求压力,就近请求物理延迟低,配套缓存策略
需求:开发模式使用本地第三方库,生产模式下使用CDN加载缓存
步骤:
1.在html中引入第三方库的CDN地址并用末班语法判断
2.配置webpack.config.js中externals外部扩展选项
3.打包观察两种模式
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const webpack = require('webpack')
const config={
//打包环境
mode: 'development',
//入口
entry: path.resolve(__dirname, 'src/login/index.js'),
//出口
output: {
path: path.resolve(__dirname, 'dist'),
filename: './login/index.js',
clean:true//生成打包内容之前,清空输出内容
},
//插件
plugins: [
new HtmlWebpackPlugin({
filename: path.resolve(__dirname,'dist/login/index.html'),
template: path.resolve(__dirname, 'public/login.html'),
useCdn:process.env.NODE_ENV==='production'//生产模式下使用引入cdn
}),
new MiniCssExtractPlugin({
filename:'./login/index.css'
}),//生成css插件
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
})
],
//加载器
module: {
rules: [
//'style-loader'不能和MiniCssExtractPlugin.loader混用
{
test: /\.css$/i,
use: [
process.env.NODE_ENV==="development"?"style-loader": MiniCssExtractPlugin.loader,"css-loader"
],
},
{
test: /\.less$/i,
use: [
process.env.NODE_ENV==="development"?"style-loader":
MiniCssExtractPlugin.loader,
'css-loader',
'less-loader',
],
},
{
test: /\.(png|jpg|jpeg|gif)$/i,
type: 'asset',
generator: {
filename: 'assets/[hash][ext][query]'
}
}
],
},
//压缩css代码
optimization: {
minimizer: [
// 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
`...`,
new CssMinimizerPlugin(),
],
},
//解析别名
resolve: {
alias: {
"@":path.resolve(__dirname,'src')
}
}
}
//开发环境下使用sourcemap
if (process.env.NODE_ENV === 'development') {
config.devtool='inline-source-map'
}
//生产环境下使用相关配置
if (process.env.NODE_ENV === 'production') {
//外部扩展,让webpack防止import的包被打进来
config.externals = {
'bootstrap/dist/css/bootstrap.min.css': 'bootstrap',
'axios':'axios'
}
}
module.exports = config
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<% if(htmlWebpackPlugin.options.useCdn){ %>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.3/css/bootstrap.min.css" rel="stylesheet">
<% } %>
</head>
<body>
<div class="login-container">
<h2>Login</h2>
<form id="loginForm">
<!-- 用户名输入框 -->
<input type="text" id="username" class="input-field" placeholder="Username" required>
<div id="username-error" class="error-message"></div>
<!-- 密码输入框 -->
<input type="password" id="password" class="input-field" placeholder="Password" required>
<div id="password-error" class="error-message"></div>
<!-- 登录按钮 -->
<button type="button" class="login-btn">Login</button>
</form>
<div class="footer">
<p>Don't have an account? <a href="#">Sign up</a></p>
</div>
</div>
</body>
<% if(htmlWebpackPlugin.options.useCdn){ %>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/1.7.2/axios.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.3/js/bootstrap.min.js"></script>
<% } %>
</html>
7.多页面打包
单页面:单个html文件,切换dom的方式实现不同业务逻辑展示
多页面:多个html文件,切换页面实现不同业务逻辑展示
步骤:
1.准备源码(html,css,js)放入相应的位置,并改用模块化语法导出
2.下载form-serialize包并导入到核心代码中使用
3.配置webpack.config.js多入口和多页面的设置
4.重新打包观察效果
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const webpack = require('webpack')
const config={
//打包环境
mode: 'development',
//入口
entry: {
'login': path.resolve(__dirname, 'src/login/index.js'),
'content':path.resolve(__dirname, 'src/content/index.js')
},
//出口
output: {
path: path.resolve(__dirname, 'dist'),
filename: './[name]/index.js',
clean:true//生成打包内容之前,清空输出内容
},
//插件
plugins: [
new HtmlWebpackPlugin({
filename: path.resolve(__dirname, 'dist/login/index.html'),
template: path.resolve(__dirname, 'public/login.html'),
useCdn: process.env.NODE_ENV === 'production',//生产模式下使用引入cdn,
chunks: ['login']//引入哪些打包后的模块,和entry的key一致
}),
new HtmlWebpackPlugin({
filename: path.resolve(__dirname,'dist/content/index.html'),
template: path.resolve(__dirname, 'public/content.html'),
useCdn: process.env.NODE_ENV === 'production',//生产模式下使用引入cdn
chunks: ['content']
}),
new MiniCssExtractPlugin({
filename:'./[name]/index.css'
}),//生成css插件
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
})
],
//加载器
module: {
rules: [
//'style-loader'不能和MiniCssExtractPlugin.loader混用
{
test: /\.css$/i,
use: [
process.env.NODE_ENV==="development"?"style-loader": MiniCssExtractPlugin.loader,"css-loader"
],
},
{
test: /\.less$/i,
use: [
process.env.NODE_ENV==="development"?"style-loader":
MiniCssExtractPlugin.loader,
'css-loader',
'less-loader',
],
},
{
test: /\.(png|jpg|jpeg|gif)$/i,
type: 'asset',
generator: {
filename: 'assets/[hash][ext][query]'
}
}
],
},
//压缩css代码
optimization: {
minimizer: [
// 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
`...`,
new CssMinimizerPlugin(),
],
},
//解析别名
resolve: {
alias: {
"@":path.resolve(__dirname,'src')
}
}
}
//开发环境下使用sourcemap
if (process.env.NODE_ENV === 'development') {
config.devtool='inline-source-map'
}
//生产环境下使用相关配置
if (process.env.NODE_ENV === 'production') {
//外部扩展,让webpack防止import的包被打进来
config.externals = {
'bootstrap/dist/css/bootstrap.min.css': 'bootstrap',
'axios':'axios'
}
}
module.exports = config
8.分割公共代码(splitChunks)
需求:把两个以上的页面引用的公共代码提取
步骤:
1.配置webpack.config.js的splitChunks分割功能
2.打包观察
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const webpack = require('webpack')
const config={
//打包环境
mode: 'development',
//入口
entry: {
'login': path.resolve(__dirname, 'src/login/index.js'),
'content':path.resolve(__dirname, 'src/content/index.js')
},
//出口
output: {
path: path.resolve(__dirname, 'dist'),
filename: './[name]/index.js',
clean:true//生成打包内容之前,清空输出内容
},
//插件
plugins: [
new HtmlWebpackPlugin({
filename: path.resolve(__dirname, 'dist/login/index.html'),
template: path.resolve(__dirname, 'public/login.html'),
useCdn: process.env.NODE_ENV === 'production',//生产模式下使用引入cdn,
chunks: ['login']//引入哪些打包后的模块,和entry的key一致
}),
new HtmlWebpackPlugin({
filename: path.resolve(__dirname,'dist/content/index.html'),
template: path.resolve(__dirname, 'public/content.html'),
useCdn: process.env.NODE_ENV === 'production',//生产模式下使用引入cdn
chunks: ['content']
}),
new MiniCssExtractPlugin({
filename:'./[name]/index.css'
}),//生成css插件
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
})
],
//加载器
module: {
rules: [
//'style-loader'不能和MiniCssExtractPlugin.loader混用
{
test: /\.css$/i,
use: [
process.env.NODE_ENV==="development"?"style-loader": MiniCssExtractPlugin.loader,"css-loader"
],
},
{
test: /\.less$/i,
use: [
process.env.NODE_ENV==="development"?"style-loader":
MiniCssExtractPlugin.loader,
'css-loader',
'less-loader',
],
},
{
test: /\.(png|jpg|jpeg|gif)$/i,
type: 'asset',
generator: {
filename: 'assets/[hash][ext][query]'
}
}
],
},
//压缩css代码
optimization: {
minimizer: [
// 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
`...`,
new CssMinimizerPlugin(),
],
//分割公共代码
splitChunks: {
chunks: 'all', // 分割所有模块(包括同步和异步模块)
cacheGroups: {
commons: { // 抽取公共部分
minSize: 0, // 最小大小
minChunks: 2, // 引用次数
reuseExistingChunk: true, // 重用已拆分的 chunk
name(module, chunks, cacheGroupKey) {
const allChunksNames = chunks.map((item) => item.name).join('~');
return `./js/${allChunksNames}`; // 输出到dist目录下的位置
}
}
}
}
},
//解析别名
resolve: {
alias: {
"@":path.resolve(__dirname,'src')
}
},
}
//开发环境下使用sourcemap
if (process.env.NODE_ENV === 'development') {
config.devtool='inline-source-map'
}
//生产环境下使用相关配置
if (process.env.NODE_ENV === 'production') {
//外部扩展,让webpack防止import的包被打进来
config.externals = {
'bootstrap/dist/css/bootstrap.min.css': 'bootstrap',
'axios':'axios'
}
}
module.exports = config