webpack基础使用了解(入口、出口、插件、加载器、优化、别名、打包模式、环境变量、代码分割等)
目录
- 1、webpack简介
- 2、简单示例
- 3、入口(entry)和输出(output)
- 4、自动生成html文件
- 5、打包css代码
- 6、优化(单独提取css代码)
- 7、优化(压缩过程)
- 8、打包less代码
- 9、打包图片
- 10、搭建开发环境(webpack-dev-server)
- 11、打包模式
- 12、打包模式的应用
- 13、前端项目中注入环境变量
- 14、开发环境中使用 source map 调试
- 15、 解析别名(alias)
- 16、优化-生产环境下使用CDN
- 17、多页面打包
- 18、优化-分割公共代码
- 19、完整的示例代码
- 20、webpack打包和不打包的区别
- 21、webpack 打包原理和 Babel 的作用
- 22、插件(Plugin) 和 加载器(Loader)区别
以下代码根据 哔哩哔哩黑马程序员视频整理
1、webpack简介
更多内容和配置请查看webpack官网
2、简单示例
3、入口(entry)和输出(output)
-
新建配置文件:在项目根目录创建
webpack.config.js
文件,用于配置 Webpack 打包行为。 -
配置入口(
entry
):- 确定入口文件路径,使用
path.resolve
方法获取绝对路径,避免路径错误。 - 示例:
// 引入 Node.js 内置的 path 模块,用于处理文件路径,确保路径解析的正确性 const path = require('path'); module.exports = { // __dirname 表示当前文件(webpack.config.js)所在的目录路径,entry: path.resolve(__dirname, 'src/login/index.js'), // 入口文件路径 };
- 确定入口文件路径,使用
-
配置出口(
output
):path
:指定打包输出目录的绝对路径。filename
:定义输出文件的名称及路径(相对于path
)。- 示例:
module.exports = { //... output: { path: path.resolve(__dirname, 'dist'), // 输出目录 filename: './login/index.js' // 输出文件名及路径 } };
-
重新打包:执行打包命令(如
webpack
或自定义脚本),观察输出结果。只有与入口文件有直接或间接引入关系的模块才会被打包。
通过以上配置,可精准控制 Webpack 的打包入口和出口,确保项目资源按预期输出,提升构建效率与文件管理的规范性。
4、自动生成html文件
使用 html - webpack - plugin
自动生成 html
文件的步骤及配置示例,解析如下:
- 下载插件:
- 命令
npm i html - webpack - plugin --save - dev
,用于在项目中安装html - webpack - plugin
作为开发依赖,以便在 Webpack 打包时使用该插件生成html
文件。
- 命令
- 配置
webpack.config.js
:- 引入插件:
const HtmlWebpackPlugin = require('html - webpack - plugin')
。 - 在
module.exports
的plugins
数组中添加插件实例,通过template
指定模板文件(如./public/login.html
),通过filename
指定输出文件路径及名称(如./login/index.html
),使 Webpack 具备利用该插件处理html
文件的能力。
- 引入插件:
- 重新打包观察效果:
- 执行打包命令(如
webpack
),插件会根据配置,基于模板文件生成指定的html
输出文件,自动引入打包后的资源(如js
文件),无需手动创建或维护html
文件。
- 执行打包命令(如
这些步骤实现了在 Webpack 构建过程中自动生成 html
文件,简化项目开发流程。
// 引入 html - webpack - plugin 插件,该插件用于在 Webpack 打包过程中自动生成 HTML 文件
const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = {// 其他配置(如 entry、output 等)可能在此处省略plugins: [// 创建 HtmlWebpackPlugin 的实例,配置生成 HTML 的相关选项new HtmlWebpackPlugin({// 指定模板文件的路径template: './public/login.html', // 指定生成的 HTML 输出文件的路径和名称// 该路径是相对于 Webpack 配置中 output.path 的目录filename: './login/index.html' })]
};
5、打包css代码
以下是对打包 CSS 代码相关内容的解析:
1. 加载器作用
- css - loader:主要负责解析 CSS 代码,例如处理
@import
和url()
等语句,将 CSS 文件转换为 JavaScript 模块,使其能被 Webpack 理解和处理。 - style - loader:把
css-loader
解析后的 CSS 代码以<style>
标签的形式插入到 HTML 的 DOM 中,从而让样式生效。
2. 操作步骤解析
- 步骤1:准备 CSS 文件代码并引入到
src/login/index.js
中(可能还会进行压缩转译等处理)。这一步是为后续的打包做准备,确保 CSS 代码能被项目所使用。 - 步骤2:使用
npm i css-loader style-loader --save -dev
下载css-loader
和style-loader
本地软件包。--save -dev
表示将其保存为开发依赖,因为这些加载器仅在开发和构建过程中使用,而不是在生产环境运行时使用。 - 步骤3:在
webpack.config.js
中进行配置,让 Webpack 拥有加载 CSS 的功能。以下是配置代码的详细注释:
module.exports = {//... 其他配置(如 entry、output 等,此处省略未展示部分)module: {rules: [{// test 字段用于匹配文件,这里 /\.css$/i 表示匹配所有以.css 结尾的文件,i 表示不区分大小写test: /\.css$/i, // use 字段指定使用的加载器,加载器的执行顺序是从右到左(从后往前)// 先使用 css-loader 解析 CSS 代码,再使用 style-loader 将解析后的代码插入到 DOM 中use: ["style-loader", "css-loader"], },],},
};
- 步骤4:执行打包命令后,观察打包效果,确保 CSS 样式在最终的页面中正确呈现。
3. 注意事项
Webpack 默认只识别 JavaScript 代码,所以对于 CSS 等其他类型的文件,需要通过相应的加载器来处理,使其能够被正确打包和使用。
6、优化(单独提取css代码)
插件作用
mini-css-extract-plugin
插件主要用于将 CSS 代码从 JavaScript 模块中提取出来,生成单独的 CSS 文件。这样做的好处是 CSS 文件可以被浏览器缓存,减少 JavaScript 文件的体积,提高页面加载性能。
操作步骤解析
- 下载软件包:使用
npm install --save -dev mini-css-extract-plugin
命令将该插件作为开发依赖安装到项目中。--save -dev
表示此插件仅在开发和构建过程中使用,而非生产环境。 - 配置
webpack.config.js
:- 首先引入插件:
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
,通过require
函数引入插件模块,并将其赋值给MiniCssExtractPlugin
变量。 - 然后在
module.rules
中配置 CSS 处理规则:
- 首先引入插件:
module.exports = {//... 其他配置(如 entry、output 等,此处省略未展示部分)module: {rules: [{test: /\.css$/i,// 之前使用 style - loader 和 css - loader,现在用 MiniCssExtractPlugin.loader 替代 style - loaderuse: [MiniCssExtractPlugin.loader, "css-loader"], },],},plugins: [// 实例化插件,启动插件功能new MiniCssExtractPlugin() ]
};
这里 test: /\.css$/i
用于匹配所有以 .css
结尾的文件,use
数组指定了处理 CSS 文件的加载器。MiniCssExtractPlugin.loader
会将 CSS 提取到单独文件,css-loader
负责解析 CSS 代码。同时,在 plugins
数组中实例化 MiniCssExtractPlugin
来启用插件功能。
3. 观察打包效果:重新执行 Webpack 打包命令,查看生成的文件中是否有单独的 CSS 文件,并且页面样式是否正常显示。
注意事项
mini-css-extract-plugin
不能和 style-loader
一起使用。因为 style-loader
是将 CSS 代码插入到 DOM 中,而该插件是将 CSS 提取成单独文件,二者功能冲突。
7、优化(压缩过程)
问题背景
在使用 mini-css-extract-plugin
等插件将 CSS 代码提取成单独文件后,CSS 代码未经过压缩处理,文件体积较大,影响页面加载性能,因此需要对其进行压缩。
插件作用
css-minimizer-webpack-plugin
插件专门用于在 Webpack 构建过程中压缩 CSS 代码,通过去除不必要的空格、注释、简化选择器和属性等方式,减小 CSS 文件的大小,从而加快页面的加载速度。
操作步骤解析
- 下载软件包:使用命令
npm install css-minimizer-webpack-plugin --save -dev
将该插件作为开发依赖安装到项目中。--save -dev
表明此插件仅在开发和构建阶段使用,而非在生产环境运行时使用。 - 配置
webpack.config.js
:- 首先引入插件:
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
,通过require
函数引入插件模块,并将其赋值给CssMinimizerPlugin
变量。 - 然后在
optimization.minimizer
数组中配置插件:
- 首先引入插件:
module.exports = {//... 其他配置(如 entry、output 等,此处省略未展示部分)optimization: {minimizer: [// 在 webpack@5 中,可以使用 `...` 语法来扩展现有的 minimizer(如 `terser-webpack-plugin`),// 确保 JS 代码也能被压缩处理(图中注释部分说明了这一点,若要启用可取消注释相关内容)new CssMinimizerPlugin(),],},
};
这里 optimization.minimizer
用于配置 Webpack 构建过程中的压缩器。将 CssMinimizerPlugin
的实例添加到 minimizer
数组中,即可在打包时对 CSS 代码进行压缩。
3. 观察打包效果:重新执行 Webpack 打包命令,查看生成的 CSS 文件大小是否减小,同时确认页面样式在压缩后是否正常显示。
8、打包less代码
加载器作用
less-loader
加载器的主要作用是将 Less 代码编译为 CSS 代码。Less 是一种 CSS 预处理器,它扩展了 CSS 的语法,增加了变量、Mixin、函数等功能,使得样式表的编写更加高效和易于维护。less-loader
能将这些扩展语法转换为浏览器可以识别的 CSS 代码。
操作步骤解析
- 准备 Less 代码:新建 Less 代码文件(例如设置背景图相关样式),并将其引入到
src/login/index.js
中。这一步是为了让 Webpack 能够找到并处理 Less 代码。 - 下载软件包:使用命令
npm i less less-loader --save -dev
下载less
和less-loader
本地软件包。less
是 Less 语言的核心库,less-loader
是 Webpack 用于处理 Less 的加载器,--save -dev
表示将它们作为开发依赖安装,即仅在开发和构建过程中使用。 - 配置
webpack.config.js
:
module.exports = {//... 其他配置(如 entry、output 等,此处省略未展示部分)module: {rules: [{test: /\.less$/i,// use 数组指定了处理 Less 文件的加载器,执行顺序从右到左(从后往前)// less - loader 先将 Less 代码编译为 CSS 代码,css - loader 解析 CSS 代码,// MiniCssExtractPlugin.loader 将 CSS 提取到单独文件(前提是已配置该插件用于提取 CSS)use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"] },],},
};
这里 test: /\.less$/i
用于匹配所有以 .less
结尾的文件,use
数组按照顺序依次使用不同的加载器对 Less 文件进行处理。
4. 观察打包效果:重新执行 Webpack 打包命令,查看打包后的结果,确认 Less 代码是否成功编译为 CSS 代码,并且页面样式是否正常显示。
注意事项
less-loader
需要配合 less
软件包使用,二者缺一不可。如果只安装了 less-loader
而没有安装 less
,在编译 Less 代码时会报错。
9、打包图片
- 资源模块:Webpack5 内置资源模块,可直接打包字体、图片等,无需额外 loader。
- 配置步骤:在
webpack.config.js
中配置规则,如通过test: /\.(png|jpg|jpeg|gif)$/i
匹配图片文件,type: 'asset'
启用资源模块,generator.filename
定义输出文件名(利用[hash]
对内容哈希计算,[ext]
保留原文件扩展名,[query]
保留查询参数)。 - 临界值判断:默认以 8KB 为临界值。大于 8KB 的图片会打包为单独文件并导出 URL 地址;小于 8KB 的图片则导出为
data URI
(base64 字符串),减少 HTTP 请求。
10、搭建开发环境(webpack-dev-server)
- 问题:修改代码后需重新打包才能查看运行效果,效率低。
- 开发环境配置:
- 作用:启动 Web 服务,自动检测代码变化并热更新到网页,且
dist
目录和打包内容在内存中,更新速度快。 - 步骤:
- 下载
webpack-dev-server
软件包到项目,命令为npm i webpack-dev-server --save -dev
。 - 设置模式为开发模式(
mode: 'development'
),并在package.json
中配置自定义命令(如"dev": "webpack serve --open"
,--open
可自动打开浏览器)。 - 使用
npm run dev
启动开发服务器,体验热更新效果。
- 下载
- 作用:启动 Web 服务,自动检测代码变化并热更新到网页,且
11、打包模式
12、打包模式的应用
- 需求:开发模式下用
style-loader
内嵌样式以加快速度,生产模式下提取 CSS 代码。 - 方案:
-
方案 1:直接在
webpack.config.js
配置导出函数,但局限性大(仅支持 2 种模式)。
-
方案 2:借助
cross-env
(跨平台通用)包区分环境:- 下载
cross-env
到项目:npm i cross-env --save -dev
。 - 在
package.json
中配置自定义命令,通过cross-env
设置参数(如NODE_ENV=production
或NODE_ENV=development
),参数会绑定到process.env
对象。 - 在
webpack.config.js
中根据process.env.NODE_ENV
区分环境,应用不同配置。 - 重新打包观察配置差异。
- 下载
-
方案 3:当多种模式差异性较大时,配置不同的
webpack.config.js
文件。
-
13、前端项目中注入环境变量
- 需求:开发模式下打印语句生效,生产模式下失效。
- 问题:
cross-env
设置的环境变量仅在Node.js
环境生效,前端代码无法直接访问process.env.NODE_ENV
。 - 解决方法:使用 Webpack 内置的
DefinePlugin
插件。该插件在编译时将前端代码中匹配的变量名替换为对应的值或表达式。 - 代码实现:
- 引入 Webpack:
const webpack = require('webpack')
。 - 在
webpack.config.js
的plugins
数组中添加DefinePlugin
实例:
这样,前端代码就能根据plugins: [new webpack.DefinePlugin({// 键为注入到前端 JS 代码中的全局变量名// 值通过 JSON.stringify 处理(确保值为字符串形式,符合前端代码规范)'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)}) ]
process.env.NODE_ENV
的值(如'development'
或'production'
)判断是否执行相应逻辑(如开发模式下的打印语句)。
- 引入 Webpack:
14、开发环境中使用 source map 调试
- 问题:代码压缩混淆后,无法准确定位源代码的行数和列数。
source map
的作用:能准确追踪error
和warning
在原始代码中的位置。- 设置方式:在
webpack.config.js
中配置devtool
选项,例如devtool: 'inline - source - map'
,该选项会将源码的位置信息一同打包在js
文件内。 - 注意事项:
source map
仅适用于开发环境,生产环境中不建议使用,以防止源码位置被轻易查看。
15、 解析别名(alias)
- 作用:配置模块解析规则,通过创建
import
引入路径的别名,简化模块引入,避免长路径或相对路径的不安全性。 - 实现方式:在
webpack.config.js
中配置resolve.alias
。例如,使用path.resolve(__dirname, 'src')
将别名@
指向项目的src
绝对路径。- 原引入方式:
import { checkPhone, checkCode } from '../src/utils/check.js'
(路径长且相对路径不够安全)。 - 配置别名后:
import { checkPhone, checkCode } from '@/utils/check.js'
(通过别名@
简化路径)。
- 原引入方式:
- 代码示例:
const config = {//...其他配置resolve: {alias: {'@': path.resolve(__dirname,'src') // 将 @ 映射到 src 目录的绝对路径}} }
通过这种配置,可使模块引入更简洁、安全,提升开发效率。
16、优化-生产环境下使用CDN
具体示例
-
使用模块语法判断
-
配置忽略的模块
-
使用参数
17、多页面打包
具体示例
18、优化-分割公共代码
Webpack 会自动分析模块依赖关系,将符合规则的公共代码提取到独立文件,减少重复代码,提升缓存利用率和打包效率。
19、完整的示例代码
webpack.config.js文件
const path = require('path'); // 用于处理文件路径的Node.js核心模块
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 生成HTML文件并自动引入打包后的JS/CSS资源
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // 生产环境中将CSS提取为独立文件(替代style-loader)
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); // 优化压缩CSS代码(配合terser-webpack-plugin)
const webpack = require('webpack'); // 引入Webpack核心模块,用于使用内置插件(如DefinePlugin)const config = {// 打包模式(development/production,通过命令行参数覆盖配置文件)// mode: 'development', // 开发模式默认开启调试相关配置(如eval-source-map)// 多入口配置(每个页面单独打包)entry: {// 键名对应最终生成的chunk名称,值为入口文件绝对路径'login': path.resolve(__dirname, 'src/login/index.js'), // 登录页面入口'content': path.resolve(__dirname, 'src/content/index.js'), // 内容页面入口'publish': path.resolve(__dirname, 'src/publish/index.js') // 发布页面入口},// 输出配置output: {path: path.resolve(__dirname, 'dist'), // 打包输出的根目录(绝对路径)filename: './[name]/index.js', // 输出文件名模板:[name]对应entry的键名(如login/index.js)clean: true // 打包前自动清空output.path目录(避免残留旧文件)},// 插件配置(增强Webpack功能)plugins: [// 登录页HTML模板处理new HtmlWebpackPlugin({template: path.resolve(__dirname, 'public/login.html'), // 源HTML模板文件路径filename: path.resolve(__dirname, 'dist/login/index.html'), // 生成的HTML文件路径useCdn: process.env.NODE_ENV === 'production', // 生产环境启用CDN资源(通过模板变量控制)chunks: ['login'] // 仅引入当前entry对应的chunk(避免引入其他页面的JS)}),// 内容页HTML模板处理(结构同上)new HtmlWebpackPlugin({template: path.resolve(__dirname, 'public/content.html'),filename: path.resolve(__dirname, 'dist/content/index.html'),useCdn: process.env.NODE_ENV === 'production',chunks: ['content']}),// 发布页HTML模板处理(结构同上)new HtmlWebpackPlugin({template: path.resolve(__dirname, 'public/publish.html'),filename: path.resolve(__dirname, 'dist/publish/index.html'),useCdn: process.env.NODE_ENV === 'production',chunks: ['publish']}),// CSS提取插件(生产环境生效)new MiniCssExtractPlugin({filename: './[name]/index.css' // 生成的CSS文件名(与JS文件路径对应)}),// 环境变量注入插件(将Node环境变量传递到前端代码)new webpack.DefinePlugin({// 使用JSON.stringify确保值为字符串形式(符合JS语法)'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)})],// 模块加载器配置(处理非JS文件)module: {rules: [// CSS文件处理规则{test: /\.css$/i, // 匹配所有.css文件(i表示不区分大小写)// 根据环境选择不同的加载器:开发环境用style-loader(内联样式),生产环境用MiniCssExtractPlugin.loader(提取文件)use: [process.env.NODE_ENV === 'development' ? 'style-loader' : MiniCssExtractPlugin.loader, "css-loader"]},// Less文件处理规则(支持CSS预处理器){test: /\.less$/i, // 匹配所有.less文件use: [// 同上:环境区分CSS加载方式process.env.NODE_ENV === 'development' ? 'style-loader' : MiniCssExtractPlugin.loader,'css-loader', // 解析CSS文件中的@import和url()'less-loader' // 将Less代码编译为CSS],},// 图片文件处理规则(Webpack5内置资源模块){test: /\.(png|jpg|jpeg|gif)$/i, // 匹配常见图片格式type: 'asset', // 自动根据文件大小选择处理方式(<8KB转base64,否则生成独立文件)generator: {filename: 'assets/[hash][ext][query]' // 输出文件名:哈希值+原扩展名+查询参数}}],},// 优化配置(生产环境关键优化)optimization: {// 压缩器配置(支持JS/CSS压缩)minimizer: [// 保留默认JS压缩器(terser-webpack-plugin,Webpack5内置)// `...` 展开运算符表示保留原有minimizer配置`...`,new CssMinimizerPlugin(), // 单独配置CSS压缩器(配合默认JS压缩器工作)],// 代码分割配置(核心优化点)splitChunks: {chunks: 'all', // 对所有模块(同步/异步/初始加载)进行公共代码分析cacheGroups: { // 缓存组(自定义分割规则)commons: { // 公共模块分组(抽取多个页面共享的代码)minSize: 0, // 允许分割任意大小的模块(覆盖默认30KB限制)minChunks: 2, // 模块被引用至少2次才进行分割reuseExistingChunk: true, // 重用已存在的chunk(避免重复生成)// 动态生成chunk名称:基于引用该模块的所有chunk名称拼接name(module, chunks, cacheGroupKey) { const allChunksNames = chunks.map((item) => item.name).join('~'); // 格式:chunk名1~chunk名2return `./js/${allChunksNames}`; // 输出路径:dist/js/[chunk名1~chunk名2].js}}}}},// 模块解析配置(简化路径引用)resolve: {// 路径别名配置(避免使用复杂相对路径)alias: {'@': path.resolve(__dirname, 'src') // 用@符号代替src目录绝对路径(如import '@/utils/xxx')}}
};// 开发环境配置(仅在NODE_ENV=development时生效)
if (process.env.NODE_ENV === 'development') {config.devtool = 'inline-source-map'; // 启用内联source map(方便调试,显示原始代码位置)
}// 生产环境配置(仅在NODE_ENV=production时生效)
if (process.env.NODE_ENV === 'production') {// 外部扩展配置(排除指定库的打包,通过CDN引入)config.externals = {// 键:import语句中的模块名,值:全局变量名(需与CDN暴露的变量一致)'bootstrap/dist/css/bootstrap.min.css': 'bootstrap', // 引导CSS(假设全局变量为bootstrap)'axios': 'axios', // axios库(全局变量axios)'form-serialize': 'serialize', // form-serialize库(全局变量serialize)'@wangeditor/editor': 'wangEditor' // 王编辑器(全局变量wangEditor)}
}module.exports = config; // 导出完整配置对象
代码说明:
- 多入口配置:针对不同页面(登录/内容/发布)设置独立入口,生成对应的HTML和JS/CSS文件
- 环境区分:通过
process.env.NODE_ENV
动态切换开发/生产环境配置(如CSS加载方式、source map、外部扩展) - 公共代码分割:通过
splitChunks.commons
规则,自动提取被多个页面引用的公共模块(如工具函数、公共组件) - 资源处理:
- CSS/Less:开发环境内联样式提升速度,生产环境提取独立文件并压缩
- 图片:使用Webpack5内置
asset
模块自动处理base64嵌入和独立文件生成
- 性能优化:
clean: true
确保输出目录无残留文件externals
排除第三方库打包,减少最终包体积(配合CDN使用)splitChunks
提升缓存利用率(公共代码变更时仅需重新打包该部分)
使用建议:
- 开发环境通过
npm run dev
启动(需配置webpack-dev-server
) - 生产环境通过
NODE_ENV=production npm run build
打包(需确保CDN资源已正确引入) - 可根据实际需求调整
splitChunks.minChunks
(公共模块引用次数阈值)和minSize
(文件大小阈值)
package.json文件
{"name": "","version": "1.0.0","description": "","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 --open --mode=development"},"keywords": [],"author": "","license": "ISC","devDependencies": {"cross-env": "^7.0.3","css-loader": "^6.7.3","css-minimizer-webpack-plugin": "^5.0.0","html-webpack-plugin": "^5.5.1","less": "^4.1.3","less-loader": "^11.1.0","mini-css-extract-plugin": "^2.7.5","style-loader": "^3.3.2","webpack": "^5.82.0","webpack-cli": "^5.1.1","webpack-dev-server": "^4.15.0"},"dependencies": {"@wangeditor/editor": "^5.1.23","axios": "^1.4.0","bootstrap": "^5.2.3","form-serialize": "^0.7.2"}
}
20、webpack打包和不打包的区别
- 运行效率:
- 不打包时,浏览器需逐个请求众多模块文件,HTTP 请求次数多,加载速度慢。尤其在现代项目模块繁杂的情况下,效率低下。
- Webpack 打包将多个模块合并为少量文件,减少 HTTP 请求次数。同时,打包过程可压缩代码(如去除冗余字符、优化代码结构),减小文件体积,显著提升浏览器加载与运行效率。
- 对基础的支持:
- 不打包时,浏览器可能无法识别现代前端的新特性(如 ES6+ 的
import/export
模块语法)及预处理文件(如less
、scss
),导致无法正确解析运行。 - Webpack 可通过
loader
对代码进行转换处理,例如:用babel - loader
将 ES6+ 代码转译为兼容旧浏览器的代码;用css - loader
、less - loader
处理样式文件;用资源模块处理图片、字体等。通过这些方式,确保项目在不同环境中正常运行,增强对各类基础的支持。
- 不打包时,浏览器可能无法识别现代前端的新特性(如 ES6+ 的
总结区别:
- 运行效率:Webpack 打包减少 HTTP 请求、压缩文件,提升加载与运行速度;不打包则因请求多、文件未优化,效率低。
- 对基础的支持:Webpack 打包通过
loader
转换代码与资源,支持现代前端特性与复杂资源;不打包时,浏览器对新特性和特殊资源支持不足,可能导致项目无法正常运行。
21、webpack 打包原理和 Babel 的作用
webpack 打包原理:
Webpack 将 JavaScript、CSS、图像等都视为模块,通过 import
/require
语句建立模块间的依赖关系。从入口文件出发,递归解析依赖的所有模块,将它们打包成少量文件(如 bundle.js
)。打包过程中:
- 支持代码分割,把
bundle
拆分为多个小文件,实现异步按需加载,提升性能。 - 若某模块被多个文件引用,仅生成一个文件,避免重复。
- 未被调用的文件、变量和方法不会被打包,减少冗余。
- 多入口场景下,若不同入口引入相同代码,可借助插件(如
SplitChunksPlugin
)抽离到公共文件,优化重复代码。
Babel 的作用:
Babel 是一个 JavaScript 编译器,核心功能是将现代 JavaScript 代码(如 ES6+ 的 let
、const
、箭头函数、对象展开运算符等)转换为旧浏览器或环境能理解的 ES5 等兼容语法,解决新语法的兼容性问题。通过配置插件和预设(如 @babel/preset - env
),还能支持对 JSX(用于 React)、装饰器等特殊语法的转换,确保代码在不同环境中稳定运行。
22、插件(Plugin) 和 加载器(Loader)区别
一、核心定义与功能
- 加载器(Loader)
-
定义:
加载器是用于 处理特定类型文件 的转换器,将浏览器无法直接识别的模块(如 CSS、Less、图片、字体等)转换为 Webpack 能够处理的模块
。 -
核心功能:
- 文件转换:将非 JS 文件转换为 JS 可识别的模块(或直接转换为最终可执行的代码/资源)。
- 单模块处理:仅针对单个模块的内容进行处理(如将
.vue
文件拆分为 JS/CSS/HTML,将 Less 编译为 CSS)。
-
典型场景:
babel-loader
:将 ES6+ 语法转换为 ES5 兼容代码。css-loader
:解析 CSS 文件中的@import
和url()
依赖。image-loader
:压缩图片并生成 URL 路径。
- 插件(Plugin)
-
定义:
插件是用于 扩展 Webpack 构建流程 的功能模块,通过监听 Webpack 的生命周期钩子(如编译开始
、文件生成后
等),在构建过程中执行自定义逻辑。 -
核心功能:
- 全局构建控制:处理构建过程中的全局逻辑(如生成 HTML、提取 CSS、代码压缩、环境变量注入等)。
- 多模块协作:操作多个模块之间的关系(如代码分割、资源优化、错误处理等)。
-
典型场景:
HtmlWebpackPlugin
:根据模板生成 HTML 文件并自动引入打包后的 JS/CSS。MiniCssExtractPlugin
:将 CSS 从 JS 中提取为独立文件(生产环境常用)。TerserPlugin
:压缩 JS 代码(Webpack 5 内置)。
二、核心区别对比
特性 | 加载器(Loader) | 插件(Plugin) |
---|---|---|
作用对象 | 单个模块文件(如 .js 、.css 、.vue ) | 整个构建流程(处理模块间关系或全局任务) |
处理阶段 | 模块加载时(在 module.rules 中配置) | 构建生命周期的各个钩子阶段(通过 plugins 数组配置) |
核心目标 | 文件转换(让 Webpack 识别非 JS 模块) | 扩展构建功能(优化、压缩、资源管理等全局操作) |
使用方式 | 在 module.rules 中通过 test 匹配文件类型,按顺序调用 use 中的加载器 | 在 plugins 中实例化插件类(可传入配置参数) |
典型配置位置 | webpack.config.js 中的 module.rules 字段 | webpack.config.js 中的 plugins 数组 |
输出结果 | 转换后的模块内容(供 Webpack 继续处理) | 无直接输出,影响构建流程或生成额外资源(如 HTML) |
三、协作关系
-
加载器是模块处理的“转换器”:
当 Webpack 解析到一个模块(如import './style.css'
),会根据module.rules
匹配对应的加载器,按顺序调用(如先css-loader
解析依赖,再style-loader
内联样式到 HTML)。 -
插件是构建流程的“控制器”:
插件在加载器处理完模块后介入,例如:MiniCssExtractPlugin
会将css-loader
处理后的 CSS 从 JS 中提取为独立文件(替代style-loader
的内联方式)。HtmlWebpackPlugin
会根据所有打包后的 JS/CSS 生成最终的 HTML 模板。
四、示例对比
- 加载器示例:处理 CSS 文件
// webpack.config.js
module.rules = [{test: /\.css$/, // 匹配 CSS 文件use: ['style-loader', // 将 CSS 内联到 HTML 样式标签(开发环境)'css-loader' // 解析 CSS 中的 @import 和 url()]}
];
- 插件示例:提取 CSS 为独立文件
// webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');plugins: [new MiniCssExtractPlugin({filename: 'css/[name].[contenthash].css' // 生产环境生成独立 CSS 文件})
];// 配合加载器使用(替换 style-loader)
use: [MiniCssExtractPlugin.loader, // 插件提供的加载器,用于提取 CSS'css-loader'
]
五、总结
- 加载器(Loader):专注于 单个文件的内容转换,是模块级的“翻译官”(如将 Less 转 CSS,ES6 转 ES5)。
- 插件(Plugin):专注于 构建流程的全局控制,是构建过程的“指挥官”(如生成 HTML、分离公共代码、压缩资源)。
两者相辅相成:Loader 处理基础文件转换,Plugin 实现高级构建功能,共同完成复杂的前端工程化需求。
相关文章:
webpack基础使用了解(入口、出口、插件、加载器、优化、别名、打包模式、环境变量、代码分割等)
目录 1、webpack简介2、简单示例3、入口(entry)和输出(output)4、自动生成html文件5、打包css代码6、优化(单独提取css代码)7、优化(压缩过程)8、打包less代码9、打包图片10、搭建开发环境(webpack-dev-server…...
【项目】基于MCP+Tabelstore架构实现知识库答疑系统
基于MCPTabelstore架构实现知识库答疑系统 整体流程设计(一)Agent 架构(二)知识库存储(1)向量数据库Tablestore(2)MCP Server (三)知识库构建(1&a…...
C语言高频面试题——malloc 和 calloc区别
在 C 语言中,malloc 和 calloc 都是用于动态内存分配的函数,但它们在 内存初始化、参数形式 和 使用场景 上有显著区别。以下是详细的对比分析: 1. 函数原型 malloc void* malloc(size_t size);功能:分配 未初始化 的连续内存块…...
深入探讨JavaScript性能瓶颈与优化实战指南
JavaScript作为现代Web开发的核心语言,其性能直接影响用户体验与业务指标。随着2025年前端应用的复杂性持续增加,性能优化已成为开发者必须掌握的核心技能。本文将从性能瓶颈分析、优化策略、工具使用三个维度,结合实战案例,系统梳理JavaScript性能优化的关键路径。 一、Ja…...
[创业之路-376]:企业法务 - 创业,不同的企业形态,个人承担的风险、收益、税费、成本不同
在企业法务领域,创业时选择不同的企业形态,个人在风险承担、收益分配、税费负担及运营成本方面存在显著差异。以下从个人独资企业、合伙企业、有限责任公司、股份有限公司四种常见形态展开分析: 一、个人承担的风险 个人独资企业 风险类型&…...
【Lua】Lua 入门知识点总结
Lua 入门学习笔记 本教程旨在帮助有编程基础的学习者快速入门Lua编程语言。包括Lua中变量的声明与使用,包括全局变量和局部变量的区别,以及nil类型的概念、数值型、字符串和函数的基本操作,包括16进制表示、科学计数法、字符串连接、函数声明…...
低空经济 WebGIS 无人机配送 | 图扑数字孪生
2024 年,”低空经济” 首次写入政府工作报告,在政策驱动下各地纷纷把握政策机遇,从基建网络、场景创新、产业生态、政策激励等方面,构建 “规划-建设-应用-赋能” 的系统性布局,作为新质生产力的重要体现,推…...
【程序员 NLP 入门】词嵌入 - 如何基于计数的方法表示文本? (★小白必会版★)
🌟 嗨,你好,我是 青松 ! 🌈 希望用我的经验,让“程序猿”的AI学习之路走的更容易些,若我的经验能为你前行的道路增添一丝轻松,我将倍感荣幸!共勉~ 【程序员 NLP 入门】词…...
基于机器学习的多光谱遥感图像分类方法研究与定量评估
多光谱遥感技术通过获取可见光至红外波段的光谱信息,为地质勘探、农业监测、环境调查等领域提供了重要支持。与普通数码相机相比,多光谱成像能记录更丰富的波段数据(如近红外、短波红外等),从而更精准地识别地物特征。…...
BEVDepth: Acquisition of Reliable Depth for Multi-View 3D Object Detection
背景 基于多视角图片的3D感知被LSS证明是可行的,它使用估计的深度将图像特征转化为3D视椎,再将其压缩到BEV平面上。对于这个得到的BEV特征图,它支持端到端训练以及各种下游任务。但是对于深度估计这一块学习的深度质量如何,到目前为止没有相关工作研究。 贡献 本文的贡献…...
【Linux】静态库 动态库
🌻个人主页:路飞雪吖~ 🌠专栏:Linux 目录 一、👑静态库和动态库 静态库: 动态库: 🌠手动制作静态库 && 手动调用一下我们自己写的静态库 1> 安装到系统里面 ✨生成静…...
Java转Go日记(六):TCP黏包
服务端代码如下: // socket_stick/server/main.gofunc process(conn net.Conn) {defer conn.Close()reader : bufio.NewReader(conn)var buf [1024]bytefor {n, err : reader.Read(buf[:])if err io.EOF {break}if err ! nil {fmt.Println("read from client…...
(51单片机)LCD显示温度(DS18B20教程)(LCD1602教程)(延时函数教程)(单总线教程)
演示视频: LCD显示温度 源代码 如上图将9个文放在Keli5 中即可,然后烧录在单片机中就行了 烧录软件用的是STC-ISP,不知道怎么安装的可以去看江科大的视频: 【51单片机入门教程-2020版 程序全程纯手打 从零开始入门】https://www.…...
【通过Docker快速部署Tomcat9.0】
文章目录 前言一、部署docker二、部署Tomcat2.1 创建存储卷2.2 运行tomcat容器2.3 查看tomcat容器2.4 查看端口是否监听2.5 防火墙开放端口 三、访问Tomcat 前言 Tomcat介绍 Tomcat 是由 Apache 软件基金会(Apache Software Foundation)开发的一个开源 …...
云原生--基础篇-3--云原生概述(云、原生、云计算、核心组成、核心特点)
1、什么是云和原生 (1)、什么是云? “云”指的是云计算环境,代表应用运行的基础设施和资源。依赖并充分利用云计算的弹性、分布式和资源池化能力。 核心含义: 1、云计算基础设施 云原生应用的设计和运行完全基于云…...
Spark-Streaming
Spark-Streaming概述 DStream实操 案例一:WordCount案例 需求:使用 netcat 工具向 9999 端口不断的发送数据,通过 SparkStreaming 读取端口数据并统计不同单词出现的次数 实验步骤: 添加依赖 <dependency> <gro…...
乐视系列玩机------乐视2 x620红灯 黑砖刷写教程以及新版刷写工具的详细释义
乐视x620在上期解析了普通黑砖情况下的救砖刷机过程。但在一些例外的情况下。使用上面的步骤会一直刷写报错 。此种情况就需要另外一种强制刷写方法来救砖 通过博文了解💝💝💝 1💝💝💝-----详细解析乐视2 x620系列 红灯 黑砖线刷救砖的步骤 2💝💝💝----图…...
若依SpringCloud项目-定制微服务模块
若依SpringCloud项目-定制微服务模块 关于微服务先不过多介绍,刚开始熟悉并不能讲的很彻底,成熟的微服务项目-若依SpringCloud就是一个典型的微服务架构工程(网上有很多教程了,不明白的可以学习一下)。 我正在看的视…...
【扫描件批量改名】批量识别扫描件PDF指定区域内容,用识别的内容修改PDF文件名,基于C++和腾讯OCR的实现方案,超详细
批量识别扫描件PDF指定区域内容并重命名文件方案 应用场景 本方案适用于以下场景: 企业档案数字化管理:批量处理扫描的合同、发票等文件,按内容自动分类命名财务票据处理:自动识别票据上的关键信息(如发票号码、日期)用于归档医疗记录管理:从扫描的检查报告中提取患者I…...
学习Docker遇到的问题
目录 1、拉取hello-world镜像报错 1. 检查网络连接 排查: 2. 配置 Docker 镜像加速器(推荐) 具体解决步骤: 1.在服务器上创建并修改配置文件,添加Docker镜像加速器地址: 2. 重启Docker 3. 拉取hello-world镜像 2、删除镜像出现异常 3、 容器内部不能运行ping命令 …...
Docker 数据卷
目录 一、数据卷(Data Volume) 二、使用 1、单独建立数据卷 2、挂载主机数据卷 3、数据卷容器挂载 基本语法: 工作原理: 主要用途: 使用事例: 一、数据卷(Data Volume) 数据卷的使用,类似于 Linux 下对目录或文件进行 mount 数据卷(Data Volume)是一个可供一个或多…...
【数据结构】励志大厂版·初级(二刷复习)双链表
前引:今天学习的双链表属于链表结构中最复杂的一种(带头双向循环链表),按照安排,我们会先进行复习,如何实现双链表,如基本的头插、头删、尾删、尾插,掌握每个细节,随后进…...
通过dogssl申请ssl免费证书
SSL证书作为实现HTTPS加密的核心工具,能够确保用户与网站之间的数据传输安全。尤其是在小程序之类的开发时,要求必须通过https发起请求的情况下。学会如何免费申请一个ssl证书就很有必要了。这里我分享一下,我通过dogssl如何申请ssl的。 一&…...
路由与路由器
路由的概念 路由是指在网络通讯中,从源设备到目标设备路径的选择过程。路由器是实现这一过程的关键设备,它通过转发数据包来实现网络的互联。路由工作在OSI参考模型的第三层,‘网络层’。 路由器的基本原理 路由器通过维护一张路由表来决定…...
Docker底层原理浅析 | namespace+cgroups+文件系统
本文目录 1. Linux NamespaceLinux系统里是否只能有一个pid为1的进程?namespace机制查看namespacenamespace机制测试使用Docker验证namespace机制 2. Dcoerk网络模式3.Control groups4.文件系统(联合文件系统)5. 容器格式 1. Linux Namespace…...
【无人机】使用扩展卡尔曼滤波 (EKF) 算法来处理传感器测量,各传感器的参数设置,高度数据融合、不同传感器融合模式
目录 #1、IMU #2、磁力计 #3、高度 #典型配置 #4、气压计 #静压位置误差修正 #气压计偏置补偿 #5、全球导航系统/全球定位系统--GNSS/GPS #位置和速度测量 #偏航测量 #GPS 速度的偏航 #双接收器 #GNSS 性能要求 #6、测距 #条件范围辅助-Conditional range aidin…...
常见的raid有哪些,使用场景是什么?
RAID(Redundant Array of Independent Disks,独立磁盘冗余阵列)是一种将多个物理硬盘组合成一个逻辑硬盘的技术,目的是通过数据冗余和/或并行访问提高性能、容错能力和存储容量。不同的 RAID 级别有不同的实现方式和应用场景。以下…...
《 C++ 点滴漫谈: 三十四 》从重复到泛型,C++ 函数模板的诞生之路
一、引言 在 C 编程的世界里,类型是一切的基础。我们为 int 写一个求最大值的函数,为 double 写一个相似的函数,为 std::string 又写一个……看似合理的行为,逐渐堆积成了难以维护的 “函数墙”。这些函数逻辑几乎一致࿰…...
EasyRTC打造无人机低延迟高清实时通信监控全场景解决方案
一、方案背景 随着无人机技术的飞速发展,其在航拍、物流配送、农业监测、应急救援等多个领域的应用日益广泛。然而,无人机在实际作业过程中面临着诸多挑战,如通信延迟、数据传输不稳定、监控范围有限等。EasyRTC作为一种高效、低延迟的实时通…...
【MATLAB第117期】#源码分享 | 基于MATLAB的SSM状态空间模型多元时间序列预测方法(多输入单输出)
【MATLAB第117期】#源码分享 | 基于MATLAB的SSM状态空间模型多元时间序列预测方法(多输入单输出) 引言 本文使用状态空间模型实现失业率递归预测,状态空间模型(State Space Model, SSM)是一种用于描述动态系统行为的…...
关于大数据的基础知识(三)——数据安全与合规
成长路上不孤单😊😊😊😊😊😊 【14后😊///计算机爱好者😊///持续分享所学😊///如有需要欢迎收藏转发///😊】 今日分享关于大数据的基础知识(三&a…...
从信息泄露到内网控制
0x01 背景 之前常见用rce、文件上传等漏洞获取webshell,偶然遇到一次敏感信息泄露获取权限的渗透,简单记录一下过程。 0x02 信息泄露 发现系统某端口部署了minio服务,经过探测发现存在minio存储桶遍历 使用利用工具把泄露的文件全部整理一…...
【Qt】QDialog类
🌈 个人主页:Zfox_ 🔥 系列专栏:Qt 目录 一:🔥 对话框 - QDialog 🦋 基本介绍🦋 对话框分类🦋 Qt 内置对话框🎀 QMessageBox -消息对话框🎀 QColo…...
【Spring Boot基础】MyBatis的基础操作:增删查改、列名和属性名匹配 -- XML实现
MyBatis的基础操作 1. MyBatis XML配置文件1.1 简单介绍1.2 配置连接字符串和MyBatis1.3 XMl文件实现--分层1.4 XMl文件实现--举例 2.增删改查操作2.1 增(insert)2.1.1 不使用Param2.1.2 用Param2.1.3 返回自增键 2.2 删(delete)2…...
谷歌推出探索型推荐新范式:双LLM架构重塑用户兴趣挖掘
文章目录 1. 背景1.1 闭环困境1.2 谷歌的两次失败尝试1.2.1 尝试一:轻量微调1.2.2 尝试二:RLHF 强化学习微调 1.3 双LLM范式的提出1.3.1 模型1:Novelty LLM — 负责生成“探索方向”1.3.2 模型2:Alignment LLM — 负责评估“相关性…...
Linux kernel signal原理(下)- aarch64架构sigreturn流程
一、前言 在上篇中写到了linux中signal的处理流程,在do_signal信号处理的流程最后,会通过sigreturn再次回到线程现场,上篇文章中介绍了在X86_64架构下的实现,本篇中介绍下在aarch64架构下的实现原理。 二、sigaction系统调用 #i…...
使用 LangChain + Higress + Elasticsearch 构建 RAG 应用
RAG(Retrieval Augmented Generation,检索增强生成) 是一种结合了信息检索与生成式大语言模型(LLM)的技术。它的核心思想是:在生成模型输出内容之前,先从外部知识库或数据源中检索相关信息&…...
【Linux】46.网络基础(3.3)
文章目录 5. 其他重要协议或技术5.1 DNS(Domain Name System)5.1.1 DNS背景5.1.2 域名简介 5.2 ICMP协议5.2.1 ICMP功能5.2.2 ICMP的报文格式5.2.3 ping命令5.2.4 一个值得注意的坑5.2.5 traceroute命令 5.3 NAT技术5.3.1 NAT技术背景5.3.2 NAT IP转换过程5.3.3 NAPT5.3.4 NAT技…...
【Unity笔记】Unity + OpenXR项目无法启动SteamVR的排查与解决全指南
图片为AI生成 一、前言 随着Unity在XR领域全面转向OpenXR标准,越来越多的开发者选择使用OpenXR来构建跨平台的VR应用。但在项目实际部署中发现:打包成的EXE程序无法正常启动SteamVR,或者SteamVR未能识别到该应用。本文将以“Unity OpenXR …...
【sylar-webserver】重构 增加内存池
文章目录 内存池设定结构ThreadCacheCentralCachePageCache allocatedeallocate测试 参考 https://github.com/youngyangyang04/memory-pool 我的代码实现见 https://github.com/star-cs/webserver 内存池 ThreadCache(线程本地缓存) 每个线程独立的内存…...
云账号安全事件分析:黑客利用RAM子账户发起ECS命令执行攻击
事件背景 某企业云监控系统触发高危告警,提示API请求中包含黑客工具特征(cf_framework),攻击者试图通过泄露的RAM子账户凭据调用ECS高危API。以下是攻击关键信息整理: 字段详情告警原因API请求包含黑客工具特征(cf_framework)攻击实体RAM子账户 mq泄露凭证AccessKey ID…...
Node.js 模块导入的基本流程
Node.js 模块导入的基本流程,主要是 CommonJS 模块加载机制(即使用 require())的内部执行步骤。下面我用清晰的结构给你梳理一下这个过程: ✅ Node.js 模块导入的基本流程(使用 require()) const someModu…...
Unitest和pytest使用方法
unittest 是 Python 自带的单元测试框架,用于编写和运行可重复的测试用例。它的核心思想是通过断言(assertions)验证代码的行为是否符合预期。以下是 unittest 的基本使用方法: 1. 基本结构 1.1 创建测试类 继承 unittest.TestC…...
wps批量修改字体
选择这个小箭头 找到需要修改的字体如正文,右击修改选择合适的字体确定即可...
【Linux网络】各版本TCP服务器构建 - 从理解到实现
📢博客主页:https://blog.csdn.net/2301_779549673 📢博客仓库:https://gitee.com/JohnKingW/linux_test/tree/master/lesson 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! &…...
航电系统多模态融合技术要点
一、技术要点 1. 多模态数据特性分析 异构数据对齐:需处理不同传感器(如雷达、摄像头、IMU、ADS-B等)在时间、空间、精度和采样率上的差异,需设计同步机制(如硬件时钟同步、软件插值对齐)。 数据预处…...
【Git】branch合并分支
在 Git 中,将分支合并到 main 分支是一个常见的操作。以下是详细的步骤和说明,帮助你完成这个过程。 1. 确保你在正确的分支上 首先,你需要确保当前所在的分支是 main 分支(或者你要合并到的目标分支)。 检查当前分支…...
uniapp-商城-33-shop 布局搜索页面以及u-search
shop页面上有一个搜索,可以进行商品搜索,这里我们先做一个页面布局,后面再来进行数据i联动。 1、shop页面的搜索 2、搜索的页面代码 <navigator class"searchView" url"/pagesub/pageshop/search/search"> …...
蓝桥杯常考的找规律题
目录 灵感来源: B站视频链接: 找规律题具有什么样的特点: 报数游戏(Java组): 题目描述: 题目链接: 思路详解: 代码详解: 阶乘求和(Java组…...
全球化2.0 | 云轴科技ZStack亮相2025香港国际创科展
4月13-16日,由香港特别行政区政府、香港贸发局主办的2025香港国际创科展(InnoEX)在香港会议展览中心举办,作为亚洲最具影响力的科技盛会之一,本届展会吸引了来自17个国家和地区的500余家顶尖科技企业、科研机构及行业先…...