这篇笔记记录了Webpack基础定义与使用的知识
一、本堂课重点内容
- 什么是Webpack
- Webpack打包核心流程
- 示例
- Entry => Dependencies => Transform => Bundle => Output
- 关键配置项介绍
- Loader组件
- Plugin组件
- 如何学习Webpack
- 入门级:学会灵活应用
- 进阶:学会扩展Webpack
- 大师:源码级理解Webpack打包编译原理
二、详细知识点介绍
1、什么是Webpack
- 前端项目由许多资源组成,旧时代(2009年之前)使用手工管理是存在许多问题的
- 依赖手工,比如css使用link标签引入,js使用script引入
- 当代码文件之间有依赖时,就得严格按照顺序书写
- 开发与生产环境一致,难以接入ts或js新特性
- 比较难接入less、sass等工具
- js、图片、css资源管理器模型不一致
- Webpack的本质:一种前端资源编译、打包工具
- 多份资源文件打包成一个bundle
- 支持多种工具、规范
- 统一资源的管理模型
2、Webpack的使用
-
基本使用方法
- 安装:
npm i -D webpack webpack-cli
- 安装:
-
编辑配置文件
-
执行编译命令:
npx webpack
-
核心流程
- 入口处理:从entry文件开始,启动编译流程
- 依赖解析:从entry文件开始,根据require或import等语句找到依赖资源
- 资源解析:根据module配置,调用资源转移器,将png、css等非标准js资源转译为js内容(第2步和第3步递归调用,直到所有资源处理完毕)
- 资源合并打包:将转译后的资源内容合并打包为可直接在浏览器运行的js文件
-
Webpack配置:Webpack的使用方法基本围绕配置展开,这些配置基本可分为两类
- 流程类:作用于流程中某个或若干个环节,直接影响打包效果的配置项
- 输入:
entry
, … - 模块解析:
resolve
,externals
, … - 模块转译:
module
, … - 后处理:
optimization
,mode
,target
, …
- 输入:
- 工具类:主流程之外,提供更多工程化能力的配置项
- Webpack必须有的两个配置项:entry(入口)、output(输出)
module.exports = { entry: './src/index', output: { filename: '[name].js', path: ... } }
module
的作用:加载Loaderconst path = require("path"); module.exports = { entry: './src/index', output: { filename: '[name].js', path: path.join(__dirname, "./dist"), } // 加载css module: { rules: [{ test: /\.css$/, use: ["style-loader", "css-loader"] }] } }
- 流程类:作用于流程中某个或若干个环节,直接影响打包效果的配置项
-
Webpack处理HTML、css、js三种资源的方法
-
css:接入loader:
npm i -D style-loader css-loader
-
js:接入babel:
npm i -D @babel/core @babel/preset-env babel-loader
const path = require("path"); module.exports = { entry: './src/index', output: { filename: '[name].js', path: path.join(__dirname, "./dist"), } 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: '[name].js', path: path.join(__dirname, "./dist"), } plugins: [new HtmlWebpackPlugin()] }
-
-
HMR(Hot Module Replace),模块热更新
- 设置
devServer
下的hot
属性为true
module.export = { ... watch: true devServer: { hot: true } }
- 执行
npx webpack serve
- 设置
-
Tree-Shaking:删除Dead Code
- Dead Code:
- 代码未被用到,不可到达
- 代码的执行结果不会被用到
- 代码只读不写
- …
- Tree-Shaking
- 开启方法
mode: "production" optimization.usedExports: true
- Dead Code:
3、理解Loader
-
作用:处理非标准js资源,将资源翻译成标准js
-
特性:
- 链式调用:按照书写的顺序从右往左依次调用
- 例如一个less文件的处理需要用到less-loader、css-loader、style-loader
- 支持异步执行
- 分为normal、pitch两种模式(pitch模式的执行顺序与normal相反,pitch是一个注入的过程,较复杂)
- 链式调用:按照书写的顺序从右往左依次调用
-
*Webpack调试小技巧:使用ndb
- 在要调试的位置插入debugger
ndb npx webpack
-
如何编写Loader
- Loader的结构
module.exports = function(source, sourceMap?, data?) { // source为loader的输入 // 可能是文件内容,也可能是上一个loader的处理结果 return source; }
- Loader的结构
-
常用的Loader,建议掌握
- JavaScript
- babel-loader
- eslint-loader
- ts-loader
- buble-loader
- vue-loader
- angular2-template-loader
- CSS
- css-loader
- style-loader
- less-loader
- sass-loader
- stylus-loader
- postcss-loader
- HTML
- html-loader
- pug-loader
- posthtml-loader
- Assets
- file-loader
- val-loader
- url-loader
- json5-loader
- JavaScript
4、理解插件
- 项目本身过于复杂时,使用插件开发可以提高可维护性和生命力
- 插件的使用
- 引入插件:
const DashboardPlugin = require('webpack-dashboard/plugin')
- 新建插件实例
module.exports = { plugins: [new DashboardPlugin()]; }
- 引入插件:
5、总结
- Webpack5知识体系
- Webpack学习方法
- 入门应用:理解打包流程,掌握Loader和Plugin的使用,熟练使用常用工具以及脚手架工具
- 进阶:理解Loader、Plugin机制,能够自行开发Webpack组件,理解优化途径,理解前端工程化概念与生态现状
- 大师级:阅读源码,参与构建
- 知识点思维导图
三、实践练习例子
- 已在上一节列出
四、课后个人总结
- 作为初学者,首先要学会使用Webpack,掌握常用的配置、Loader和插件,然后可以探索深入其底层逻辑