Webpack构建工具
构建工具系列
- Gulp构建工具
- Grunt构建工具
- Webpack构建工具
- Vite构建工具
Webpack构建工具
- 构建工具系列
- 前言
- 一、安装
- 打包
- 配置webpack
- 安装样式加载器
- devtool
- webpack devtool 配置详解
- 常见 devtool 值及适用场景
- 选择建议
- 性能影响
- 注意事项
- module
- 处理流程
- module.rules
- module.use
- module.type
跟着B站视频30 分钟掌握 Webpack写的
代码:项目地址
前言
Webpack 是一个现代 JavaScript 应用的静态模块打包工具。它将项目中的各类资源(如 JavaScript、CSS、图片等)视为模块,通过依赖关系分析生成优化后的静态资源。
一、安装
- 通过 npm 安装相关插件:
mkdir pkdemo cd pkdemo npm init -y npm i webpack webpack-cli -D npm i html-webpack-plugin -D npm i babel-loader @babel/core @babel/preset-env -D npm i terser-webpack-plugin -D npm i webpack-dev-server -D npm i webpack-bundle-analyzer -D code .
- npm init -y 是一个快速初始化 Node.js 项目的命令,它跳过交互式问答环节,直接生成默认的 package.json 文件。 -y 或 --yes 参数表示使用默认配置,无需手动输入信息。默认值包括项目名(基于当前目录)、版本号(1.0.0)、描述等字段。
- webpack 是模块打包工具,用于处理 JavaScript 和其他静态资源
- webpack-cli 是 Webpack 的
命令行工具
,提供命令行交互和配置支持。- –save-dev(或 -D 简写)表示将安装的包记录在 devDependencies 中,即这些包仅在开发阶段需要,不会包含在生产环境中。
- html-webpack-plugin一个常用的插件,用于简化 HTML 文件的创建和管理。它能够
自动生成 HTML 文件
,并自动注入打包后的 JavaScript 和 CSS 资源。- babel-loader将现代 JavaScript 代码(如 ES6+、TypeScript 或 JSX)转换为向后兼容的版本,确保代码能在旧版浏览器或环境中运行。babel-loader 依赖于 Babel 核心工具链(@babel/core)和配置的预设(presets)或插件(plugins)来完成转译任务。
- @babel/core负责解析源代码、应用插件或预设的转换规则,并生成目标代码,是
整个 Babel 生态系统的引擎
。- @babel/preset-env 是一个智能预设,根据目标浏览器或环境自动确定需要的 Babel 插件和 polyfill。它通过分析项目的 browserslist 配置或手动指定的目标环境,仅转换必要的语法特性,避免不必要的代码转换。例如:
- 如果目标环境支持箭头函数,@babel/preset-env 会跳过箭头函数的转换。
- 如果目标环境缺乏 Promise,它会自动引入相关 polyfill(需配合 core-js 使用)。- terser-webpack-plugin用于通过 Terser 工具
压缩 JavaScript 代码
- webpack-dev-server一个基于 Express 的本地开发服务器,专为 webpack 项目提供实时重新加载(Live Reloading)和模块热替换(HMR)功能。它通过内存编译文件,避免写入磁盘,从而提升开发效率。配置完成,
初次打包后将自动打开浏览器并加载页面,且更改代码后将自动更新页面
。- webpack-bundle-analyzer 是一个可视化工具,用于分析 Webpack 构建生成的 bundle 文件。它帮助开发者理解打包后的文件结构、大小及其依赖关系,从而优化性能。
配置后打包得时候会自动显示一个可视化页面,从里面可以看到各文件大小
。
可视化分析 bundle 组成
通过交互式树状图或矩形图展示 bundle 中每个模块的大小及其占比,直观呈现哪些模块占用了最多空间。开发者可以快速定位体积过大的模块。
识别冗余或重复依赖
工具会高亮显示重复或未被使用的依赖项,帮助开发者发现代码分割或 Tree Shaking 未优化的部分,减少不必要的代码打包。
优化代码分割策略
分析结果可用于调整 Webpack 的 SplitChunks 配置,合理拆分公共代码或第三方库,避免单个 bundle 过大影响加载速度。
对比不同构建版本
支持与历史构建结果对比,观察优化前后的 bundle 变化,验证配置调整是否有效。例如检查是否成功压缩了特定依赖的体积。
辅助长期性能监控
整合到持续集成流程中,定期生成分析报告,监控项目体积的增长趋势,防止因新增依赖导致性能退化。- code . 打开VScodde
打包
在项目根目录新建一个
index.html
文件。输入英文状态下的!
或者输入html:5
并回车即可自动创建一个HTML模板。
新建src\index.js
在插件市场安装Live Server
,可帮我们运行html页面,在html页面右键选择open in the Liver Server
即可(安装目的:查看html页面编写是否有问题)。
运行打包指令:
npx webpack
在根目录出现一个dist
文件夹即打包成功。
配置webpack
在项目根目录新建webpack.config.js文件,并在其中进行信息配置。
// 导入path插件
const path = require('path');
//导入静态页面生成插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
//导入压缩插件
const TerserPlugin = require('terser-webpack-plugin');
//导入打包分析插件
const BundleWebpackPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
/*
* model.exports:nodejs模块导出对象
* mode 开发模式或生产模式
* entry 用于指定打包的入口文件。webpack会从这些入口文件开始,构建内部依赖图,并打包所有依赖模块
* output 用于指定打包后的文件输出位置、文件名格式以及其他相关设置
* module指的是项目中可被分割的最小功能单位。每个文件(如JavaScript、CSS、图片等)都被视为一个module.
* webpack通过分析这些module之间的依赖关系,构建依赖图(Dependency Graph),最终打包成浏览器可识别的静态资源
*/
module.exports = {mode: 'development', // 模式, development或production//设置此属性是为了方便查看打包后得源代码devtool: 'inline-source-map', // 开发环境下使用source-map,生产环境下使用hidden-source-map,eval-source-mapentry: "./src/index.js",//入口文件output: {//输出文件path: path.resolve(__dirname ,'dist'), // 指定输出文件的目录,必须为绝对路径// filename: "bundle.js"// 定义输出文件的名称。可以使用[name]、[hash]等占位符动态生成文件名filename: "[name].[contenthash].js"// [name]会被替换为入口文件的名称,[contenthash]会根据内容生成一个唯一的哈希值,确保文件名在内容变化时也会变化,从而实现缓存优化},optimization: {minimize:true,//是否压缩minimizer:[new TerserPlugin()]//使用TerserPlugin压缩},/* 插件 * plugins:[new HtmlWebpackPlugin() ]可自动生成html,可不传参*/plugins:[// 自动生成html文件new HtmlWebpackPlugin({title: 'webpack打包测试',// 定义生成的html文件的标题filename: 'testIndex.html',// 定义生成的html文件的名称// template: 'src/index.html'// 定义html模板文件路径}),// 打包分析插件new BundleWebpackPlugin({})],module:{ rules: [//匹配css的规则{//用于匹配以 .css 结尾的字符串,且匹配时不区分大小写test: /\.css$/i,//\.转义'.' ,$匹配字符串的结尾,i 修饰符表示不区分大小写的匹配/**用于指定处理特定文件类型时使用的 loader。*它是一个数组,可以包含多个 loader,webpack 会从右到左(或从下到上)依次应用这些 loader。*/use: ['style-loader', 'css-loader']// 使用的loader,Loader 从右向左执行,例如 use: ['style-loader', 'css-loader'] 中先执行 css-loader。},//匹配图片的规则{test:/\.(png|jpg|jpeg|png|gif|svg)$/i,type: 'asset/resource', // 使用资源模块处理图片文件,将文件直接输出到输出目录并返回最终的 URL},//匹配js的规则{ test: /\.js$/, // 匹配所有以 .js 结尾的文件exclude: /node_modules/, // 排除 node_modules 目录下的文件use: {loader: 'babel-loader', // 使用 babel-loader 处理 JavaScript 文件options: {presets: ['@babel/preset-env'] // 使用 @babel/preset-env 预设}}}]},// 开发环境下使用 webpack-dev-server 开启热更新,还需要再去package.json中配置相关命令:scripts中添加“"start": "webpack serve --open"”devServer:{// 静态资源目录static: "./dist"},resolve:{alias: {// 设置别名,方便在代码中引用'@': path.resolve(__dirname, 'src'),'@utils': path.resolve(__dirname, 'src/utils'),'@assets': path.resolve(__dirname, 'src/assets')},}// EntryOptionPlugin
}
安装样式加载器
在Webpack或Vite等构建工具中配置样式加载器后方可编译样式文件。
npm i style-loader css-loader -D
devtool
devtool 是 webpack 配置中用于控制生成 source map 方式的选项,主要用于调试代码。source map 可以映射编译后的代码回源文件,方便定位问题。
webpack devtool 配置详解
devtool
是 webpack 配置中用于控制生成 source map 方式的选项,主要用于调试代码。source map 可以映射编译后的代码回源文件,方便定位问题。
常见 devtool 值及适用场景
eval
- 使用
eval
包裹模块代码,生成速度最快 - 只能映射到转换后的代码,无法映射到源文件
- 适用于开发环境快速构建
module.exports = {devtool: 'eval'
}
eval-source-map
- 每个模块使用
eval
执行 - 生成完整的 source map 并作为 DataUrl 嵌入
- 构建速度较慢但质量高
- 适用于开发环境需要精确源映射
cheap-eval-source-map
- 类似 eval-source-map 但只映射行号
- 不映射列信息,构建速度更快
- 适用于开发环境折中方案
cheap-module-eval-source-map
- 类似 cheap-eval-source-map
- 但会映射 loader 转换前的源代码
- 推荐用于开发环境
source-map
- 生成完整独立的 source map 文件
- 质量最高但构建速度最慢
- 适用于生产环境调试
module.exports = {devtool: 'source-map'
}
hidden-source-map
- 生成 source map 但不添加引用注释
- 需要手动处理 source map 文件
- 适用于生产环境但不想暴露源文件
nosources-source-map
- 生成 source map 但不包含源代码
- 只能看到错误堆栈但无法查看代码
- 适用于生产环境部分保护源代码
选择建议
开发环境推荐:
eval-source-map
或cheap-module-eval-source-map
生产环境推荐:
source-map
或hidden-source-map
性能考虑:
- 带
eval
的选项构建更快 - 带
module
的选项能映射 loader 前代码 - 带
cheap
的选项忽略列映射
性能影响
不同 devtool 设置对构建和重建速度有显著影响。质量越高的 source map 生成时间越长。开发环境下需要在质量和速度间取得平衡。
// 开发环境推荐配置
module.exports = {devtool: 'cheap-module-eval-source-map',// 其他配置...
}// 生产环境推荐配置
module.exports = {devtool: 'source-map',// 其他配置...
}
注意事项
- 生产环境如需 source map 应考虑安全性
- 某些设置可能导致源文件暴露
- 大型项目应测试不同设置的构建速度
- 现代浏览器开发工具已很好支持各种 source map
module
在webpack中,module指的是项目中可被分割的最小功能单位。每个文件(如JavaScript、CSS、图片等)都被视为一个module,webpack通过分析这些module之间的依赖关系,构建依赖图(Dependency Graph),最终打包成浏览器可识别的静态资源。
module的类型
webpack支持多种类型的module,常见的有:
- JavaScript模块:通过import或require导入的JS文件。
- CSS模块:通过css-loader处理的样式文件。
- 图片/字体资源:通过file-loader或url-loader处理的静态资源。
- 第三方库:如lodash、jQuery等通过npm安装的依赖。
处理流程
module的处理流程
- 解析路径:webpack根据配置的resolve规则解析模块路径。
- 匹配规则:通过test正则匹配文件类型,调用对应的loader处理。
- 依赖分析:处理过程中发现新的依赖(如import语句),递归处理。
- 打包输出:最终将所有module合并为bundle文件。
module.rules
module.exports = {module: {rules: [{test: /\.js$/,use: 'babel-loader',exclude: /node_modules/},{test: /\.css$/,use: ['style-loader', 'css-loader']}]}
};
module.use
用于指定处理特定文件类型时使用的 loader。它是一个数组,可以包含多个 loader,webpack 会从右到左(或从下到上)依次应用这些 loader。
常见loader的作用
- babel-loader:将ES6+代码转换为ES5。
- css-loader:解析CSS文件中的@import和url()。
- style-loader:将CSS注入到DOM中。
- file-loader:将文件输出到指定目录并返回URL。
注意事项
- loader 的执行顺序是从右到左(或从下到上),第一个 loader 会将结果传递给下一个 loader
- 对于需要选项的 loader,建议使用对象形式配置
- 复杂的 loader 链可以拆分成多个规则
- 在生产环境中,可能需要使用 MiniCssExtractPlugin.loader 替代 style-loader
module.type
module.type 用于定义模块的处理方式。
- asset/resource:专门用于处理文件资源(如图片、字体等),它会将文件直接输出到输出目录并返回最终的 URL。适用于需要直接引用文件路径而非文件内容的场景,例如:
- 图片文件(.png, .jpg, .svg)
- 字体文件(.woff, .ttf)
- 其他静态资源
- asset/inline:将文件内容作为 Data URL 嵌入(适用于小文件)。
- asset/source:将文件内容作为字符串返回(适用于文本文件)。
- asset:自动选择 resource 或 inline(默认阈值 8KB)。