学习目标
1.打包,把多个文件打成个数小的文件
2.支持模块化
3.优化,代码压缩,加密
配置webpack.config.js /使用入口出口
4.loader 一切皆模块 不同的文件用不同的loader来加载
5.plugin 扩展功能
webpack
概述 : 是一个现代的JavaScript应用程序的静态模块的打包器(module bundle)
静态:文件资源
模块:node环境,引入文件,遵守模块化语法.
less/sass ->css 多个文件 -->webpack(打包 翻译(es6/7/8的翻译成es5(兼容浏览器)) 压缩(把文件压缩合并(删除空格和注释))) --> .js .css .jpg .png
操作: 1.环境基于node 2.项目准备 3. 模块化的知识 模块化写代码 es6 commonjs模块化均可
安装并使用
**
1.安装node ,用npm init -y 初始化项目(生成package.json),在当前项目中安装webpack
2.创建一个文件(在文件中创建index.html,index.js,tool.js)初始化后
**
(1)开始:随着js个数增加,项目不好管理 (解决 :模块化+webpack打包)
//index.html
<div id="app">
</div>
<!-- 引入两个js文件 -->
<script src="./tool.js"></script>
<script src="./index.js"></script>
//tool.js
const updateDom = (id, content) =>{
window.document.getElementById(id).innerHTML = content
}
//index.js
updateDom ('app','index.html')
**安装webpack **npm i webpack webpack-cli -D
**考虑到不同的项目中可能使用不同的webpack版本,所以不推荐大家全局安装.特别是一些老项目,一定要注意webpack版本号. 采用局部安装的方式来安装它,注意,它只是一个开发依赖,并不是生产依赖,所以在命令行中加上-D。 **
(2) npx是npm5.2之后提供的新功能。可以通过npx -v来检测它的版本
验证webpack安装成功 方式一:node_modules\.bin\webpack -v 方式二:npx webpack -v
修改模块化的方式来改写代码
(3)在tool.js导出模块,它用来提供一个方法,供其它模块来使用。这里使用commonjs规范(就是node.js中的导出模块的方式)导出工具方法。
const updateDom = (id, content) =>{
window.document.getElementById(id).innerHTML = content
}
module.exports = {
updateDom
}
在index.js中导入模块,在index.js中引入tool.js中的定义的方法。注意,这里已经涉及到了在一个js中引用另一个js
const {
updateDom } = require('./tool')
updateDom ('app','index.html')
(4)用webpack命令处理index.js
npx webpack ./index.js
# 或者是
node_modules/.bin/webpack index.js
.处理结果:
结果:引入js到index.html页面显示成功
**
1.为啥要用webpack,默认情况下浏览器并不支持模块化,而我们的前端项目又使用了模块化,有了webpack之后,就可以突破这个限制了。
2. webpack可以把多个相互引用的.js文件打包成一个文件,且文件有加密,压缩的效果,上线更安全。
3. nodejs起了什么作用,node环境文件进行读写操作 , 最终生成的main.js并不是在nodejs环境中运行的,整个的项目效果还是在浏览器中运行的。**
认识webpack配置文件
作用:
a. 是。找到这个指定的配置文件
b. 否。去项目根目录找是否有一个名为webpack.config.js的文件。
ⅰ. 找到。使用即可。
ⅱ. 找不到。采用默认配置。
(1).在项目根目录下创建一个名为webpack.config.js
module.exports = {
mode: 'development', // 打包方式
}
这个文件的意义是导出一个配置项:用来对webpack的打包行为做设置。在操作层面,就是学习如何去使用这个文件。然后,再次运行打包命令,查看产生的main.js文件的内容,对比与之间的变化。
**
● 默认入口是:./src/index.js
● 默认出口是:./dist/main.js。**
(2)修改目录结构,新建一个src目录,并把index.js,tool.js,tooles6.js移动到它下面。
直接省略入口文件,直接打包: npx webpack 由于在src目录已经存在index.js
设置入口文件
(3)● 这个入口文件不是index.js,而是main.js
● 整体js文件不是放在src目录下,而是src/js下。
module.exports = {
mode: 'development', // 打包方式
entry:'./src/js/main.js' // 入口文件
}
a.重新打包,测试。
设置出口文件
在webpack.config.js中设置output项。
1.目标: 把出口文件设置为在build目录下的bundle.js
// 引入nodejs中的核心模块
const path = require('path')
console.log(path.join(__dirname,'/build'))
module.exports = {
mode: "production",
entry: './src/js/main.js', // 入口文件
output: {
"path": path.join(__dirname,'/build'), // 决定出口文件在哪里
"filename": "bundle.js" // 设置出口文件的名字。默认情况下,它叫main.js
}
}
● output中的filename用来指定打包后的文件名字。
● output中的path用来指定打包后的路径。注意:它必须是绝对路径。所以,这里引用path模块中的join和__dirname来生成绝对路径。
● 如果path中的路径不存在,它会自动创建。
修改打包模式
webpack.config.js中的mode项用来设置打包的方式,如果不设置,会默认为production。
module.exports = {
mode:"development"
}
● development :开发模式(代码不会压缩 混淆)
● production:生产模式(压缩,混淆,加密… 不可读)
在打包时指定配置文件
下面,自已创建一个webpack.dev.js的文件,用它来做配置文件。
在项目根目录下创建webpack.dev.js,内容如下:
module.exports = {
output:{
filename:'boundle.js'
}
}
下面,希望使用这个配置文件中的设置来打包。
它的格式是:npx webpack --config webpack
的配置文件运行命令:npx webpack --config webpack.dev.js
简化打包命令
背景
当涉及多个打包配置要指定时,打包命令比比较复杂,难以记忆。
定制script
可以在package.json中添加script命令来快速启动webpack,格式如下:
"scripts": {
"自定义命令名": "要具体执行的代码",
}
//示例
package.json JavaScript 复制代码
"scripts": {
+ "dev": "webpack --config webpack.dev.js",
+ "build": "webpack",
"test": "echo "Error: no test specified" && exit 1" }
注意:在script中不再需要添加npx。它会自动在node_modules/.bin中去找命令。
这样 ,我们就得到了两个可以执行的命令: dev, build 。
可以在根目录下的小黑窗中通过:
npm run build, npm run dev 来运行
2.webpack基础使用阶段小结
● webpack的配置文件默认名是webpack.config.js ,也可以单独指定
● 学习webpack就学习webpack.config.js的使用。
● 把webpack的命令集成到script中可以简化打包命令。
● 可以自行定义入口和出口文件
loader处理css/less
(1) loader整体介绍
在webpack看来 一切皆模块,图片,样式文件,js文件… 。 但是webpack默认只能处理js模块,对于非js的内容,例如css, less文件,图片文件等等它就需要一些帮手来处理了。这些帮手就是loader。
(2) webpack 可以使用 loader 来预处理文件。这允许你打包除 JavaScript 之外的任何静态资源。你可以使用 Node.js 来很简单地编写自己的 loader。
loader处理css文件
创建.css文件
引入css文件之后的变化 Plain Text 复制代码
src/css/public.css的内容如下 CSS
body,html{
padding:0;
font-size:14px;}
src/css/style.css的内容如下
@import "public.css";
div {
border:4px solid #ccc;
width: 50%;
height: 200px;
margin:30px auto;
box-shadow: 3px 3px 3px #ccc;
background-color: #fff;
text-align: center;
}
说明:css的@import语句用来导入另一个css文件。
在.js中导入css
import Vue from 'vue';
import ElementUI from 'element-ui';
// 引入 css
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue';
Vue.use(ElementUI);
new Vue({
el: '#app',
render: h => h(App)
});
很明显,上面的.js代码中引入了.css。
下面,我们修改自已的main.js,在 src/js/main.js中,引入css。
// nodejs中的模块化
const {
updateDom } = require('./tool')
// es6中的模块化
import {
log} from './tooles6'
import '../css/style.css'
updateDom ('app','index.html')
log('test')
再次,打包代码,会报错,上面报错的原因是:webpack把.css文件内容当作了js代码来运行,那当然会报错了。所以,解决方法是安装相应的loader来处理。
安装并使用css-loader
对1.于loader的使 用,其基本步骤是一致的,分成两步:
2. 安装npm包
配置webpack.config.js中的module
安装npm i css-loader -D
安装包的命令是:它也是开发依赖。
在配置文件中使用
修改webpack.config.js文件,添加module
const path = require('path')
module.exports = {
mode: 'development',
entry:'./src/js/main.js',
output:{
path:path.resolve(__dirname, './build'),
filename:'bundle.js'
},
+ module:{
// 处理非js模块
+ rules:[ // 规则
+ {
+ test: /\.css$/, // 正则测试
+ use: ['css-loader'] // loader
+ }
+ ]
+ }
}
**再次打包,**它不会报错。但是,页面上也并没有出现样式的效果。打包之后的文件中并没有包含css代码。
安装并使用style-loader
如果我们希望样式生效,最终在.html文件中有两种情况:
● 有style标签
● 有link标签
而css-loader 只是能让你在.js中通过import来引入.css,如果你希望引入的css代码最终以style标签的方式插入到html页面中,则还需要安装一个loader:style-loader
安装
npm i style-loader -D
配置
webpack.confg.js
const path = require('path')
module.exports = {
mode: 'development',
entry:'./src/js/main.js',
output:{
publicPath:'https://www.baidu.com',
path:path.resolve(__dirname, './build'),
filename:'bundle.js'
},
module:{
// 处理非js模块
rules:[ // 规则
{
test: /\.css$/, // 正则测试
use: ['style-loader','css-loader'] // loader
}
]
}
}
Tip: 在有多个loader的情况下,use数组中的loader执行顺序是从右到左的过程。即:
● 先用css-loader来处理css
● 再用style-loader把css代码插入到html中的style标签中。
打包查看效果
loader处理less文件
如果希望处理less文件,则还需要去安装额外的包。
创建less文件
在src目录的less目录下创建 index.less,
@import "../css/style.css";
body{
div {
color: red;
}
}
在.js中引用.less
在src/js/main.js文件中引入less
// nodejs中的模块化
const {
updateDom } = require('./tool')
// es6中的模块化
import {
log} from './tooles6'
- import '../css/style.css'
+ import '../less/index.less'
updateDom ('app','index.html')
log('test')
安装包
参考官网添加链接描述
npm i less-loader less -D
-------------------------
+ less@3.11.2
+ less-loader@6.1.0
added 50 packages from 123 contributors in 23.883s
● less 用来把less–>css
● less-loader用来加载less文件。
配置模块
在rules中添加一个配置,专门针对less文件。
module.exports = {
// 非js模块,在这里处理
module: {
rules: [ // 规则
{
test: /\.css$/, // 正则匹配,以.css结尾的文件
// 如果发现是.css文件,则由如下两个loader来处理
// 处理的顺序是 从右向左
// css-loader: 作用是允许.js中引入.css
// style-loader:作用是在.html上创建style标签,把css代码输入进去
use: ['style-loader','css-loader'] // 匹配成功,使用指定的loader
},
+ {
+ test: /\.less$/, // 正则匹配,以.less结尾的文件
// 如果发现是.less文件,则由如下三个loader来处理
// 处理的顺序是 从右向左
// less-loader: 作用是加载less文件,会帮你less转成css
// css-loader: 作用是允许.js中引入.css
// style-loader:作用是在.html上创建style标签,把css代码输入进去
+ use: ['style-loader','css-loader','less-loader'] // 匹配成功,使用指定的loader
+ }
]
}
}
注意:如上配置中 ,对于less文件的处理涉及三个loader,其处理顺序是less-loader --> css-loader–>style-loader。
● less-loader:用来加载less文件,并处理成css
● css-loader:用来加载css文件
● style-loader:用来将css代码以style标签的格式插入到html文件中
处理资源文件
目标:处理资源文件。假设在css中引入图片,要怎么处理呢?
30
在项目中引入图片
在src下新增目录,img,并在其下放置两张图片。注意:一张图片大一些,一张图片小一些(可以自行决
定)。
○ webpack.png: 49.4kb
○ webpack.svg: 3kb
目录结构 Plain Text 复制代码
1
项目名
2 ├── index.html
3 ├── src
4 │ ├── less
5 │ │ └── index.less
6 │ ├── img
7 │ │ ├── webpack.png
8 │ │ └── webpack.svg
9 │ ├── css
10 │ │ ├── public.css
11 │ │ └── style.css
12 │ └── js
13 │├── main.js
14 │├── tool.js
15 │└── tooles6.js
16 └── package.json
使用图片
两种方式使用图片:
● 作为css的背景图
● 作为独立的图片资源使用
在style.css中引入图片,作为div标签的background。
31
Dif 复制代码
1 @import “public.css”;
2div {
3border:4px solid #ccc;
4width: 50%;
5height: 200px;
6margin:30px auto;
7box-shadow: 3px 3px 3px #ccc;
8 background-color:pink;
9text-align: center;
10 + background-image: url(‘…/img/webpack.svg’)
11 }
在src/main.js中,通过代码 - 把大图插入到创建的img标签上, 添加body上显示
JavaScript 复制代码
1 // -
2 引入图片 使用
import imgUrl from ‘…/img/webpack.png’
3 const theImg = document.createElement(“img”)
4theImg.src = imgUrl
5document.body.appendChild(theImg)
配置
5
webpack 内置处理方案, 只需要填入配置即可参考:asset module资源模块文档
webpack.config.js中的内容如下
32
JavaScript 复制代码
1 module: {
2 rules: [
3 // …
4 { 省略其他
5 test: /.(png|jpg|gif|jpeg)$/i, //
6 type: ‘asset’ // data URI 匹配图片文件
7 } 在导出一个 和一个单独的文件之间自动选择
8 ]
9}
打包后运行dist/index.html观察区别
loader小结
● 一切皆模块,不同的模块有不同的loader
● loader
○ 第一步:安装包
○ 第二步:配置rules
plugin整体说明
webpack中除了loader之外,还有一个核心概念:plugin,中文就是插件。它可以用来增强webpack的功能。
plugin是用于扩展webpack的功能,各种各样的plugin几乎可以让webpack做任何与构建相关关的事情。
plugin的配置很简单,plugins配置项接收一个数组,数组里的每一项都是一个要使用的plugin的实例,plugin需要的参数通过构造函数传入。
33
使用plugin的难点在于plugin本身的配置项,而不是如何在webpack中引入plugin,几乎所有webpack无法直接 实现的功能,都能找到开源的plugin去解决,我们要做的就是去找更据自己的需要找出相应的plugin。
html-webpack-plugin
功能:把我们自已写的.html文件复制到指定打包出口目录下,并引入相关的资源代码。
为html文件中引入的外部资源如script、link动态添加每次compile后的hash,防止引用缓存的外部文件问题。可以生成创建html入口文件。
官网:https://www.npmjs.com/package/html-webpack-plugin
实现步骤:
下载安装
命令:npm i html-webpack-plugin -D
配置
在webpack.config.js中,做两件事:
引入插件
Plain Text 复制代码
1 const HtmlWebpackPlugin = require(‘html-webpack-plugin’);
添加一个plugins配置
34
webpack.confg.js JavaScript 复制代码
1 const HtmlWebpackPlugin = require(‘html-webpack-plugin’);
2 // nodejs
3 引入 中的核心模块
const path = require(‘path’)
4 console.log(path.join(__dirname,‘/build’)) 5 module.exports = {
6 mode: “production”,
7 entry: ‘./src/js/main.js’, //
8 output: { }, 入口文件
12 // js
非 模块,在这里处理
13 module: { },
51 plugins: [
52 new HtmlWebpackPlugin({ // HTML
53 minify: { // HTML 打包输出
54 压缩 文件 HTML
removeComments: true, //
55 移除 中的注释
collapseWhitespace: true, // 删除空白符与换行符
56 minifyCSS: true// css
57 }, 压缩内联
58 filename: ‘index.html’,
59 template: path.resolve(‘./index.html’) //
60 }) 指定模块的位置
61 ]
62 }
打包测试
● 它会把template中指定的.html文件复 制(压缩)到出口文件夹
● 还会自动附上打包之后.css和 .js代码
clean-webpack-plugin
在生成打包文件之前,把目录清空掉。
安装
npm i clean-webpack-plugin -D
修改配置文件
引入:
35
Plain Text 复制代码
1 const { CleanWebpackPlugin } = require(‘clean-webpack-plugin’)
添加plugins
配置文件 Plain Text 复制代码
1 plugins:[
2 new CleanWebpackPlugin()
3 … ,
4 ] 其它
plugin小结
plugin用来增加webpack能力。
步骤:
- 下载安装
配置webpack.config.js
a.
b. 引入
添加plugins的设置
webpack实时打包
目标
实现实时打包预览效果。当我们修改了代码时,立即运行打包命令,并显示效果。
工具:[webpack-dev-server]
36
● npm官网
● 配置手册
注意 :
● 项目开发都是对src目录内部的文件进行更新,不要去修改dist打包好的文件
● 现在对src内部的任何文件做修改操作后,都需要重新打包,才可以看到对应效果
步骤
安装
Bash 复制代码
1 npm i webpack-dev-server -D
2 -------------------------------
3+ webpack-dev-server@3.11.0
4added 395 packages from 272 contributors in 62.727s
在webpack.config.js中做如下配置
JSON 复制代码
1 module.exports = {
2 // …
3 其他省略
4 // webpack-dev-server
5 配置 的选项
devServer: {
6 host: ‘127.0.0.1’, // ip
7 port: 10088, // 配置启动 地址
配置端口
8 open: true //
9 } 配置是否自动打开浏览器
10 }
在package.json中补充一个script
37
Dif 复制代码
1 “scripts”: {
2 +“dev”: “webpack-dev-server”,
3 // webpack.config.js
4 它默认会找 文件
5 “build”: “webpack-dev-server --config webpack.config.js”
6 // webpack.config.js
7 }, 指定使用 配置文件文件
启动命令 npm run dev
现在通过 就可以实现实时打包、实时编译、实时浏览器查看效果了。它会自动打
- 开一个浏览器窗口。测试
○ 修改.js代码,
○ 修改.css代码,检查是否会重启
注意:
浏览器看到的实时效果是服务器通过“ 内存 ”提供的,没有物理文件,也不会生成dist目录
拓展:babel-loader
6 5
能够把es 高级内容变为es 的loader名称为 babel-loader
6 7 8
es /es /es 等等高级标准有很多(let、箭头函数、对象解构赋值、…展开运算符、反勾号字符串等等),每个标准都需要一个独立的plugin进行降级处理,如果使用许多高级标准内容,那么势必要为此安装许多plugin,这样工作比较繁琐,系统已经考虑到这点了,其通过preset把许多常用的plugin给做了集合,因此一般性的使用只需要安装preset即可搞定(如果项目应用到了一个生僻的高级标准内容,preset处理不来,就还需要再安装对应的plugin处理)
let----降级---->plugin
38
箭头函数----降级—>plugin
npm官网: babel-loader
babel官网:https://www.babeljs.cn/setup#installation
步骤:
安装依赖包
Bash 复制代码
1 npm i babel-loader @babel/core @babel/preset-env -D
在webpack.config.js中做如下配置:
JavaScript 复制代码
1 {
2 test: /.js$/,
3 exclude: /node_modules/, //
4 use: [ 排除目录
5 {
6 loader:‘babel-loader’,
7 options: {
8 presets: [‘@babel/preset-env’]
9 }
10 }
11 ] // es6 es5
12} 转
说3.明 : @babel/preset-env用来指定按什么样的预设来进行降级处理打包测试
6 5
打包之后,去打包后的文件中检查是否已经把const和箭头函数这种es 的代码转成了es 的代码。
拓展:source map的说明
39
目标: source map概念, 用于在浏览器调试错误使用, 记录代码打包前原始位置
准备: src/main.js产生一个未定义变量的报错, 启动webpack服务器
JavaScript 复制代码
1 console.log(abc); // abc
不要声明 变量
问题: 看浏览器-控制台报错信息, 但是发现看不出哪行代码报错了
原因: webpack对代码, 压缩, 混淆, 减小 文件的体积(提高文件的加载效率)
○ 变量被替换成没有任何语义的名称
○ 空行和注释被剔除, 压缩到一行
解决方案: 启用source map
开发环境
webpack.config.js - 配置
40
JavaScript 复制代码
1 module.exports = {
2 // …
3 其他配置
mode: ‘development’,
4 // development
5 开发模式 是 ,
// webpack
6 // 内部不会使用内置优化 不压缩代码
‘production’ ,
7 使用 上线生产模式 会压缩代码
8 + devtool: ‘cheap-module-source-map’,
9 // cheap-module-source-map ,
( eval ) 开发模式下使用 保证运行时的行数 和 源代码行数 一致
10 }默认不写是 模式
重新启动开发服务器/打包, 观察是否有错误代码打包前的位置信息了
生产环境
不显示源码, 但是可以看到哪行报错
JavaScript 复制代码
1 devtool: ‘nosources-source-map’
显示源码
41
JavaScript 复制代码
1 devtool: ‘source-map’
devtool值说明
规则字符串列表:https://webpack.docschina.org/configuration/devtool/
格式: [inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map (了解即可)
规则值 速度 位置 说明
false 建立:最快 无 不开启sourcemap( 规
重建:最快 则值写错也是这个)
inline 建立:最慢 内嵌 报错信息, 以及源码和
重建:最慢 源码位置信息
hidden 建立:最慢 独立map文件 报错信息, 没有源码和
重建:最慢 源码位置信息
eval 建立:快 内嵌 报错信息, 以及源码
重建:最快 (mode为development
时使用这个值)
cheap 建立:固定 独立map文件 报错信息, 以及源码和
重建:慢 源码的行数(没有列)
module 建立:慢 与别的一起用 是否为loaders加 载器
重建:快速 生成source map
[xxx-…]source-map 建立:最慢 独立map文件 报错信息, 以及源码和
重建:最慢 源码位置信息
nosource 建立:最慢 独立map文件 报错信息, 不显示源码
重建:最慢
42
总结: 名字如何组合, 还要看上面文档, 不记录快于 内嵌快于 独立文件
devtool常用组合
6
拓展:使用es 6模块化
webpack中也是支持es 模块化的。
6
新建tooles .js文件,内容如下:
6
tooles .js的文件内容 JavaScript 复制代码
1 const log = (content) => {
2 console.log(Date.now(),content)
3 }
4
5// es6
的导入
6 export { log }
43
6
注意,这里采用的是es 中的模块化导出。
接下来,在index.js中引入,并使用这个模块
index.js中引入模块 JavaScript 复制代码
1 // nodejs
中的模块化
2 const { updateDom } = require(‘./tool’)
3 // es6
中的模块化
4 import {log} from ‘./tooles6’
5
6 updateDom (‘app’,‘index.html’)
7log(‘test’)
最后,打包 index.js ,在index.html中测试。
6
它可以处理es 的模块化和nodejs中的模块化。
总结webpack(前端工程化)常见问答
1
、什么是webpack
- webpack是一个javascript的静态模块打包工具
webpack里一切文件皆模块,通过loader转换文件,通过plugin注入钩子,增强功能
44
最后输出由多个模块组合成的文件,webpack专注构建模块化项目
2
、webpack的优点是什么?
-
专注于处理模块化的项目,能做到开箱即用,一步到位
-
通过plugin扩展, 完整好用又不失灵活
-
通过loaders扩展, 可以让webpack把所有类型的文件都解析打包
社区庞大活跃,经常引入紧跟时代发展的新特性,能为大多数场景找到已有的开源扩展
3
、webpack的构建流程是什么?从读取配置到输出文件这个过程尽量说全
webpack 的运行流程是一个串行的过程,从启动到结束会依次执行以下流程:
-
初始化参数:从配置文件读取与合并参数,得出最终的参数
-
开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,开始执行编译
-
确定入口:根据配置中的 entry 找出所有的入口文件
编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行翻译,再找出该模块依赖的模
块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理
5. 4
完成模块编译:在经过第 步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容
6. 以及它们之间的依赖关系
输出资 源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk, 再把每个
7. Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会
输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。
在以上过程中,webpack 会在特定的时间点广播出特定的事件,插件在监听到 感兴趣的事件后会执行特定的逻辑,并且插件可以调用 webpack 提供的 API 改变 webpack 的运行结果
4
、说一下 webpack 的热更新原理(必会)
webpack 的热更新又称热替换(Hot Module Replacement),缩写为 HMR。这个机制可以做到不用刷新浏览器而将新变更的模块替换掉旧的模块。
45
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
、有哪些常见的Loader?他们是解决什么问题的?(必会)
1
、 file-loader:把文件输出到一个文件夹中,在代码中通过相对 URL 去引用输出的文件
2
、 url-loader:和
代码中去
file-loader
类似,但是能在文件很小的情况下以 base
64
的方式把文件内容注入到
3
、 source-map-loader:加载额外的 Source Map 文件,以方便断点调试
4
、 image-loader:加载并且压缩图片文件
5 6 5
、 babel-loader:把 ES 转换成ES
6
、 css-loader:加载 CSS,支持模块化、压缩、文件导入等特性
7
、 style-loader:把 CSS 代码注入到 JavaScript 中,通过 DOM 操作去加载 CSS。
8
、 eslint-loader:通过 ESLint 检查 JavaScript 代码
6
、Loader和Plugin的不同?
1
) 不同的作用
loader直译为"加载器"。webpack将一切文 件视为模块,但是webpack原生是只能解析js文件,如果想将其他文件也打包的话, 就会用到loader。 所以loader的作用是让webpack拥有了加载和解析非JavaScript文件的能力。
46
Plugin直译为"插件"。Plugin可以扩展webpack的功能,让webpack具有更多的灵活性。 在 webpack 运行的生命周期中会 广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 webpack 提供的 API 改变输出结果。
2
) 不同的用法
Loader在module.rules中配置,也就是说他作为模块的解析规则而存在。 类型为数组,每一项都是一个Object,里面描述了对于什么类型的文件(test),使用什么加载(loader)和使用的参数(options)
Plugin在plugins中单独配置。 类型为数组,每一项是一个plugin的实例,参数都通过构造函数传入。