webpack & vite

前端工程化:
开发环境
1)准备阶段:技术选型;规范(分支规范、UI规范)
2)开发阶段:开发、打包;测试(mocha、jest、Cypress 测试用例保证代码质量)
3)发布阶段:CI/CD持续集成和部署、docker、nginx
开发体验
前端:基础数据FCP、LCP;异常数据 接口异常、脚本异常;资源 白屏率、秒开率(performance API)
utils:业务API 业务组件 环境兼容
core:全局配置 数据处理 埋点上报

一、webpack

1、前端代码为什么要进行构建和打包?

1)模块化开发

2)编译高级语法(less、scss、ES6+、JSX、TS)
Babel转译:将 ES6+/TS/JSX 转换为 ES5 代码;Polyfill:Babel默认只转换新的JS句法,不转换新的API,如Iterator、Generator、Set、Map、Promise等全局对象,以及一些定义在全局对象上的方法如Object.assign;Css预处理

3)性能优化
代码压缩:压缩 JS、 CSS;Tree Shaking:删除未使用的代码(依赖 ESM 静态分析);代码分割(Code Splitting):拆分包,按需加载(如路由懒加载);缓存策略:生成 [contenthash] 文件名,利用浏览器缓存

4)开发体验
热更新(HMR):修改代码后局部更新,保留应用状态;Dev Server:提供本地开发环境(如 webpack-dev-server);Source Map:调试压缩后的代码时定位到源码

5)其他
资源管理与自动化:Loader 处理资源、HTML 中自动引入打包后的 JS/CSS;工程化与团队协作:Lint 工具、TS类型检查、CI/CD 集成;框架支持:React、vue等
统一高效的开发环境,统一的构建流程和产出标准,集成公司构建规范(提测、上线)

2、基本配置

Entry入口:指定打包的起点文件(如 src/index.js)
Output输出:定义打包后的文件存放位置(如 dist/main.js)
Loaders加载器:处理不同类型的文件
处理ES6 babel-loader
处理样式 style-loader css-loader less-loader postcss-loader(loader执行顺序从后往前)
处理图片 file-loader url-loader
Plugins插件:扩展功能(如 HTML 生成、代码压缩)
Mode模式:development(开发)或 production(生产)
环境管理:DefinePlugin 注入变量,区分 development 和 production
扩展能力:自定义Loader和Plugin

3、常见的loader和plugin?区别?

常见的loader如下

  • babel-loader/swc-loader:转译 ES6+/JSX/TypeScript → ES5
  • css-loader:解析 CSS 中的 @import 和 url(),处理模块化 CSS
  • style-loader:将 CSS 注入到 DOM(通过 style 标签),生产环境用MiniCssExtractPlugin.loader
  • sass-loader/less-loader:编译 SCSS/SASS/LESS → CSS
  • postcss-loader:处理 CSS 兼容性(如自动添加前缀)
  • file-loader:将文件(如图片/字体)输出到 dist 目录,返回文件URL
  • url-loader:小文件转为 Base64 内联,大文件交给 file-loader
  • raw-loader:允许将文件处理成一个字符串导入
    (file-loader、url-loader、raw-loader在webpack5被取代,type: asset/source功能相当于 raw-loader;asset/inline功能相当于url-loader;asset/resource功能相当于file-loader;asset默认会根据文件大小来选择使用哪种类型,当文件小于 8 KB 的时候会使用 asset/inline,否则会使用 asset/resource,也可手动进行阈值的设定)

常见的plugin如下

  • HtmlWebpackPlugin:打包结束后,自动生成一个html文件,并把打包生成的js模块引入该html中
  • mini-css-extract-plugin:提取css到一个单独的文件中
  • DefinePlugin:允许在编译时创建配置的全局对象,是一个webpack内置插件,不需要安装
  • ReactRefreshWebpackPlugin:Webpack 配置中用于启用 React 组件热更新(HMR)的插件配置
  • SplitChunksPlugin:用于优化代码分割的核心插件
  • css-minimizer-webpack-plugin:css压缩
  • terser-webpack-plugin:js压缩
  • ImageMinimizerWebpackPlugin:图片压缩

