什么是 Webpack、Webpack 打包核心流程、使用 Webpack、理解 Loader、理解插件、学习方法

# Webpack 知识体系

# 为什么要学习 Webpack

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

# 什么是 Webpack

前端项目由许多不同类型的文件、资源构成,比如:

我们当然可以手动管理这些资源,而且在旧时代我们也的确是这样做的,比如:

但是,会有许多潜在问题:

  • 依赖手工,比如有 50 个 JS 文件… 操作,过程繁

  • 当代码文件之间有依赖的时候,就得严格按依
    赖顺序书写

  • 开发与生产环境一致,难以接入 TS 或 JS 新特

  • 比较难接入 Less、Sass 等工具

  • JS、图片、CSS 资源管理模型不一致

这些都是旧时代非常突出的问题,对开发效率影响非常大,直到… 出现了很多的工程化工具,比如:webpack、vite、esbuild、rollup.js 等等

某种程度上,正是这些工具的出现,才有了 “前端工程” 这一概念

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

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

简单示例:

  1. 安装: npm install webpack

  2. 编辑配置文件: webpack.config.js

    const path = require('path');
    module.exports = {
        
    }
  3. 执行编译命令: npx webpack

# Webpack 打包核心流程

核心流程:

Get-StartDependencies-LookupTransformCombine-Assets`entry``require`&`inport``module``output`入口处理y解析

image-20220123102147141

# 使用 Webpack

使用 Webpack 的好处:

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

关于 Webpack 的使用方法,基本都围绕 “配置” 展开,而这些配置大致可划分为两类:

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

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

image-20220123102907178

# 解析 CSS

Loader 有什么作用?为什么这里需要用到 css-loader、style-loader?

与旧时代 —— 在 HTML 文件中维护 css 相比,这种方式会有什么优劣处?

有没有接触过 Less、Sass、Stylus 这一类 CSS 预编译框架?如何在 Webpack 接入这些工具?

# 解析 JS

Babel:一个 JS 的降级化转义器,为了让 ES6 等新语言特性能够兼容尽量多的浏览器,需要将 ES6 等新语言特性装换成 ES5 等兼容性更强的代码

接入 Babel:

  1. 安装依赖: npm i -D @babel/core @bebel/preset-env babel-loader

  2. 声明产物出口 output

    
    
  3. 执行 npx webpack

Babel 具体有什么功能?

Babel 与 Webpack 分别解决了什么问题?为何两者能协作到一起了?

# 生成 HTML

当各种资源文件都已经由 Webpack 统一管理后,HTML 也不必要我们自己维护,可以使用 Webpack 插件生成

接入 html-webpack-plugin

相比于手工维护 HTML,使用 Webpack 自动化有什么优缺点?

# 模块热替换 - HMR

  1. 开启 HMR

    module.exports = {
        // 其他配置项...
        devServer: {
            hot:true
        },
        watch: true // 持续监听本地文件变化并即时构建
    }

# Tree-Shaking

删除未被使用的代码(Dead Code):

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

使用:

  • 只需要配置 mode = "production"optimization.usedExports = true 即可

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

# 其他工具

缓存、SourceMap、性能监控、日志、代码压缩、分包等等

  • 除上面提到的内容,还有哪些配置可划分为 “流程类” 配置?

  • 工具类配置具体有什么作用?包括 devtool/cache/stat

# 理解 Loader

为什么需要 Loader:因为 Webpack 只认识 JS,所以为了处理非标准 JS 资源,设计出资源翻译模块 ——Loader,用于将资源翻译为标准 JS

Loader 特性:链式调用、支持异步执行、分 normal/pitch 两种模式

# 链式调用

以 Less 语法文件的解析为例:

  1. less-loader:实现 less => css 的转换

  2. css-loader:将 CSS 包装成类似 module.exports = “${css}” 的内容,包装后的内容符合 JavaScript 语法

  3. style-loader:将 css 模块包进 require 语句,并在运行时调用 injectStyle 等函数将内容注入到页面的 style 标签

# 如何编写 Loader

Loader 输入是什么?要求的输出是什么?

Loader 的链式调用是什么意思?如何串联多个 Loader ?

Loader 中如何处理异步场景?

# 理解插件

很多知名工具,如:

  • VS Code、Web Storm、Chrome、Firefox
  • Babel、Webpack、Rollup、Eslint
  • Vue、Redux、Quill、Axios

等等,都设计了所谓 “插件” 架构,为什么?

工具的源码和工作原理是一个特别复杂的过程,那么∶

  • 新人需要了解整个流程细节,上手成本高

  • 功能迭代成本高,牵一发动全身

  • 功能僵化,作为开源项目而言缺乏成长性

  • 学习的心智成本高 => 可维护性低 => 生命力弱

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

# 钩子

钩子的核心信息∶

  1. 时机:编译过程的特定节点,Webpack 会以钩子形式通知插件此刻正在发生什么事情

  2. 上下文:通过 tapable 提供的回调机制,以参数方式传递上下文信息义

  3. 交互:在上下文参数对象中附带了很多存在 side effect 的交互接口,插件可以通过这些接口改变

# 学习方法

  1. 入门应用

    • 理解打包流程
    • 熟练掌握常用配置项、Loader、插件的使用方法,能够灵活搭建集成 Vue、React、Babel、Eslint、Less、Sass、图片处理等工具的 Webpack 环境
    • 掌握常见脚手架工具的用法,例如:Vue-cli、create-react-app、@angular/cli
  2. 进阶

    • 理解 Loader、Plugin 机制,能够自行开发 Webpack 组件

    • 理解常见性能优化手段,并能用于解决实际问题

    • 理解前端工程化概念与生态现状

  3. 大师级

    • 阅读源码,理解 Webpack 编译、打包原理,甚至能够参与共建

image-20220123145507754

Webpack 进阶知识体系

# 参考资料

  • 字节青训营课程
更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

TagBug 微信支付

微信支付

TagBug 支付宝

支付宝