1. webpack-概念
1.1 目标
为何学webpack
什么是webpack
1.2 场景
开发完项目, 可以用node+webpack来分析, 翻译, 压缩, 打包, ==加快浏览器打开速度==
1.3 概念
-
现代 javascript 应用程序的 静态模块打包器 (module bundler)
-
静态: 文件资源
-
模块: node环境, 引入文件, 遵守模块化语法
-
-
除了合并代码, 还可以翻译和压缩代码
-
less/sass -> css
-
ES6/7/8 -> ES5
-
html/css/js -> 压缩合并
-
1.4 小结
什么是webpack?
答案:静态模块打包器
还能翻译和压缩代码
减小代码包体积, 让浏览器更快速打开网页
2. webpack--使用前--准备
2.1 目标
用webpack, 需要准备什么
2.2 软件
webpack依赖Node环境
npm或yarn等模块管理工具
2.3 步骤
-
创建Day01_webpack基础使用文件夹
-
初始化包环境
yarn init 或 npm init --yes
3.安装依赖包
为何指定版本: 防止以后包更新, 造成课程内容报错
npm i webpack@5.31.2 webpack-cli@4.6.0 -D
4.在package.json中, 配置scripts(自定义命令)
scripts: {
"build": "webpack"
}
2.4 小结
使用webpack前, 准备什么?
答案 :Node环境软件
npm或yarn模块管理器
项目文件夹和包环境
下载webpack并配置命令
3. webpack--基本使用
3.1 目标
学习webpack使用, 打包2个js文件
3.2 步骤
1. 新建src/add/add.js - 定义求和函数导出
export const addFn = (a, b) => a + b
2. 新建src/index.js导入使用
// webpack打包的入口
import { addFn } from './add/add'
console.log(addFn(5, 2));
3. 运行打包命令
npm run build 或者 yarn build
3.3 效果
1. src并列处, 生成dist目录和main.js文件
2. 查看main.js文件, 是打包压缩后的代码
(()=>{"use strict";console.log(7)})();
3. 打包关系图
3.4 小结
webpack如何使用?
答案:先下载安装webpack, 配置打包命令
默认入口src/index.js-要被打包的文件, 要引入到这里使用
输入yarn build打包命令(实际是项目环境webpack命令)
输出代码到dist/main.js中
4. webpack-更新打包
4.1 目标
代码变化, 如何打包
4.2 步骤
1. 新建src/tool/tool.js - 导出数组求和方法
export const getArrSum = arr => arr.reduce((sum, val) => sum += val, 0)
2. src/index.js - 导入使用
import { addFn } from './add/add'
import { getArrSum } from './tool/tool'
console.log(addFn(5, 2));
console.log(getArrSum([5, 6, 9, 10]));
3. 重新打包
npm run build 或者 yarn build
4.3 效果
自动覆盖原dist, 结果压缩极致
4.4 小结
代码增加后如何打包?
答案:要和src/index.js有直接或间接的引入关系
重新执行yarn build
5. webpack--修改配置
5.1 目标
修改默认入口和出口
默认入口: src/index.js
默认出口: dist/main.js
5.2 步骤
-
项目根目录 - 新建webpack.config.js文件 (默认配置文件名)
-
填入配置项
const path = require("path")
module.exports = {
entry: "./src/main.js", // enter: 默认入口
output: {
path: path.join(__dirname, "dist"), // 出口"文件夹"名
filename: "bundle.js" // 出口"文件"名
}
}
3. 修改代码里src/index.js 为 src/main.js
4. 重新打包观察输出文件名字
5.3 小结
1. webpack默认入口和出口是什么?
答案:默认入口src/index.js
默认出口dist/main.js
2. webpack默认配置文件名?
答案:webpack.config.js
6. webpack--打包流程图
6.1 目标
运行npm run build 或者 yarn build发生了什么
6.2 图示
1. 代码执行过程
2. 代码源文件和webpack之间关系图
源码一定要和入口产生直接/间接引入关系, 才会被一起打包
6.3 小结
1. 简述总结下打包流程?
答案:执行局部webpack命令(前提项目中下载了webpack包)
有webpack.config.js用, 否则用内置默认
根据入口建立引入关系
编译翻译整合打包输出到指定位置
2. 模块想要被webpack识别打包, 要注意什么?
答案:模块文件要和webpack入口产生直接或间接引入关系
7. webpack插件--自动生成html文件
7.1 目标
学习webpack插件html-webpack-plugin
自动生成html文件
自动引入打包后文件
7.2 步骤
1. 下载插件
yarn add html-webpack-plugin@5.3.1 -D 或者 npm i html-webpack-plugin@5.3.1 -D
2. webpack.config.js配置
// 引入自动生成 html 的插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
// ...省略其他代码
plugins: [
new HtmlWebpackPlugin({
// 以此为基准生成打包后html文件
template: './public/index.html'
})
]
}
3. 重新打包后观察dist下
-
自动生成html文件
-
自动引入打包后js文件
总结: webpack就像一个人, webpack.config.js是人物属性, 给它穿什么装备它就干什么活
7.3 小结
自动生成html和引入打包后文件, 如何做?
答案:下载html-webpack-plugin插件包, 给webpack.config.js配置上
8. webpack加载器--处理css文件问题
8.1 目标
webpack能否打包css文件
8.2 步骤
1. 新建 - src/css/index.css
2. 编写去除li圆点样式代码
li{
list-style: none;
}
3. ==在main.js引入index.css==
一定要引入到入口才会被webpack打包
import "./css/index.css"
4. 执行打包命令观察效果
错误解释: 你可能需要一个loader来支持这种类型文件, 解析css代码
原因: webpack默认只识别js文件
8.3 小结
为何webpack打包css文件会报错呢?
答案:不能, 因为webpack默认只识别js文件
9. webpack加载器--处理css文件
9.1 目标
学习loader加载器, 打包更多类型文件
9.2 步骤
1. 安装依赖
需要这2个模块包, 帮助webpack打包css
yarn add css-loader@5.2.1 style-loader@2.0.0 -D
或者
npm i css-loader@5.2.1 style-loader@2.0.0 -D
2. webpack.config.js 配置
module.exports = {
// ...其他代码
module: { // 如何处理项目中不同模块文件
rules: [ // 规则
{
test: /\.css$/, // 匹配所有的css文件
// use数组里从右向左运行
// 先用 css-loader 让webpack能够识别 css 文件的内容并打包
// 再用 style-loader 将样式, 把css插入到dom中
use: [ "style-loader", "css-loader"]
}
]
}
}
3. 执行打包命令, 观察打包后dist下
9.3 效果
-
css代码被打包进了dist/bundle.js中
-
运行时, css代码插入到html的style标签中
9.4 小结
1. webpack如何支持css打包?
答案:使用style-loader和css-loader
2. style-loader和css-loader作用?
答案:css-loader让webpack识别.css文件, 打包代码到js中
style-loader把js中的css代码, 插入到style标签里显示
3. 打包后样式在哪里?如何生效?
答案:打包后样式在.js文件中
运行后, 被插入到style标签里
10. webpack加载器--处理less文件
10.1 目标
学习less-loader处理.less文件
10.2 步骤
1. 新建src/less/index.less - 设置li字体大小24px
@size:24px;
ul, li{
font-size: @size
}
2. 引入到main.js中
import "./less/index.less"
3. 下载依赖包
yarn add less@4.1.1 less-loader@8.1.0 -D 或者 npm i less@4.1.1 less-loader@8.1.0 -D
4. webpack.config.js 配置
module: {
rules: [
// ...省略其他
{
test: /\.less$/, // 匹配.less结尾文件
// 使用less-loader, 让webpack处理less文件, 内置还会用less模块, 翻译less代码成css代码
use: [ "style-loader", "css-loader", 'less-loader']
}
]
}
总结: 只要找到对应的loader加载器, 就能让webpack处理不同类型文件
10.3 小结
1. webpack如何支持less打包?
答案:下载less和less-loader2个包
less-loader识别less文件
less是翻译less代码到css代码
2. less翻译后, 还要注意什么?
答案:还要用css-loader把css代码打包进js中
style-loader, 把css代码插入到DOM上
11. webpack加载器--处理图片文件
11.1 目标
配置webpack, 打包图片文件
11.2 步骤
1. 素材文件夹/2个图文件
2. 在css/less/index.less - 把小图片用做背景图
body{
background: url(../assets/logo_small.png) no-repeat center;
}
3. 在src/main.js - 把大图插入到创建的img标签上, 添加body上显示
// 引入图片-使用
import imgUrl from './assets/1.gif'
const theImg = document.createElement("img")
theImg.src = imgUrl
document.body.appendChild(theImg)
11.3 配置
webpack5内置处理方案, 只需要填入配置即可
1. webpack.config.js填写
module: {
rules: [
// ...省略其他
{
test: /\.(png|jpg|gif|jpeg)$/i, // 匹配图片文件
type: 'asset' // 在导出一个 data URI 和一个单独的文件之间自动选择
// 小于8kb的, 转成data URI(图片转成base64字符串打包进js中)
// 大于8kb的, 直接复制文件到dist目录下(因为转base64会体积增30%)
}
]
}
2. 打包后运行dist/index.html观察区别
11.4 小结
1. webpack如何支持图片打包?
答案:webpack5内置了, 只需要配置type:'asset'
2. 对图片有哪两种处理方案?
答案:默认8kb以下图片, 转成base64字符串打包进js中, 减少网络请求次数
超过8kb的图片, 直接复制到dist下, 转base64会增加30%体积
12. webpack加载器--处理字体文件
12.1 目标
webpack如何处理字体文件
12.2 步骤
1. 素材文件夹/字体库fonts文件夹
2. 在main.js引入iconfont.css
// 引入字体图标文件
import './assets/fonts/iconfont.css'
3. 在public/index.html使用字体图标样式
<i class="iconfont icon-weixin"></i>
12.3 配置
webpack5, 用asset module技术
webpack.config.js
{
test: /\.(eot|svg|ttf|woff|woff2)$/,
type: 'asset/resource', // 当做静态资源直接复制文件
generator: {
filename: 'font/[name].[hash:6][ext]' // 放到dist/font文件夹, 文件名格式如左
}
}
12.4 小结
webpack如何处理字体文件?
答案:在webpack.config.js的rules里针对字体图标文件类型设置asset/resource,直接输出到dist下
13. webpack加载器--处理高版本js语法
13.1 目标
让webpack, 对高版本js语法降级
13.2 介绍
babel编译器=> 用于处理高版本 js语法 的兼容性 babel官网
webpack配合babel-loader 对js语法做处理 babel-loader文档
13.3 步骤
1. src/main.js - 编写箭头函数
const fn = () => { // 高级语法
console.log("你好babel");
}
console.log(fn) // 一定打印函数, 才会被webpack把"函数体"打包起来
2. 安装包
yarn add -D babel-loader@8.2.2 @babel/core@7.13.15 @babel/preset-env@7.13.15
或者
npm i -D babel-loader@8.2.2 @babel/core@7.13.15 @babel/preset-env@7.13.15
3. webpack.config.js 配置规则
module: {
rules: [
{
test: /\.js$/, // 匹配js结尾文件
exclude: /(node_modules|bower_components)/, // 不转换这2个文件夹里的js
use: {
loader: 'babel-loader', // 使用加载器-处理
options: {
presets: ['@babel/preset-env'] // 预设:转码规则(用bable开发环境本来预设的)
}
}
}
]
}
13.4 小结
webpack如何帮助我们降低js版本语法?
答案:借助babel-loader和babel编译器,给webpack配置上, 翻译再打包使用
14. webpack开发服务器--学习
14.1 目标
下载webpack-dev-server, 启动一个开发服务器, 用于快速开发应用程序
14.2 步骤
-
构建入口和所有模块依赖关系图
-
磁盘读取对应的文件到内存, 才能加载
-
用对应的 loader 进行处理和翻译
-
将处理完的内容, 输出到内存里而非磁盘上
-
以后代码变化, 自动更新打包变化的代码, 显示到浏览器上
14.3 安装
1. 下载包
yarn add webpack-dev-server@3.11.2 -D 或者 npm i webpack-dev-server@3.11.2 -D
2. 配置自定义命令serve
scripts: {
"build": "webpack",
"serve": "webpack serve"
}
3. 运行命令-启动webpack开发服务器
yarn serve
#或者 npm run serve
14.4 小结
1. 如何用webpack开发服务器, 实时打包我们的代码?
答案:下载webpack-dev-server包
在package.json配置serve命令, 启动
webpack-dev-server给我们一个地址+端口, 供浏览器访问查看index.html页面和打包后的js和css等
2. webpack开发服务器好处是?
答案:打包进内存里, 使用更快
代码变化, 只会重新打包和更新, 变化的文件和代码
15. webpack-开发服务器-配置
15.1 目标
查找文档, 修改开发服务器配置
15.2 步骤
1. webpack.config.js中添加服务器配置
module.exports = {
// ...其他配置
devServer: {
port: 3000, // 端口号
open: true // 启动后自动打开浏览器
}
}
15.3 小结
如何修改webpack开发服务器的配置呢?
答案:去文档查找配置项的名字
在webpack.config.js的devServer选项里添加
16. webpack-项目打包发布
16.1 目标
项目做完了, 要上线怎么办
16.2 步骤
1. 执行之前的yarn build产生dist目录
所有代码, 被整合打包
2. 把dist目录交给后台/运维, 部署给客户使用即可
开发环境的代码不用发
16.3 小结
项目分哪2个环境?
答案:线上和线下2个环境
线上也叫"生产环境"/"部署", 英文"production"
线下也叫"开发环境"/写代码, 英文"development"
+++++++++ 附加 webpack面试题 ++++++++++++++
1、什么是webpack(必会)
-
webpack是一个javascript的静态模块打包工具
-
webpack里一切文件皆模块,通过loader转换文件,通过plugin注入钩子
-
最后输出由多个模块组合成的文件,webpack专注构建模块化项目
2、webpack的优点是什么?(必会)
-
专注于处理模块化的项目,能做到开箱即用,一步到位
-
通过plugin扩展,完整好用又不失灵活
-
通过loaders扩展, 可以让webpack把所有类型的文件都解析打包
-
区庞大活跃,经常引入紧跟时代发展的新特性,能为大多数场景找到已有的开源扩展
3、webpack的构建流程是什么?从读取配置到输出文件这个过程尽量说全(必会)
webpack 的运行流程是一个串行的过程,从启动到结束会依次执行以下流程:
-
初始化参数:从配置文件读取与合并参数,得出最终的参数
-
开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,开始执行编译
-
确定入口:根据配置中的 entry 找出所有的入口文件
-
编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理
-
完成模块编译:在经过第4步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系
-
输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会
-
输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。
在以上过程中,webpack 会在特定的时间点广播出特定的事件,插件在监听到感兴趣的事件后会执行特定的逻辑,并且插件可以调用 webpack 提供的 API 改变 webpack 的运行结果
4、说一下 webpack 的热更新原理(必会)
webpack 的热更新又称热替换(Hot Module Replacement),缩写为 HMR。这个机制可以做到不用刷新浏览器而将新变更的模块替换掉旧的模块。
HMR的核心就是客户端从服务端拉去更新后的文件,准确的说是 chunk diff (chunk 需要更新的部分),实际上 WDS(webpack-dev-server) 与浏览器之间维护了一个 Websocket,当本地资源发生变化时,WDS 会向浏览器推送更新,并带上构建时的 hash,让客户端与上一次资源进行对比。客户端对比出差异后会向 WDS 发请求来获取更改内容(文件列表、hash),这样客户端就可以再借助这些信息继续向 WDS 发起 jsonp 请求获取该chunk的增量更新。
后续的部分(拿到增量更新之后如何处理?哪些状态该保留?哪些又需要更新?)由 HotModulePlugin 来完成,提供了相关 API 以供开发者针对自身场景进行处理,像react-hot-loader 和 vue-loader 都是借助这些 API 实现 HMR。
5、webpack与grunt、gulp的不同?(必会)
1) 三者之间的区别
三者都是前端构建工具,grunt和gulp在早期比较流行,现在webpack相对来说比较主流,不过一些轻量化的任务还是会用gulp来处理,比如单独打包CSS文件等。
grunt和gulp是基于任务和流(Task、Stream)的。类似jQuery,找到一个(或一类)文件,对其做一系列链式操作,更新流上的数据, 整条链式操作构成了一个任务,多个任务就构成了整个web的构建流程。
webpack是基于入口的。webpack会自动地递归解析入口所需要加载的所有资源文件,然后用不同的Loader来处理不同的文件,用Plugin来扩展webpack功能。
2) 从构建思路来说
gulp和grunt需要开发者将整个前端构建过程拆分成多个Task
,并合理控制所有Task
的调用关系 webpack需要开发者找到入口,并需要清楚对于不同的资源应该使用什么Loader做何种解析和加工
3) 对于知识背景来说
gulp更像后端开发者的思路,需要对于整个流程了如指掌 webpack更倾向于前端开发者的思路
6、有哪些常见的Loader?他们是解决什么问题的?(必会)
1、 file-loader:把文件输出到一个文件夹中,在代码中通过相对 URL 去引用输出的文件
2、 url-loader:和 file-loader 类似,但是能在文件很小的情况下以 base64 的方式把文件内容注入到代码中去
3、 source-map-loader:加载额外的 Source Map 文件,以方便断点调试
4、 image-loader:加载并且压缩图片文件
5、 babel-loader:把 ES6 转换成 ES5
6、 css-loader:加载 CSS,支持模块化、压缩、文件导入等特性
7、 style-loader:把 CSS 代码注入到 JavaScript 中,通过 DOM 操作去加载 CSS。
8、 eslint-loader:通过 ESLint 检查 JavaScript 代码
7、Loader和Plugin的不同?(必会)
1) 不同的作用
loader直译为"加载器"。webpack将一切文件视为模块,但是webpack原生是只能解析js文件,如果想将其他文件也打包的话,就会用到loader。 所以loader的作用是让webpack拥有了加载和解析非JavaScript文件的能力。
Plugin直译为"插件"。Plugin可以扩展webpack的功能,让webpack具有更多的灵活性。 在 webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 webpack 提供的 API 改变输出结果。
2) 不同的用法
Loader在module.rules中配置,也就是说他作为模块的解析规则而存在。 类型为数组,每一项都是一个Object,里面描述了对于什么类型的文件(test),使用什么加载(loader)和使用的参数(options)
Plugin在plugins中单独配置。 类型为数组,每一项是一个plugin的实例,参数都通过构造函数传入。