Webpack 与 Vite | 青训营笔记

108 阅读5分钟

这是我参与「第四届青训营 」笔记创作活动的的第10天

一、重点内容:

  • 为什么学习Webpack,什么是Webpack,Webpack的基本使用
  • Webpack的进阶之路
  • 为什么学习Vite,什么是Vite,Vite的基本使用
  • Vite的进阶之路

二、详细知识点介绍:

WebPack知识体系

为什么要学习Webpack?

  • 理解前端“工程化”概念、工具、目标
  • 一个团队总要有那么几个人熟悉Webpack,某种程度上可以成为个人的核心竞争力
  • 高阶前端必经之路

什么是Webpack

前端项目由资源构成,包括JS,TS,PNG,CSS,Less等

在旧时代,需要手动引入很多文件

Webpack是一种前端资源编译、打包工具

  • 多份资源文件打包成一个Bundle
  • 支持Babel,Eslint,TS,CoffeScript、Less,Sass

使用Webpack

Webpack 打包核心流程

  1. 入口处理:从‘entry’文件开始,启动编译流程
  1. 依赖解析:从’entry‘文件开始,根据’require‘ or ’import‘ 等语句找到依赖资源
  1. 资源解析:根据’module‘配置,调用资源转移器,将png、css等非标准JS资源转译为JS内容;递归调用2、3,直到所有资源处理完毕
  1. 资源合并打包:将转译后的资源内容合并打包为可直接在浏览器运行的文件

特点

模块化+一致性

  • 多个文件资源合并成一个,减少HTTP请求数
  • 支持模块化开发
  • 支持高级JS特性
  • 支持TypeScript、CoffeeScript方言
  • 统一图片、CSS、字体等其他资源的处理模型

配置分类

  • 流程类:作用于流程中某个 or 若干个环节,直接影响打包效果的配置项
  • 工具类:主流程之外,提供更多工程化能力的配置项

流程类配置

  • 输入:’entry‘、’context‘
  • 模块解析:’resolve‘、’externals‘
  • 模块转译:’module‘
  • 后处理:’optimization、‘mode’、‘target’

HMR Hot Module Replacement——模块热替换

\

Tree-Shaking

用于删除没用的代码

  • 代码没有被用到,不可到达
  • 代码的执行结果不会被用到
  • 代码只读不写
  • 模块导出了,但未被其他模块使用

Loader组件

Webpack只认识JS

为了处理非标准JS资源,设计出资源翻译模块——Loader,用于将资源翻译为标准JS

链式调用

  • less-loader:实现less->css的转换
  • css-loader:将CSS包装成类似module.exports=“${CSS}"的内容,包装后的内容符合JavaScript语法
  • style-loader:将CSS模块包进require语句,并在运行时调用injectStyle等函数将内容注入到页面的style标签

特点

  • 链式执行
  • 支持异步执行
  • 分normal、pitch两种模式

Plugin组件

插件架构精髓:对扩展开放,对修改封闭

//npm i -D 插件

const chajianName=require{"插件"}

module.exports={
    plugins:[new chajianName()]
}

钩子的核心信息:

  • 时机:编译过程的特定节点,Webpack会以钩子形式通知插件此刻正在发生什么事情
  • 上下文:通过tapable提供的回调机制,以参数方式传递上下文信息
  • 交互:在上下文参数对象中附带了很多存在side effect的交互接口,插口可以通过这些接口改变

如何学习Webpack

Vite知识体系

为什么需要构建工具

痛点

  • 模块化:ESM,CommonJS、UMD
  • 资源编译:高级语法的编译
  • 产物质量:代码体积、代码性能
  • 开发效率:热更新

意义

  • 模块化方案:提供模块加载方案;兼容
  • 语法转译:高级语法转译,如Sass、TypeScript;资源加载,如图片、字体、worker
  • 产物质量:产物压缩、无用代码删除、语法降级
  • 开发效率:热更新

什么是Vite?为什么是Vite?

定位:新一代前端构建工具

两大组成部分

  1. No-Bundle开发服务,源文件无需打包
  1. 生产环境基于Rollup的Bundle

核心特征

  1. 高性能,dev启动速度和热更新速度非常快
  1. 简单易用,开发体验好

传统构建工具存在的问题

缓慢的启动->项目编译等待成本高

缓慢的热更新->修改代码后不能实时更新

瓶颈

bundle带来的性能开销

JavaScript语言的性能瓶颈

基于原生ESM的开发服务优势

  • 无需打包项目源代码
  • 天然的按需加载
  • 可以利用文件级的浏览器缓存

基于Esbuild的编译性能优化

Esbuild——基于Golang开发的前端工具

  1. 打包器Bundle
  1. 编译器Transformer
  1. 压缩器Minifier

Vite上手使用

npm i -g pnpm

pnpm create vite

pnpm install

npm run dev

Tree Shaking 优化原理

  1. 基于ESM的import/export 语句依赖关系,与运行时状态无关
  1. 在构建阶段将未使用到的代码进行删除

CommonJS格式不能做到tree shaking,因为require的部分可能依赖运行时计算的结果,只有ESM才能tree shaking

Vite整体架构

为什么要进行预打包

  1. 避免node_modules过多的文件请求
  1. 将CommonJS格式转换为ESM格式

实现原理

  1. 服务启动前扫描代码中用到的依赖
  1. 用Esbuild对依赖代码进行预打包
  1. 改写import语句,指定依赖为预构建产物路径

用Esbuild编译TS/JSX

优势:编译速度提升10-100倍

局限性:不支持类型检查;不支持语法降级到ES5

插件机制

开发阶段->模拟Rollup机制

生产环境->直接使用Rollup

Vite进阶路线

双引擎:Esbuild,Rollup

先了解基本使用,动手尝试各项常用配置

然后学习插件开发

为什么需要插件

  • 抽离核心逻辑
  • 易于扩展

Vite 钩子函数

插件示例

JS编译工具(Babel)

JavaScript语法标准繁多,浏览器支持程度不一

开发者需要用到高级语法

语法安全降级

上层解决方案:@vite/plugin-legacy

底层原理:借助Babel进行语法自动降级;提前注入Polyfill实现

服务端渲染SSR

用于提升首屏性能和SEO优化

三、课后个人总结:

今天真的收获满满,学习了两种构建工具——Webpack和Vite,两者既有共性,也有差异,Webpack作为老大哥,功能既强大又有些繁琐,而Vite作为后起之秀,完美实现了前者很多功能,且简单易用,对新手十分友好。