这是我参与「第五届青训营 」伴学笔记创作活动的第 19 天
这篇笔记记录了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()] }
- css:接入loader
- 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
- 例如一个less文件的处理需要用到
- 支持异步执行
- 分为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和插件,然后可以探索深入其底层逻辑