Webpack知识体系 | 青训营笔记

95 阅读6分钟

Webpack知识体系 | 青训营笔记

这是我参与「第四届青训营 」笔记创作活动的第13天 与大家分享Webpack的知识体系、基础知识,包括Webpack的学习方法等,不足之处欢迎大家批评指正!

01 为什么要学习Webpack?

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

02 什么是Webpack

引入

  • 前端项目由什么构成?——资源

image.png

可以手动管理这些资源

image.png

  • 手动管理的缺点
  1. 依赖手工,比如有50个JS文件...操作,过程繁琐
  2. 当代码文件之间有依赖时,就得严格按依赖顺序书写
  3. 开发与生产环境一致,难以接入TS或JS新特性
  4. 比较难接入Less,Sass等工具
  5. JS、图片、CSS资源管理模型不一致
  • 直到出现工程化工具

image.png

Webpack的本质

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

  • 多份资源打包成一个Bundle
  • 支持 Babel,Eslint,TS,CoffeScript,Less,Sass
  • 支持模块化处理css,图片等资源文件
  • 支持 HMR + 开发服务器
  • 支持持续监听、持续构建
  • 支持代码分离
  • 支持Tree-shaking
  • 支持Sourcemap

image.png

03 使用Webpack

示例

  1. 安装

image.png

  1. 编辑配置文件

image.png

  1. 执行编译命令

image.png

image.png

核心流程——极度简化版

  1. 入口处理(Get Start)

entry文件开始,启动编译流程

2.依赖解析(Dependencies Lookup)

entry文件开始,根据require or import等语句找到依赖资源

  1. 资源解析(Transform)

根据module配置,调用资源转移器,将png,css等非标准资源转译为JS内容

  1. 资源合并打包(Combine Assets)

将转译后的资源内容合并打包为可直接在浏览器运行的JS文件

image.png

模板化 + 一致性

image.png

使用Webpack

使用围绕配置展开,大致划分为两类:

  • 流程类

作用于流程中某个 or 若干个环节直接影响打包效果的配置项

  • 工具类

主流程之外,提供更多工程化能力的配置项

image.png

流程类配置

  1. 入口处理(Get Start)

输入:

entry

context

2.依赖解析(Dependencies Lookup)

模块解析:

resolve

externals

  1. 资源解析(Transform)

模块转译:

module

  1. 资源合并打包(Combine Assets)

后处理:

optimization

mode

target

image.png

配置总览

按使用频率:

  • 'entry/output'
  • 'module/plugins'
  • 'mode'
  • 'watch/devServer/devtool'

Webpack官方配置文档:webpack.js.org/configurati…

image.png

使用Webpack方法

image.png

  1. 声明入口entry

image.png

  1. 声明产物出口output

image.png

  1. 运行npx webpack

处理CSS

image.png

image.png

  1. 安装Loader

image.png

  1. 添加module处理css文件

image.png

image.png

思考

  1. Loader有什么作用?为什么这里要用css-loader,style-loader?
  2. 与旧时代——在HTML文件中维护css相比,这种方式的优劣?
  3. Less,Sass,Stylus这类的预编译框架,如何在Webpack中接入?

参考资料:

CSS-loader: github.com/webpack-con…

Webpack 原理系列七:如何编写loader: mp.weixin.qq.com/s/TPWcB4MfV…

Style-loader: webpack.js.org/loaders/sty…

接入Babel

image.png

image.png

  1. 安装依赖

image.png

  1. 声明产物出口output

  2. 执行npx webpack

image.png

image.png

思考

  1. Babel 的具体功能?
  2. Babel 与Webpack 分别解决了什么问题?为何二者能协作到一起? 参考资料:

Babel-Loader: webpack.js.org/loaders/bab…

Babel官网:babeljs.io/

@babel/preset-env:babeljs.io/docs/en/bab…

@babel/preset-react: babeljs.io/docs/en/bab…

@babel/preset-typescript:babeljs.io/docs/en/bab…

生成HTML

image.png

  1. 安装依赖

image.png

  1. 声明产物出口output

image.png

  1. 执行npx webpack
  • 执行结果

image.png

思考

  1. 相比于手工维护HTML,这种自动生成方式的优缺点?

参考资料:

HtmlWebpackPlugin:webpack.js.org/plugins/htm…

工具线

image.png

HMR(Hot Module Replacement)模板热替换

image.png

  1. 开启HMR

image.png

  1. 启动Webpack

image.png

image.png

参考资料:

Webpack 原理系列十:HMR 原理全解析:mp.weixin.qq.com/s/cbYMpuc4h…

Tree-Shaking

Tree-Shaking——树摇,用于删除Dead Code

模板导出了,但未被其它模块使用

Dead Code

  • 代码没有被用到,不可到达
  • 代码的执行结果不会被用到
  • 代码只读不写
  • ...

image.png

Dead Code的情况:

image.png

开启Tree-shaking:

mode:"production"

optimization.usedExports:true

PS:对工具类库如 Lodash 有奇效

image.png

其它工具

  • 缓存
  • Sourcemap
  • 性能监控
  • 日志
  • 代码压缩
  • 分包
  • ...

04 进阶篇:理解Loader

问题

Webpack只认识JS

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

image.png

使用Loader

image.png

image.png

  1. 安装Loader

image.png

  1. 添加module处理 CSS 文件

image.png

认识Loader——链式调用

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

image.png

其它特性

特点:

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

image.png

如何编写Loader

image.png

image.png

参考资料:

Webpack 原理系列七:如何编写loader:mp.weixin.qq.com/s/TPWcB4MfV…

常见Loader

站在使用角度,建议掌握常见Loader的功能、配置方法

image.png

05 进阶篇:理解插件

设计插件原因

  1. Webpack编译流程复杂
  • 新人需要了解流程细节,上手成本高
  • 功能迭代成本高,牵一发动全身
  • 功能僵化,作为开源项目而言缺乏成长性
  • ...
  1. 心智成本高 => 可维护性低 => 生命力弱
  2. 插件架构精髓对扩展开放,对修改封闭

image.png

Webpack的很多功能也是基于插件实现的

  • 使用html-webpack-plugin

image.png

  • 使用 html-webpack-plugin + DefinePlugin

image.png

理解插件

插件围绕“钩子”展开

image.png

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

image.png

时机:compier.hooks.compilation

参数:compilation

交互:dependencyFacories.set

image.png

思考:

  1. Loader与插件有什么区同点?
  2. “钩子”有什么作用?如何监听钩子函数?

参考资料:

[源码解读] Webpack 插件架构深度讲解:mp.weixin.qq.com/s/tXkGx6Ckt…

[万字总结] 一文吃透 Webpack 核心原理: mp.weixin.qq.com/s/SbJNbSVzS…

小结:Webpack5知识体系

image.png

06 学习方法

方法

  1. 入门应用
  • 理解打包流程
  • 熟练掌握常用配置项、Loader、插件的使用方法,能够灵活搭建集成Vue、React、Babel、Eslint、Less、Sass、图片处理等工具的Webpack环境
  • 掌握常见脚手架工具的用法,例如:Vue-cli、create-react-app、@angular/cli
  1. 进阶
  • 理解Loader、Plugin机制,能够自行开发Webpack组件
  • 理解常见性能优化手段,并能用于解决实际问题
  • 理解前端工程化概念与生态现状
  1. 大师级
  • 阅读源码,理解Webpack编译、打包原理,甚至能够参与共建

知识点

image.png