区别
loader模块转换器,处理单个文件(转换、编译)(在 webpack内部,任何文件都是模块,不仅仅只是 js文件。默认情况下,在遇到import或者require文件打包加载模块的时候, webpack只支持对js和json文件打包。像 css、 sass、png等这些类型的文件的时候,需要配置对应的loader进行文件内容的解析);loader在模块加载阶段执行(文件级别)

plugin扩展插件,扩展Webpack 整体功能(打包优化、资源管理、环境变量注入等);plugins干预构建流程的各个阶段(整个流程)

参考:常见的loader和plugin

4、module、chunk、bundle分别是什么?区别?

module(模块)各种源码文件,Webpack 将所有文件(包括 JS、CSS、图片等)视为模块,并通过依赖关系(如 import/require)构建依赖图;
chunk(代码块)构建过程中的中间产物,由一个或多个模块组成;
bundle(打包产物)chunk经过编译和打包后的最终输出文件(如 .js、.css),直接提供给浏览器运行的静态资源。

产生 Chunk 的场景
入口文件(Entry):每个入口文件生成一个 Chunk。
动态导入(Dynamic Import):import() 语法会自动生成新的 Chunk。
代码分割(SplitChunksPlugin):提取公共代码或第三方库到独立 Chunk。
在这里插入图片描述

5、webpack构建流程

初始化:合并配置、compiler、plugin registry。配置包括:优先级webapck.config.js.< npm script “start”: “webpack --XX” cli < env。从配置文件和 Shell语句中读取与合并参数,并初始化需要使用的插件和配置插件执行环境需要的参数。
编译构建 build:config、entry编译、loader针对源代码进行代码转换、AST、递归编译。从入口文件开始,针对每个Module调用对应的Loader,再找到该 Module依赖的Module,对每个依赖模块重复调用 loader 处理,递归地进行编译处理。loader 按配置顺序(从右到左、从下到上)处理模块。
生成 seal:chunk、assets。对编译后的Module组合成Chunk,把Chunk转换成文件最后输出
写入 emit
请添加图片描述

6、webpack性能优化

代码分割(Code Splitting):减少首屏加载时间,按需加载代码。包括:入口分割、动态导入、SplitChunksPlugin公共代码提取
缓存优化:[contenthash]
Tree shaking:删除未使用的代码
压缩代码:TerserPlugin等
懒加载(Lazy Loading):延迟加载非关键资源
预加载(Preload/Prefetch):Preload 立即加载关键资源;Prefetch 空闲时加载未来可能需要的资源
多进程并行处理

tree Shaking什么时候失效

tree shaking 用于消除代码中未使用的部分,依赖于ES Module的静态语法分析。
Tree Shaking 的触发条件:
1)静态模块:必须使用 ES6 模块语法(import/export)。CommonJS 的 require/module.exports 是动态的,无法被 Tree Shaking;import(‘./module.js’).then(…) 动态导入会导致整个模块无法被优化。
2)无副作用:Tree Shaking 只会移除没有副作用的代码。如果模块执行时会影响外部状态(如修改全局变量、DOM 操作),则不会被移除。
3)未被引用:未被其他模块引用的代码才会被移除。
4)工具支持:Webpack/Rollup 等工具配置正确。
Webpack:
必须启用 production 模式(自动开启 Tree Shaking)。
使用 optimization.usedExports: true 标记未使用的导出。
package.json中使用 sideEffects: false 告诉 Webpack 哪些模块没有副作用。

code splitting

目的
减少首屏加载时间:只加载当前页面需要的代码。
优化缓存:独立模块可单独缓存,避免整体重新加载。
提高运行时性能:减少主线程阻塞时间。
实现方式
1)入口分割。手动配置多个入口,适用于多页面应用(MPA)

module.exports = {
  entry: {
    home: './src/home.js',
    about: './src/about.js',
  },
  output: {
    filename: '[name].[contenthash].js',
  },
};

2)动态导入,使用 import() 语法,ES6 动态导入(返回 Promise)

button.addEventListener('click', () => {
  import('./module.js').then(({ func }) => {
    func();
  });
});

