先简单回顾下 webpack 原理
Webpack 可以看做是模块打包机,把解析的所有模块变成一个对象,然后通过入口模块去加载我们的东西,然后依次实现递归的依赖关系,通过入口来运行所有的文件。由于 webpack 只认识js,所以需要通过一系列的 loader 和 plugin 转换成合适的格式供浏览器运行。
loader 主要是对资源进行加载/转译的预处理工作,其本质是一个函数,在该函数中对接收到的内容进行转换,返回转换后的结果。某种类型的资源可以使用多个 loader,执行顺序是从右到左,从下到上。
plugin(插件)主要是扩展 webpack 的功能,其本质是监听整个打包的生命周期。webpack 基于事件流框架 Tapable, 运行的生命周期中会广播出很多事件,plugin 可以监听这些事件,在合适的时机通过 webpack 提供的 API 改变输出结果。
新建一个目录,进入目录初始化 package.json,并安装 webpack 依赖
// 初始化包
npm init -y
// 安装依赖
npm i webpack webpack-cli -D
webpack 默认配置文件名字为 webpack.config.js,于是在项目根目录下新建一个名为 webpack.config.js 的文件,在配置文件里写最简单的单页面配置:
let path = require("path");
module.exports = {
mode: "development",
entry: "./src/js/index.js",
output: {
filename: "js/bundle.js",
path: path.resolve("dist"),
publicPath: "http://cdn.xxxxx"
}
}
配置详解
development 为开发模式,打包后代码不会被压缩production 为生产模式,打包后代码为压缩代码filename:打包后文件,filename 的值可设置成带 hash 戳的文件:js/bundle.[hash].js / js/bundle.[hash:8].js(只显示 8 位 hash 戳)path:打包文件路径,需为绝对路径publicPath:上线的cdn地址TIP: 上述代码中
path为内置模块,无需安装,直接引入即可。
新建后还需在项目根目录下的 src/js 目录下新建 index.js 文件,然后随便输入一句 js 代码。
配置后可使用 webpack 命令尝试打包,若报错找不到命令可 npm i webpack -g 全局安装后再打包,打包成功后会输出到项目根目录下的 dist 目录。
项目目录结构大致如下
├─package.json
├─webpack.config.js
├─src
| ├─js
| | └index.js
├─dist
由于 webpack 只认识 js,因此需通过 html-webpack-plugin 插件打包 html 文件
npm i html-webpack-plugin -D
安装后在 webpack.config.js 配置文件中
let HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
plugins: [ new HtmlWebpackPlugin({
template: "./src/index.html" }) ]
}
production 模式下可以开启 html 文件的压缩配置:
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html",
minify: {
removeAttributeQuotes: true, collapseWhitespace: true },
hash: true
})
]
配置详解
removeAttributeQuotes:删除属性双引号collapseWhitespace:代码压缩成一行TIP: 如果不指定模板
template配置,将是插件默认的 html文件,而不是项目中的 html 文件
webpack 通过安装 webpack-dev-server 开启服务
npm i webpack-dev-server -D
配置 webpack.config.js
devServer: {
port: 5000,
compress: true,
open: true,
client: {
progress: true }
}
配置详解
webpack-dev-server 配置
gzip 压缩progress:在浏览器中以百分比显示编译进度配置好可运行 webpack-dev-server 命令查看效果,若找不到命令可 npm i webpack-dev-server -g 全局安装下
开发过程中容易遇到接口跨域问题,可通过 devServer.proxy 配置解决
假设接口地址为 http://localhost:3000/api/users,对 /api/users 的请求可如下配置
devServer: {
proxy: {
'/api': 'http://localhost:3000',
},
},
但实际项目中接口的地址有很多种可能,一般不会有 /api 目录,即一般接口地址为http://localhost:3000/users,因此枚举配置会很麻烦,可通过代理请求解决
即先请求 http://localhost:3000/api/users 接口地址,然后通过 devServer 代理到 http://localhost:3000/users
本文通过 express 开启接口服务,接口地址为 http://localhost:3000/user,接口代码不再赘述,后期上传完整的源码,可通过 node "项目路径\webpack5\src\js\server.js" 启动接口服务,然后配置 webpack.config.js
devServer: {
proxy: {
"/api": {
target: "http://localhost:3000/",
pathRewrite: {
"/api": ""
},
},
}
}
devServer 配置详解
当后端接口没有写好,又不希望被阻塞进度,可以通过 mock 前期跟后端约定好的接口数据格式来模拟调试页面。可使用有自定义函数和应用自定义中间件的能力的配置 devServer.setupMiddlewares,在 middlewares.unshift 中的回调函数使用 res.send 把需要 mock 的数据传递进去:
devServer: {
setupMiddlewares: (middlewares, devServer) => {
if (!devServer) {
throw new Error("webpack-dev-server is not defined");
}
middlewares.unshift({
name: "user-info",
// `path` 是可选的,接口路径
path: "/user",
middleware: (req, res) => {
// mock 数据模拟接口数据
res.send({
name: "moon mock" });
},
});
return middlewares;
},
}
样式处理需要用到的 loader 及其作用:
less-loader:加载和转译 LESS 文件postcss-loader:使用 PostCSS 加载和转译 CSS/SSS 文件,如可以处理 autoprefixer css 包,为css添加浏览器前缀css-loader:解析 @import and url() 语法,使用 import 加载解析后的css文件,并且返回 CSS 代码mini-css-extract-plugin 的 loader:抽取出 css 文件,通过 link 标签引入 html 文件