webpack.config.js就是导出一个对象,且语法是基于nodeJS的,遵守common.js规范
1.入口配置:entry 指定入口路径,类型可以是字符串、数组、对象
入口合并配置、 多入口多出口配置
// 字符串(单js):项目构建时只执行 ./src/index.js,构建后生成一个主文件
entry: "./src/index.js",
// 数组(合并js):项目构建时同时执行数组里的js文件,构建后生成一个主文件
entry: ["./src/index.js", "./src/otherIndex.js"],
// 对象(多入口,多出口):项目构建时同时执行对象里的js文件,构建后生成多个主文件
entry: {
index: "./src/index.js",
other: "./src/otherIndex.js",
},
2.出口配置:output 指定出口路径、出口文件名称、静态资源路径,类型是对象
指定打包后的根路径、文件名、静态资源前缀拼接
占位符:
[id] 占位符,使用内部chunk id (测试,和name值相同)
[name ]占位符,使用入口文件名称
[hash] 占位符(单入口),项目每次构建都会生成唯一的hash,共20位数
[chunkhash ]占位符(多入口),根据不同入口entry进行依赖解析,构建对应的chunk,生成相应的hash,只要>组成entry的模块没有内容改动,则对应的hash不变, 默认情况下是chunkhash
[contenthash] 占位符:只关注单个文件,使用 contenthash 值,只要当前文件内容不变,hash也不变,也不会重复构建。
output: {
//构建后的生成的资源文件夹路径,必须是绝对路径,dist路径是默认的
path: path.resolve(__dirname, "./dist"),
//构建后生成的主文件,无论是多出口还是单出口都推荐使用占位符
//占位符
// id 占位符,使用内部chunk id (测试,和name值相同)
// name 占位符,使用入口文件名称
// hash 占位符(单入口),只要项目里有文件更改,整个项目构建的 hash 值都会更改,并且全部文件都共用相同的 hash 值
// chunkhash 占位符(多入口),根据不同入口entry进行依赖解析,构建对应的chunk,生成相应的hash,只要组成entry的模块没有内容改动,则对应的chunkhash 不变
// contenthash 占位符:只关注单个文件,使用 contenthash 值,只要当前文件内容不变,hash也不变,也不会重复构建。
filename: "[name]-[hash:20].js",
// 用来给生成的静态资源路径添加前缀,生产环境
publicPath: "https://cdn.hahaha.com/assets/",
// 用来给生成的静态资源路径添加前缀,开发环境
publicPath: "/assets/",
// 这样会在构建后的项目的index.html中,给所有静态资源路径添加上此前缀
// 如果不配置是无法找到静态资源的,不管是开发还是生产(开发也是构建项目,只是在内存中无法查看到)
// 有时候我们需要将我们的静态资源进行CDN托管:将静态资源上传到cdn的指定路径下并指定成 publicPath
},
3.构建模式配置:mode 指定构建模式,类型是字符串
development(开发环境)、production(生产环境)
mode: "development", // none、development(开发环境)、production(生产环境)
4. 插件配置:plugins 实例化所有引入的插件,类型是数组
插件返回的是函数类型,实例化后方可使用,相关的插件参数使用可以到github上去参考对应插件
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
plugins: [
new CleanWebpackPlugin(),
new MiniCssExtractPlugin({
filename: "css/[name].css",
}),
new HtmlWebpackPlugin({
title: "首页", // 配置页面名称
template: "./src/index.html", // 针对的html文件
filename: "index.html", // 打包后生成的文件名,也可以 html/index.html
}),
],
5. 文件处理loader配置:module的rules属性,将所有匹配的文件都通过对应的loader进行处理
通过文件类型对所有文件进行处理
- 无需引入直接在webpack的配置文件中的module中的rules数组中使用,
- loader的执行是异步的(等后一个执行完才执行前一个),执行顺序是从后往前
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
{
test: /\.less$/, // 正则匹配到对应后缀的文件
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
modules: true, // 传递给loader的参数
},
},
{
loader: "postcss-loader", // 对象类型
},
"less-loader", // 字符串类型,直接按名称调用不需配置参数
],
},
}
6. 调试模式source-map配置:devtool 配置浏览器的调试信息,报错时如何显示,类型字符串
浏览器的调试模式、报错结构
- source map 的种类很多比如:
devtool: 'source-map', 构建后生成 main.js.map 文件
devtool: 'inline-source-map', 构建后以 base64 的格式嵌入到 main.js 中- 开发环境推荐:cheap-module-eval-source-map
生产环境推荐:cheap-module-source-map
devServer: {
contentBase: path.resolve(__dirname, "./dist"), // 指定静态资源的根目录,默认的
publicPath: "/assets/", // 指定静态资源的公共路径, 加上上面就是 ./dist/assets/
open: true, // 自动打开浏览器
host: "http://localhost", //服务url,这里设置默认,可以设置本局域网的其他设备
port: 8080, // 服务启动的端口
openPage: "/other/page", // 构建时打开指定的网页
hot: true, // 模块热替换特性,开启模块热替换功能后在不刷新整个页面的情况下通过用心模块替换老模块来实现实时预览,只针对css
hotOnly: true, //即便HMR没有生效,浏览器也不要自动刷新。
allowedHosts: [".xxx.com", "xxx.xxxx.com", "bbbbbb.com"], // 可访问的url白名单
//接口请求时,跨域代理
proxy: {
"/api": {
target: "http://localhost:3000",
changeOrigin: true, // 可跨域
pathRewrite: { "^/api": "/" }, // 路径重写
},
},
// 接口请求之前,生命周期,常用于本地mock数据
before(app, server) {
app.get("/api/mock.json", (req, res) => {
res.json({
hello: "express",
});
});
// 接口请求之后,生命周期
after(app, server) {}
},
},
8. 优化配置
摇树、代码分割、作用域合并优化
// webpack优化,正常无其他要求直接使用默认配置即可,webpack4.0后基本无需配置
optimization: {
usedExports: true, //摇树: 导出的模块被使用了会打包处理,否则不会打包它(也就是定义了没用到)
// 代码分割: 满足下面所有条件的代码会被分割处理、默认配置如下(除了打包组的lodash和react)
splitChunks: {
chunks: "async", // async:异步模块,all:同时支持异步和同步
minSize: 30000, // 最小基数,大于等于这个30KB将会被分割,比如 echarts、xlsx 等大包
minChunks: 1, // 最小的使用次数:大于等于一次被分割,比如:import后再组件中使用一次以上将被分割
maxAsyncRequests: 5, // 按需加载 chunk 的并发请求数量小于等于 5 个
maxInitialRequests: 3, // 页面初始加载时的并发请求数量小于等于 3 个
automaticNameDelimiter: "~", //打包后名称的分隔符
name: true,
// 缓存组:可将多个模块打包成一文件
cacheGroups: {
lodash: {
test: /lodash/, // lodash模块 打包进一个组
name: "lodash", // 名字时lodash.js
},
react: {
test: /react|react-dom/, // react 和 react-dom模块,一起打包进入一个文件
name: "react", // 名称时react.js
},
vendors: {
test: /[\\/]node_modules[\\/]/, // 检测文件 node_modules 里的模块打包进一个文件
priority: -10, // 优先级:数字越大优先级越高
},
default: {
minChunks: 2, // 使用两次的chunk会打包进一个组里,除了node_modules因为它优先级高被拦截啦
priority: -20,
reuseExistingChunk: true,
},
},
},
concatenateModules: true, // 开启作用域提升,复用打包后的公用函数,将多个 function 函数合并成一个,减少代码体积,速度更快
},
9. 开发配置
指定第三方依赖所在路径、别名映射、后缀补齐
resolve: {
modules: [path.resolve(__dirname, "./node_modules")], //指定第三方包的路径:在哪个目录下查找第三方依赖
alias: {
// 别名:路径映射
"@": path.resolve(__dirname, "./src"),
react: "./node_modules/react/umd/react.production.min.js", // 也可映射到node_modules中
},
extensions: [".js", ".json"], // 文件后缀补齐:从前往后
},