3)懒加载组件(React/Vue 等框架)
React:使用 React.lazy 和 Suspense。
Vue:使用异步组件定义

const LazyComponent = React.lazy(() => import('./LazyComponent'));

function App() {
  return (
    <div>
      <React.Suspense fallback={<div>Loading...</div>}>
        <LazyComponent />
      </React.Suspense>
    </div>
  );
}

4)SplitChunks 插件(Webpack)
自动分割共享模块:提取公共依赖到单独的 chunk。
配置项:minSize、minChunks、cacheGroups 等。

module.exports = {
  optimization: {
    splitChunks: {
      chunks: 'all', // 分割所有类型的 chunks
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
        },
      },
    },
  },
};

最佳实践
优先使用动态导入:灵活且自动化程度高。
避免过度分割:过小的 chunks 会增加 HTTP 请求数。
预加载(Preload)与预取(Prefetch)

<!-- 预加载:当前页面急需的资源 -->
<link rel="preload" href="critical.js" as="script">

<!-- 预取:未来可能需要的资源 -->
<link rel="prefetch" href="optional.js">

使用分析工具 webpack-bundle-analyzer分析包大小

7、webpack5相比webpack4新增了哪些功能?

1)资源模块(Asset Modules):在 Webpack5 之前,一般都会使用raw-loader、file-loader、url-loader来处理一些常见的静态资源,比如 PNG 图片、SVG 图标等等。Webpack5 提供了内置的静态资源构建能力,取代了 file-loader/url-loader/raw-loader

module.exports = {
    ...,
    module: {
      rules: [
          {
            test: /\.(png|jpg|svg|gif)$/,
            type: 'asset/resource',
            generator: {
                // [ext]前面自带"."
                filename: 'assets/[hash:8].[name][ext]',
            },
        },
      ],
    },
}

2)内置 FileSystem Cache 能力加速二次构建:Webpack5 之前,我们会使用 cache-loader缓存一些性能开销较大的 loader ,或者是使用 hard-source-webpack-plugin为模块提供一些中间缓存。在 Webpack5 之后,默认就为我们集成了一种自带的缓存能力。

module.exports = {
    ...,
    cache: {
        type: 'filesystem',
        ...,
    },
}

3)更强大的 Tree Shaking 能力:Tree Shaking 能力,是指能够在打包的过程中移除 JavaScript 上下文中未被引用到的变量,借以次来减少打包后的体积。webpack已经默认开启了这个功能,无需其他配置,但是使用这个会有条件。webpack5支持嵌套的 tree-shaking、支持 CommonJS 的 tree-shaking、支持内部模块的 sideEffects 标记
4)移除/废弃功能:移除了 Node.js polyfills(需要手动添加)、弃用了 require.include(已完全移除)、移除了 IgnorePlugin 的某些用法(需要显式指定上下文)
5)长期缓存优化(Long term cache): 防止模块顺序变化导致ID变化,避免无关修改影响所有chunk的hash
6)Module Federation(模块联邦):支持微前端架构,跨应用共享模块
Webpack 5 的这些改进使得构建更快、输出更小、配置更简单
参考:Webpack5 新特性

8、webpack的热更新原理

热模块替换(Hot Module Replacement, HMR)允许在不完全刷新页面的情况下更新修改的模块
Webpack HMR 原理解析

9、webpack proxy工作原理?为什么能解决跨域?

中间服务器webpack-dev-server,将自动编译和自动刷新浏览器等一系列对开发友好的功能全部集成在一起,目的是伪类提高日常开发效率,只用在开发阶段。
devServer里面proxy是关于代理的配置,proxy ⼯作原理实质上是利⽤ http-proxy-middleware 这个 http 代理中间件,实现请求转发给其他服务器。
工作流程如下:
1)浏览器发送请求(受同源策略限制):前端代码请求 http://localhost:8080/api/users(本地开发服务器)。
2)webpack-dev-server 拦截请求:检测到 /api 匹配代理规则,于是 不直接返回数据,而是 转发请求 到 http://backend-server.com/api/users。
3)目标服务器返回数据:后端服务器(如 http://backend-server.com)处理请求,返回数据给 webpack-dev-server。
4)webpack-dev-server 返回数据给浏览器:浏览器接收到数据,认为请求是来自 http://localhost:8080,因此 不会触发跨域错误。

