Webpack知识体系 | 青训营笔记

80 阅读3分钟

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

课程目标:

  • 理解Webpack的基本用法
  • 通过介绍Webpack功能、Loader 与 Plugin组件设计,建立一个知识体系

为什么要学习Webpack?

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

什么是 Webpack

前端的构成文件

image.png

手动管理资源的缺陷:

  • 依赖手工,比如有50个JS文件...操作,过程繁 琐
  • 当代码文件之间有依赖的时候,就得严格按依 赖顺序书写
  • 开发与生产环境一致,难以接入TS 或JS新特性
  • 比较难接入 Less、Sass等工具
  • JS、图片、CSS资源管理模型不一致
  • 对开发效率影响非常大

=>于是出现了很多工程化工具

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

image.png

什么是Webpack

本质上是一种前端资源编译和打包的工具

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

image.png

Webpack打包核心流程

示例

//安装依赖
npm i -D webpack webpack-cli

//编辑配置文件
module.exports={
    entry : ' main.js ',
    output: {
        filename: " [name] .js"path: path.join(__dirname, "./dist" ),
    }
    module: {
        rules : [{
            test:/\.less$/i,
            use: [ 'style-loader', 'css-loader', 'less-loader' ]
        }]
    }
}

//执行编译命令
npx webpack

核心流程———简化版

image.png

递归调用2、3。直到所有资源处理完毕

Entry => Dependencies Lookup => Transform => Bundle => Output

使用Webpack

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

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

流程类配置

image.png

配置总览

image.png

按使用频率:

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

使用Webpack—处理CSS

//文件结构
src index.js webpack.config.js

//声明入口'entry'
module.exports = {
    entry: "./src/index"
};

//声明产物出口'output'
const path = require( "path" );
module.exports={
    entry: "./src/index",
    output: {
        filename: "[name].js",
        path: path.join(__dirname, "./dist" ),
    }
};

//运行npx webpack

image.png

使用Webpack—处理JS——接入Babel

image.png

使用Webpack—生成HTML

image.png

使用Webpack—工具线

image.png

HMR

Hot Module Replacement——模块热替换 写的代码直接在页面中更新(不需要页面刷新)

image.png

Tree-Shaking

Tree-Shaking一树摇,用于副除 Dead Code

image.png

Dead Code

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

Tree-Shaking

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

image.png

开启tree-shaking :

  • mode:"production”
  • optimization.usedExports: true

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

其他工具

image.png

其它工具: - 缓存 - Sourcemap - 性能监控 - 日志 - 代码压缩 - 分包

Loader组件

//安装Loader
npm add -D css-loader style-loader

问题:Webpack只认识JS

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

image.png

Loader:链式调用

image.png

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

Loader的特性

image.png

特点:

  • 链式执行
  • 支持异步执行
  • 分normal、pitch两种模式
//Loader的写法
module.exports = function( source,sourceMap?,data? ) {
    //source为loader的输入
    //可能是文件内容,也可能是上一个loader处理结果    return source;
};

image.png

很多知名工具,如

  • vs Code、Web Storm、Chrome、Firefox
  • Babel、Webpack、Rollup、Eslint
  • Vue、Redux、Quill、Axios 等等,都设计了所谓“插件”架构,为什么?

能提升整个应用(工具)的扩展性

image.png

这是一个特别复杂的过程,那么:

  • 新人需要了解整个流程细节,上手成本高
  • 功能迭代成本高,牵一发动全身
  • 功能僵化,作为开源项目而言缺乏成长性

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

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

甚至,Webpack本身的很多功能也是基于插件实现的

image.png

插件的“钩子”

插件围绕‘钩子展开

image.png

image.png

钩子的核心信息:

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

钩子的三个要点:

  1. 时机: compier .hooks.compilation
  2. 参数:compilation'等
  3. 交互:dependencyFactories.set

如何学习 Webpack

入门级:学会灵活应用

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

image.png

## 进阶:学会扩展Webpack * 理解Loader、Plugin 机制,能够自行开发Webpack * 组件 * 理解常见性能优化手段,并能用于解决实际问题 * 理解前端工程化概念与生态现状

大师:源码级理解Webpack 打包编译原理

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