12Webpack知识体系 | 青训营笔记

66 阅读2分钟

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

PPT: bytedance.feishu.cn/file/boxcnt…

为什么要学习Webpack?

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

主要内容

 什么是Webpack
 Webpack打包核心流程
     示例
     Entry => Dependencies Lookup => Transform => Bundle => Output
     关键配置项介绍
 Loader组件
 Plugin组件
 如何学习Webpack
     入门级: 学会灵活应用
     进阶: 学会扩展Webpack
     大师: 源码级理解Webpack打包编译原理
 理解Webpack的基本用法
 通过介绍Webpack功能, Loader与Plugin组件设计, 建立一个知识体系

为什么Webpack

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

使用Webpack

1 安装

npm i -D webpack webpack-cli

2 编辑配置文件

 // webpack.config.js
 path = require('path')
 ​
 module.exports = {
     entry: './src/index', // index是js文件不是htnm
     mode: 'development',
     output: {
         filename: "bundle.js",
         path: path.join(__dirname, "./dist"),
     },
     module: {
         rules:[{
             test: /.less$/i,
             use: ['style-loader', 'css-loader', 'less-loader']
         }]
     }
 }

3 执行编译命令

npx webpack

核心流程

  1. 入口处理 (Get Start)

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

  1. 依赖解析 (Dependencies Lookup)

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

  1. 资源解析 (Transform)

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

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

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

(递归调用2, 3, 直到所有资源处理完毕)

配置

关于Webpack的使用方法, 基本都围绕"配置"展开, 配置大致可划分为两类

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

流程类配置

输入: entry, context

模块解析: resolve external

模块转译: module

后处理: optimization, mode, target

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

基本配置

 // 最少最少是要entry和output的
 const path = require('path')
 ​
 module.exports = {
     entry: './src/index', 
     output: {
         filename: "bundle.js",
         path: path.join(__dirname, "./dist")
     }
 }
 ​
 // mode 默认是 production
 // npm add -D css-loader style-loader less-loader
 // 处理css less文件
 const path = require('path')
 ​
 module.exports = {
     entry: './src/index',
     mode: 'development',
     output: {
         filename: "bundle.js",
         path: path.join(__dirname, "./dist"),
     },
     module: {
         // 用use里的loader处理满足test的文件
         rules:[{
                 test: /.css$/i,
                 use: ['style-loader', 'css-loader']
             }, {
                 test: /.less$/i,
                 use: ['style-loader', 'css-loader', 'less-loader']
             }
         ]
     }
 }
 // 接入Babel (将高版本的js代码转译成低版本的代码)
 // npm i -D @babel/core @babel/preset-env babel-loader
 module: {
     rules:[{
         test: '/.js?$/',
         use: [{
             loader: 'babel-loader',
             options: {
                 presets: [
                     ['@babel/preset-env']
                 ]
             }
         }]
     }]
 }
 // 自动生成HTML
 // npm i -D html-webpack-plugin
 const path = require('path')
 const HtmlWebpackPlugin = require('html-webpack-plugin')
 ​
 module.exports = {
     entry: './src/index',
     output: {
         filename: "bundle.js",
         path: path.join(__dirname, "./dist"),
     },
     plugins: [new HtmlWebpackPlugin()]
 }

工具线

HMR

Hot Module Replacement 模块热替换

 module.exports = {
     devServer: {
         hot: true
     }
 };
 // 启用这个配置项后, 要改用这个命令 npx webpack serve

Tree-Shaking

删除没用的代码

 module.exports = {
     mode: 'production',
     optimization: {
         usedExports: true
     }
 }

其他工具

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

理解Loader

Webpack只认识JS

特点:

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

理解插件

对扩展开放, 对修改封闭

钩子

核心信息

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

\