浏览器的 同源策略(Same-Origin Policy) 限制的是:前端页面(如 http://localhost:8080) 不能直接通过 XMLHttpRequest 或 fetch 访问 不同源(如 http://backend-server.com) 的 API。
但 代理服务器 不受此限制,因为:服务器之间没有跨域限制(同源策略仅适用于浏览器)。webpack-dev-server 作为中间代理,代替浏览器发送请求,拿到数据后再返回给前端,浏览器看到的是同源响应,因此不会报跨域错误。

Webpack DevServer Proxy:本地环境
nginx反向代理:生产环境

二、vite

为什么打包速度快

原生 ES 模块 (ESM) 支持
按需编译:开发服务器只编译当前页面需要的模块
预构建(Pre-Bundling)优化:使用 esbuild预构建依赖项,将 CommonJS/UMD 依赖转换为 ESM 格式;合并多个小文件减少网络请求(结果缓存到 node_modules/.vite,仅在依赖变化时重新构建)
高效的热更新
生产构建优化:开发用 esbuild 实现极速体验;生产用 Rollup 保证最佳打包质量

vite config

resolve
devServer
build
optimizeDeps

Vite 的 HMR(热更新)是如何实现的?

Vite 的 HMR 基于原生 ESM 实现,核心流程:
服务器与浏览器通过 WebSocket 建立连接。
当文件修改时,服务器发送更新通知到浏览器。
浏览器接收更新后,仅替换变更的模块,保持应用状态。

Vite 如何处理 CSS、TypeScript 和静态资源

  • CSS
    直接支持 import ‘./style.css’,自动处理路径和 HMR。
    内置 CSS Modules(.module.css)和 PostCSS 支持。
  • TypeScript
    无需 Babel,直接通过 esbuild 编译(仅类型检查,不转换语法)。
    需配合 tsconfig.json,但运行时依赖浏览器原生支持。
  • 静态资源
    自动处理资源导入(如 import img from ‘./logo.png’)。
    小于 4KB 的资源会内联为 Base64(可通过 build.assetsInlineLimit 配置)。

Vite Plugin

@vitejs/plugin-react:React 支持
@vitejs/plugin-vue:Vue 支持
vite-plugin-html:html优化
vite-plugin-image-optimizer:图片压缩
vite-plugin-compression:资源压缩
vite-plugin-remove-console:移除生产环境的console
rollup-plugin-visualizer:可视化分析打包结果
unplugin-auto-import:自动导入常用API

三、babel

babel介绍及配置用法解析

其他

pnpm、npm、yarn

npm 生态最成熟,锁文件package-lock.json
yarn 在大型项目中表现稳定,支持离线模式,锁文件yarn.lock
npm和yarn都采用扁平化依赖树(hoisting),会将依赖提升到顶层 node_modules,可能导致版本冲突。
pnpm 使用硬链接和符号链接的方式管理依赖,锁文件pnpm-lock.yaml。适合追求性能和磁盘空间优化、需要严格依赖隔离的项目,或使用 monorepo 架构的项目

性能对比

  • 安装速度:pnpm > yarn > npm(通常情况下)。pnpm 因共享依赖存储,重复安装时无需重新下载;yarn 早期通过并行安装提升速度,npm 后期版本也在性能上有较大优化。
  • 磁盘空间:pnpm 最优,因为依赖被全局存储并复用;npm 和 yarn 可能在不同项目中重复存储相同依赖。

monorepo、multirepo

monorepo 单一代码仓库
multirepo 多代码仓库
monorepo包管理工具lerna、yarn workspace、pnpm workspace、nx、trubo

微前端、MF模块联邦

&lt;think&gt;好的,我现在要比较WebpackVite的特点、性能以及使用场景。首先,我需要回顾一下用户提供的引用内容,确保信息准确。用户给出了四个引用,分别从不同的角度对比了WebpackVite,包括构建速度、配置复杂度、生态成熟度、开发模式和应用场景等。 首先,我需要整理WebpackVite各自的特点。根据引用,Webpack是一个成熟的构建工具,适合处理大型复杂项目,拥有丰富的插件生态。而Vite则利用了现代浏览器的ES模块特性,开发模式下启动快,热更新迅速,适合快速开发和中小型项目。 接下来是性能方面。Webpack在开发模式下需要打包整个项目,启动时间较长,但随着项目规模增大,生产构建优化较好。Vite在开发时按需编译,启动快,但生产构建可能依赖Rollup,速度也不错,但可能不如Webpack在复杂场景下的优化。 使用场景部分,引用中提到Webpack适合大型复杂项目,尤其是需要灵活配置和大量自定义的情况。Vite适合快速原型开发、中小项目以及对开发体验要求高的场景。 然后,我需要确保回答的结构清晰,分点对比,同时正确应用LaTeX格式。例如,提到Vite的ES模块加载时,可能需要用数学公式符号,比如$ES模块$,但根据用户指令,变量或技术术语不需要用LaTeX,所以可能不需要。但如果有数学表达式,比如复杂度分析,才需要应用。例如,如果讨论时间复杂度,可以用$O(n)$,但当前内容可能不涉及。 然后需要生成相关问题,根据用户示例,问题应围绕对比的各个方面,比如性能优化、配置差异、适用场景的选择等。 需要检查是否有引用标记正确添加,每个引用结束的位置是否自然。例如,在提到Webpack适合大型项目时,引用[^4]可能适用,而提到Vite的快速热更新时,引用[^1]或可用。 最后,确保回答使用中文,LaTeX格式正确,独立公式用$$...$$,行内用$...$,但当前内容可能较少涉及数学公式,可能需要确认是否有必要的地方使用。例如,构建时间的比较如果有具体数值可能需要,但用户引用中没有提供具体数据,所以可能不需要。 总结回答结构: 1. 概述 2. 核心差异(构建机制、开发模式、配置复杂度、生态) 3. 性能对比(开发/生产) 4. 应用场景 5. 相关问题 现在开始组织内容,确保每个部分引用正确的来源,并在末尾添加相关问题。&lt;/think&gt;### Webpack vs Vite: 特点、性能及使用场景对比 #### 一、核心差异对比 1. **构建机制** - **Webpack**:基于打包器模式,开发阶段需将所有模块打包成静态资源,通过`loader`和`plugin`处理依赖优化。这导致项目越大,启动和热更新越慢。 - **Vite**:利用浏览器原生支持ES模块的特性,开发阶段按需编译文件,跳过打包步骤,实现毫秒级启动和快速热更新。 2. **开发模式** - **Webpack**:依赖完整的打包过程,修改代码后需重新构建部分或全部模块,影响开发效率。 - **Vite**:通过`ESM`按需加载,仅编译当前修改的文件,结合原生`HMR`实现即时更新。 3. **配置复杂度** - **Webpack**:配置灵活但复杂,需手动设置`loader`、`plugin`及优化策略,适合有经验的开发者[^3]。 - **Vite**:默认集成常见功能(如TypeScript、CSS预处理),配置简洁,开箱即用[^4]。 4. **生态成熟度** - **Webpack**:插件生态丰富,支持各种定制需求(如代码分割、懒加载),社区资源完善[^2]。 - **Vite**:生态快速发展,依赖Rollup插件兼容,但复杂场景可能需要额外适配[^3]。 --- #### 二、性能对比 | 维度 | Webpack | Vite | |--------------|----------------------------------|-----------------------------------| | **开发启动** | 项目规模越大,启动越慢 | 按需编译,启动极快(毫秒级) | | **热更新** | 部分重建,速度中等 | 原生HMR,更新几乎无延迟[^4] | | **生产构建** | 优化成熟,支持复杂场景(如Tree Shaking) | 依赖Rollup,速度较快但定制性稍弱 | --- #### 三、应用场景 - **Webpack适用场景**: - 大型项目,需深度定制构建流程(如微前端、多入口)。 - 历史项目迁移,依赖特定Webpack插件[^2]。 - **Vite适用场景**: - 快速原型开发或中小型项目,追求开发体验。 - 现代框架(如Vue 3/React)项目,需即时反馈。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值