webpack配置全面讲解【完整篇】
文章目录
- 前言
- webpack 核心包:
- 配置文件导出三种方式:
- 在线配置 webpack
- 配置文件解析:
- 入口(Entry):
- 输出(Output):
- 加载器(Loaders):
- 插件(Plugins):
- 模式(Mode):
- 目标(Target):
- webpack 的 runtime 和 manifest
- 服务器
- 模块解析配置
- 优化配置
- 热模块替换(Hot Module Replacement, HMR):
- 代码分割(Code Splitting):
- 在 Node 中使用 webpack
前言
Webpack 是一个现代 JavaScript 应用程序的静态
模块打包工具
,它可以将项目中的所有模块
(JavaScript、图片、CSS 等)打包成一个或多个 bundle
。
Webpack 4 是一个重要的版本,它提供了零配置、合理的默认设置、性能改进和开箱即用的优化工具。本文将对webpack 4
进行介绍,后面会对其他版本特性进行补充
webpack 核心包:
-
webpack: 这是 Webpack 的
核心包
,提供了模块打包的能力。它能够处理项目中 JavaScript 模块的依赖关系,并生成最终的静态资源文件。 -
webpack-cli: 这是 Webpack 的
命令行工具
,允许你通过命令行界面来运行 Webpack。它提供了各种命令来控制 Webpack 的构建过程。 -
webpack-dev-server: 这是一个小型的 Express
开发服务器
,用于开发环境。它提供了热模块替换(HMR)功能,允许在开发过程中实时重新加载模块,而无需刷新整个页面。
配置文件导出三种方式:
默认使用的是 webpack.config.js
文件,也可以是其他名字,webpack -c xxx
,只需要通过-c
置顶文件就行,配置文件默认有是三种导出格式:
- 对象或数组:单个配置或多个配置
- 函数: 可以根据环境变量和条件导出不同的配置
- Promise:用于远程加载其他配置参数,最终返回结果
代码实例:
// 对象或数组
module.exports = [{output: {filename: "./dist.js",},entry: "./app.js",},{output: {filename: "./dist-test.js",},entry: "./app.js",},
];
// 函数
module.exports = function (env, argv) {return {mode: env.production ? "production" : "development",devtool: env.production ? "source-map" : "eval",plugins: [new TerserPlugin({terserOptions: {compress: argv.mode === "production", // only if `--mode production` was passed},}),],};
};
// promise
module.exports = () => {return new Promise((resolve, reject) => {setTimeout(() => {resolve({entry: "./app.js",/* ... */});}, 5000);});
};
在线配置 webpack
- createapp.dev
配置文件解析:
入口(Entry):
- 入口点是应用程序的起点,Webpack 从这些点开始构建其依赖图。入口可以是一个文件或者一个文件数组。
// 单入口
entry: {main:'./index.js',
}
// 多入口
entry: {main: './src/app.js',foo: './src/foo.js',
},
输出(Output):
- 输出属性指定了打包后的文件将如何被写入到磁盘上。它定义了输出文件的名称、路径以及它们在浏览器中被引用的方式。
output: {filename: '[name].js', //hash选择:[hash],[contenthash] 或者 [chunkhash] 的长度可以使用 [hash:16]path: __dirname + '/dist', //输出目录publicPath: 'https://cdn.example.com/assets/[fullhash]/' // 设置cdn 和 hash},
加载器(Loaders):
- Webpack 只能理解 JavaScript,
Loaders 允许 Webpack 处理其他类型的文件
,并将它们转换为 Webpack 能够理解的模块【模块转化】
。 - loader 可以使你在 import 模块时预处理文件。因此,loader 类似于其他构建工具中“任务(task)”,并提供了处理前端构建步骤的得力方式
- loader 支持配置和内联的方式书写
- loader 执行顺序:
从右到左(或从下到上)
的执行(execute)
module: {rules: [{test: /\.css$/,exclude: /node_modules/,use: [{ loader: 'style-loader' },{loader: 'css-loader',options: {modules: true, // css模块化},},{ loader: 'sass-loader' },],},],}
插件(Plugins):
- 插件在 Webpack 构建过程中提供了更多的功能,如优化、压缩、分割代码等。插件可以在整个构建过程中的特定时机注入上下文。
- Webpack 内部广泛使用
Tapable
(一个 Node.js 库),它提供了一个发布-订阅(pub-sub)
机制,允许用户在特定的钩子(hook)上注册监听器(listener)。
const HtmlWebpackPlugin = require("html-webpack-plugin");
const webpack = require("webpack"); // 访问内置的插件plugins: [new webpack.ProgressPlugin(),new HtmlWebpackPlugin({ template: "./src/index.html" }),
];
模式(Mode):
- 模式决定了 Webpack 是为开发环境还是生产环境构建应用程序。它可以是
development
、production
或none
。模式影响 Webpack 的优化和警告。
// 模式mode: 'production', //development
目标(Target):
用于告知 Webpack 为哪个环境或目标(target)进行构建编译 , 默认情况下,
target 的值是 "web"
// 模式target: 'web', //node、webworker 。。。。
webpack 的 runtime 和 manifest
- manifest 包含文件一般包含 ,如模块及模块依赖、每个模块的源码映射、异步加载的模块,等。
- runtime 会通过 manifest 来解析和加载模块。
服务器
配置开发服务器,包括代理、热模块替换等
devServer: {// 设置开发服务器监听的主机地址// '0.0.0.0' 表示服务器将接受所有可用网络接口的请求host: '0.0.0.0',// 设置开发服务器监听的端口号port: 3000,// 设置为 true 时,当 webpack 编译完成后,会自动在浏览器中打开应用open: true,// 启用模块热替换(HMR),允许在不刷新整个页面的情况下,实时更新模块hot: true,// 为单页应用(SPA)提供支持,当访问不存在的路由时,会返回 index.htmlhistoryApiFallback: true,// 开启 gzip 压缩,提高传输效率compress: true,// 指定了 public 目录下的文件作为静态资源// 当你访问如 /js/index.js 这样的路径时,devServer 会从 public 目录提供文件static: {directory: path.join(__dirname, 'public')},// 配置代理,用于开发环境的后端接口代理proxy: {// 当请求前缀为 /api 时,触发代理'/api': {// 代理目标服务器的地址target: 'http://backend.server.com',// 配置是否改变请求头中的origin字段changeOrigin: true,// URL 重写,这里将请求中的 /api 替换为空字符串 例如,将 /api/user 重写为 /userpathRewrite: { '^/api': '' },},},
},
模块解析配置
resolve: {alias: { //创建 import 或 require 的别名@: path.resolve(__dirname, 'src/'),_: path.resolve(__dirname, 'src/utils/'),},extensions: ['.js', '.jsx', '.ts','.tsx'], //尝试按顺序解析这些后缀名modules: [path.resolve(__dirname, 'src'), 'node_modules'], //告诉 webpack 解析模块时应该搜索的目录。},
优化配置
配置代码压缩、优化分割代码块。
// 优化optimization: {minimize:true, // 开启优化// minimizer 属性用于配置压缩工具,用于压缩 JavaScript 和 CSS 文件minimizer: [// TerserPlugin 是一个插件,用于压缩 JavaScript 文件new TerserPlugin({// terserOptions 用于传递给 Terser 的选项terserOptions: {// compress 属性用于配置压缩选项compress: {// drop_console 选项设置为 true,将删除所有的 console 语句drop_console: true}},// extractComments 选项设置为 false,以防止插件提取注释到单独文件extractComments: false}),// OptimizeCSSAssetsPlugin 用于压缩 CSS 文件new OptimizeCSSAssetsPlugin({})],// splitChunks 属性用于配置代码分割选项splitChunks: {// chunks 属性用于指定应该分割哪些 chunks,'all' 表示所有 chunkschunks: 'all',// minSize 属性定义了分割出的 chunk 的最小大小,这里是 20000 字节minSize: 20000,// minRemainingSize 属性定义了分割后剩余模块的最小大小,这里设置为 0minRemainingSize: 0,// minChunks 属性定义了模块应该被分割的最小 chunk 数量,这里是 1minChunks: 1,// maxAsyncRequests 属性定义了按需加载时的最大并行请求数,这里是 5maxAsyncRequests: 5,// maxInitialRequests 属性定义了初始加载时的最大并行请求数,这里是 3maxInitialRequests: 3,// automaticNameDelimiter 属性定义了自动生成的 chunk 名称之间的分隔符automaticNameDelimiter: '~',// automaticNameMaxLength 属性定义了自动生成的 chunk 名称的最大长度,这里是 30automaticNameMaxLength: 30,// cacheGroups 属性用于配置缓存组,用于更细致地控制代码分割cacheGroups: {// defaultVendors 缓存组用于处理来自 node_modules 的第三方库defaultVendors: {// test 属性用于定义哪些模块应该被包含在这个缓存组test: /[\\/]node_modules[\\/]/,// priority 属性定义了这个缓存组的优先级,-10 表示较低优先级priority: -10,// reuseExistingChunk 选项设置为 true,表示尽可能重用现有的 chunkreuseExistingChunk: true},// default 缓存组用于处理应用程序代码default: {// minChunks 属性定义了模块应该被分割的最小 chunk 数量,这里是 2minChunks: 2,// priority 属性定义了这个缓存组的优先级,-20 表示较低优先级priority: -20,// reuseExistingChunk 选项设置为 true,表示尽可能重用现有的 chunkreuseExistingChunk: true}}}
},
热模块替换(Hot Module Replacement, HMR):
- HMR 是一种功能,允许在应用程序运行时替换、添加或删除模块,而无需重新加载整个页面。
- 原理:
- 浏览器和服务器建立socket 通道
- 修改代码后,webpack compiler 发出
update
事件, - hmr 请求 manifest和chunk,根据页面内容配置,更新模块
// webpack.config.jsdevServer:{hot:true
}plugins: [new webpack.HotModuleReplacementPlugin()
]// component.jsfunction component() {const element = document.createElement('input');element.value = 123;return element;}let element = component();document.body.appendChild(element);if (module.hot) {module.hot.accept('./print.js', function() {console.log('热更新进入!');const value = document.getElementsByTagName("input")[0].value.value;element = component(); // 重新渲染 component 以更新点击事件处理程序document.body.appendChild(element);// 回显数据document.getElementsByTagName("input")[0].value.value = value})}
代码分割(Code Splitting):
- 代码分割是 Webpack 的一个特性,可以将代码分割成多个块,这些块可以按需加载或者并行加载,从而优化加载时间和性能。
- 代码拆分手段:import 动态导入、ensure方法、SplitChunksPlugin插件、多入口
- 动态导入(Dynamic Imports)
动态导入是实现代码分割最简单的方式之一。你可以使用 import()
函数来动态地加载模块。
// 1. 直接使用
if (someCondition) {import("./otherModule.js").then((otherModule) => {otherModule.doSomething();});
}// 2. promise 返回
function loadModule(modulePath) {return new Promise((resolve, reject) => {import(modulePath).then((module) => {resolve(module);},(err) => {reject(err);});});
}// 动态加载模块
loadModule("./otherModule.js").then((module) => {module.doSomething();}).catch((err) => {console.error("模块加载失败", err);});
在 Webpack 配置中,你不需要做任何特别的配置来处理动态导入,因为 Webpack 已经自动支持了。
- 使用
require.ensure
require.ensure
是一个更老的代码分割方法,require.ensure()
是 webpack 特有的,已被 import()
取代。。
// 参数1: dependencies 依赖数组
// 参数2: callback 回调函数
// 参数3: errorCallback: 失败回调
// 参数4: chunkName
// Webpack会创建一个名为 `feature` 的新chunk。
require.ensure([],() => {const module = require("./module");module.someFunction();},"feature"
);
- SplitChunksPlugin
SplitChunksPlugin
是 Webpack 4+ 引入的一个插件,用于控制代码块的分割逻辑。以下是一个基本的配置示例:
const webpack = require("webpack");module.exports = {// ...optimization: {splitChunks: {chunks: "all", // 代码分割的chunk类型,可选值有 'initial'、'async' 或 'all'minSize: 20000, // 最小chunk大小,默认单位是byteminChunks: 1, // 最小chunk数量,默认是1maxAsyncRequests: 5, // 按需加载时的最大并行请求数maxInitialRequests: 3, // 入口点的最大并行请求数automaticNameDelimiter: "~", // 分割出的chunk文件名的连接符cacheGroups: {defaultVendors: {test: /[\\/]node_modules[\\/]/,priority: -10,reuseExistingChunk: true,},default: {minChunks: 2,priority: -20,reuseExistingChunk: true,},},},},// ...
};
- 多入口拆分
如果你想要手动拆分第三方库,可以在 entry
属性中指定:
entry: {bundle: './src/index.js',vendor: ['react', 'react-dom'] // 将React和ReactDOM拆分出去
},output: {filename: '[name].js' // 根据entry的key来命名
},optimization: {splitChunks: {cacheGroups: {vendor: {test: /[\\/]node_modules[\\/]/,name: 'vendor',chunks: 'all'},},},
},
-
摇树优化(Tree Shaking):
- 摇树优化是一种去除应用程序中未引用代码的技术,通常与 ES6 模块一起使用。
-
懒加载(Lazy Loading):
- 懒加载是一种按需加载模块的技术,可以减少初始加载时间。
-
配置(Configuration):
- Webpack 的配置是通过一个名为
webpack.config.js
的文件来进行的,它定义了入口、输出、加载器、插件等。
- Webpack 的配置是通过一个名为
-
解析(Resolving):
- 解析是 Webpack 确定如何处理文件的过程,包括如何找到文件、如何解析文件中的模块请求等。
-
缓存(Caching):
- Webpack 通过缓存来提高构建性能,它会跳过未发生变化的模块,避免不必要的重新构建。
-
记录(Profiling):
- Webpack 可以生成构建的记录,帮助开发者分析和优化构建过程。
-
持久化(Persistence):
- Webpack 4 引入了持久化缓存,即使在构建之间也可以保持缓存状态。
在 Node 中使用 webpack
const webpack = require("webpack"); // 访问 webpack 运行时(runtime)
const configuration = require("./webpack.config.js");let compiler = webpack(configuration); //传入配置new webpack.ProgressPlugin().apply(compiler);compiler.run(function (err, stats) {if (err) {console.log("编译出错");}
});
相关文章:

webpack配置全面讲解【完整篇】
文章目录 前言webpack 核心包:配置文件导出三种方式:在线配置 webpack配置文件解析:入口(Entry):输出(Output):加载器(Loaders):插件&…...

十、kotlin的协程
协程 基本概念定义组成挂起和恢复结构化并发协程构建器作用域构建器挂起函数阻塞与非阻塞runBlocking全局协程像守护线程 Job的生命周期 常用函数延时和等待启动和取消启动取消 暂停 协程启动调度器启动方式启动模式线程上下文继承的定义继承的公式 协程取消与超时取消挂起点取…...

vscode qt 最新开发环境配置, 基于最新插件 Qt All Extensions Pack
qt 之前发布了vscode qt offical ,但是最新更新中将其升级改为了几个不同的插件,功能更强大 1. 前置条件 qt 已安装 2. 插件安装 打开vscode 插件安装,搜索qt 会看到很多qt插件,直接选择Qt All Extensions Pack 安装 会安装qt环境所需的…...

【MySQL】Ubuntu环境下MySQL的安装与卸载
目录 1.MYSQL的安装 2.MySQL的登录 3.MYSQL的卸载 4.设置配置文件 1.MYSQL的安装 首先我们要看看我们环境里面有没有已经安装好的MySQL 我们发现是默认是没有的。 我们还可以通过下面这个命令来确认有没有mysql的安装包 首先我们得知道我们当前的系统版本是什么 lsb_…...

C# StringBuilder类:高效构建和修改字符串的利器
C# 中的 StringBuilder 类是一个可变的字符序列,用于高效地构建和修改字符串。与字符串(string)不同,字符串在 C# 中是不可变的,这意味着每次修改字符串(如拼接、替换等操作)时,都会…...

AVL平衡树(AVL Tree)
**场景:课堂讨论** --- **小明(ESFP学生)**:张老师,为什么AVL树(AVL Tree)中的旋转操作这么重要?感觉只是节点的移动,有没有什么实际意义? **张老师&#…...

【python实操】python小程序之两数取大值以及login登录
引言 python小程序之两数取大值以及login登录 文章目录 引言一、两数取大值1.1 题目1.2 代码1.3 代码解释 二、login登录2.1 题目2.2 代码2.3 代码解释 三、思考3.1 两数取大值3.2 login登录 一、两数取大值 1.1 题目 定义一个函数my_max,包含两个参数, 函数的作用…...

Pikachu-File Inclusion-远程文件包含
远程文件包含漏洞 是指能够包含远程服务器上的文件并执行。由于远程服务器的文件是我们可控的,因此漏洞一旦存在,危害性会很大。但远程文件包含漏洞的利用条件较为苛刻;因此,在web应用系统的功能设计上尽量不要让前端用户直接传变…...

TIM(Timer)定时器的原理
一、介绍 硬件定时器的工作原理基于时钟信号源提供稳定的时钟信号作为计时器的基准。计数器从预设值开始计数,每当时钟信号到达时计数器递增。当计数器达到预设值时,定时器会触发一个中断信号通知中断控制器处理相应的中断服务程序。在中断服务程序中&a…...

Microsoft Visual Studio有多油饼
#1 Microsoft Visual Studio C 2023: 必须安装在C盘 为啥? 安其他盘能亖啊? 真有病 #2 Microsoft Visual Studio C 2013: 每个硬盘必须都腾出至少8个G的空间 不是我安在这个盘不就是为了其他盘没空间吗? 合着…...

Golang | Leetcode Golang题解之第452题用最少数量的箭引爆气球
题目: 题解: func findMinArrowShots(points [][]int) int {if len(points) 0 {return 0}sort.Slice(points, func(i, j int) bool { return points[i][1] < points[j][1] })maxRight : points[0][1]ans : 1for _, p : range points {if p[0] > …...

Python 从入门到实战35(进程-multiprocessing模块)
我们的目标是:通过这一套资料学习下来,可以熟练掌握python基础,然后结合经典实例、实践相结合,使我们完全掌握python,并做到独立完成项目开发的能力。 上篇文章我们讨论了turtle库绘制图画操作的相关知识。今天学习一下…...

“米哈游悄然布局未来科技:入股星海图,共绘具身智能机器人新篇章“
米哈游悄然入股具身智能机器人公司:技术布局与未来展望 近日,米哈游阿尔戈科技有限公司宣布入股具身智能机器人公司星海图,这一消息在行业内引起了广泛关注。米哈游,这家以游戏开发而闻名的企业,近年来正逐步扩大其在人工智能和新兴科技领域的投资布局,此次入股星海图正是…...

基于spring boot的篮球论坛系统
作者:计算机搬砖家 开发技术:SpringBoot、php、Python、小程序、SSM、Vue、MySQL、JSP、ElementUI等,“文末源码”。 专栏推荐:SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:Java精选实战项…...

华夏ERP账号密码泄露漏洞
漏洞描述 华夏ERP账号密码泄露漏洞 漏洞复现 FOFA "jshERP-boot" POC IP/jshERP-boot/user/getAllList;.ico...

Android问题笔记五十:构建错误-AAPT2 aapt2-7.0.2-7396180-windows Daemon
Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC 👉关于作者 专注于Android/Unity和各种游戏开发技巧,以及各种资源分…...

CAD 3dsmax maya等autodesk系列专用卸载修复工具AutoRemove,一键完全彻底卸载删除软件的专用卸载工具
AutoRemove 是一款功能强大的软件卸载工具,专门设计用于彻底清除Autodesk系列软件,如AutoCAD、3ds Max、Revit、Maya、Inventor、Navisworks、civil 3d、sketchbook、Architecture、Electrical、Mechanical、、等,从您的系统中。它通过深度清…...

python中的函数介绍
文章目录 1.函数1.1 语法格式1.2 函数参数1.3 函数的返回值1.4 变量作用域1.5 函数的执行过程1.6 链式调用1.7 嵌套调用1.8 函数栈帧1.9 函数递归1.10 参数默认值1.11 关键词参数 1.函数 无论是编程中的函数还是数学中的函数,本质都是差不多的,丢给函数…...

LinuxO(1)调度算法
概念 在Linux中,O(1)调度算法是一种进程调度算法。O(1)表示算法的时间复杂度是常数级别的,与系统中的进程数量无关。 运行队列结构 他采用了两个运行队列,一个活动队列和一个过期队列。活动队列中的进程是有资格获取CPU时间片的进程&#x…...

安防监控/视频系统EasyCVR视频汇聚平台如何过滤134段的告警通道?
视频汇聚/集中存储EasyCVR安防监控视频系统采用先进的网络传输技术,支持高清视频的接入和传输,能够满足大规模、高并发的远程监控需求。平台支持国标GB/T 28181协议、部标JT808、GA/T 1400协议、RTMP、RTSP/Onvif协议、海康Ehome、海康SDK、大华SDK、华为…...

SDKMAN!安装Maven
一、通过SDKMAN!正常安装 查看maven版本 sdk list maven安装maven 3.6.3版本 sdk install maven 3.6.3查看maven 3.6.3安装目录 sdk home maven 3.6.3安装过程中可能会失败,出现tmp临时目录中存在临时文件 # 移除临时文件,不要手动删除,…...

[NeurIPS 2022] STaR: Bootstrapping Reasoning With Reasoning
Contents IntroductionMethodExperimentsReferences Introduction CoT 推理可以有效提升 LLM 推理能力,但 few-shot prompting 无法发挥 CoT 的全部潜力,训练能够生成中间推理步骤 (i.e., rationale) 的 LLM 又需要大量人工标注 rationale,为…...

C++中对象的构造与析构
目录 一、引言 二、构造函数详解 1.构造函数的作用 2.构造函数的调用时机 3.构造函数的分类 三、析构函数详解 1.析构函数的作用 2.析构函数的调用时机 四、实例分析 五、总结 本文将详细讲解C中对象的构造和析构过程,包括构造函数、析构函数的作用及其调用时机…...

算法笔记(九)——栈
文章目录 删除字符串中的所有相邻重复项比较含退格的字符串基本计算机II字符串解码验证栈序列 栈是一种先进后出的数据结构,其操作主要有 进栈、压栈(Push) 出栈(Pop) 常见的使用栈的算法题 中缀转后缀逆波兰表达式求…...

动态SLAM总结一
文章目录 方法分类:OctoMap:(2013)UFOMap:(2020)Removert:(2020)ERASOR:(2021)DynamicFilter:(202…...

HTB:Mongod[WriteUP]
连接至HTB服务器并启动靶机 靶机IP:10.129.99.33 分配IP:10.10.16.12 1.How many TCP ports are open on the machine? 使用nmap对靶机进行全端口TCP脚本、服务扫描: nmap -sC -sV -T4 -p- {TARGET_IP} 可以看到靶机共开放TCP端口2个&…...

DenseNet算法:口腔癌识别
本文为为🔗365天深度学习训练营内部文章 原作者:K同学啊 一 DenseNet算法结构 其基本思路与ResNet一致,但是它建立的是前面所有层和后面层的密集连接,它的另一大特色是通过特征在channel上的连接来实现特征重用。 二 设计理念 三…...

828华为云征文 | 利用FIO工具测试Flexus云服务器X实例存储性能
目录 一、Flexus云服务器X实例概要 1.1 Flexus云服务器X实例摘要 1.2 产品特点 1.3 存储方面性能 1.4 测评服务器规格 二、FIO工具 2.1 安装部署FIO 2.2 主要性能指标概要 三、进行压测 3.1 测试全盘随机读IO延迟 3.2 测试全盘随机写IO延迟 3.3 测试随机读IOPS 3.4…...

Pikachu-File Inclusion- 本地文件包含
前端每次挑选篮球明星,都会通过get请求,传了文件名,把页面展示出来,由于文件名时前端传给后台;并且查看源码,没有对参数做限制; 尝试直接从前端修改filename 参数; filename../../../../../../…...

linux基础 超级笔记
1.Linux系统的组成 Linux系统内核:提供系统最核心的功能,如软硬件和资源调度。 系统及应用程序:文件、任务管理器。 2.Linux发行版 通过修改内核代码自行集成系统程序,即封装。比如Ubuntu和centos这种。不过基础命令是完全相…...