05-webpack串讲

7/26/2023

# 一. webpack5串讲

# 1,认识webpack

官网:https://webpack.js.org/

介绍:

1673659104344

我们之前写项目,使用的vue-element-admin也是基于webpack的,之前我们通过vue-cli创建的项目也是基于webpack的。今天我们需要自己去搭建开发环境,不使用官方提供的脚手架。

总结:

  • webapck是一个构建工具,是基于node的,电脑上必须安装node,node版本需要大于16
  • 打包器,是从入口开始,按照模块依赖进行打包,最终得到浏览器的可以识别的静态资源。
  • 从某种程度来说,webpack代表的是一种架构能力。

# 2,搭建环境

创建一个文件夹,如下:

1673659309870

初始化一个配置文件,如下:

1673659352842

安装webpack,webpack-cli。webpack是核心包,提供了很多的API,插件。webpack-cli提供了很多命令。

我们有两种安装方式,第一种,全局安装, (不推荐),全局安装相当它把当成一个工具进行安装了。如下:

  • cnpm i webpack -g
  • cnpm i webpack-cli -g

第二种,就是在项目中安装(推荐),如下:

  • cnpm i webpack -D // -D表示开发依赖
  • cnpm i webpack-cli -D

我们采用局部安装(项目中安装),如下:

1673659593364

1673659688080

测试你的webpack是否安装成功,如下:

1673659819422

学习webpack,就是学习一堆的配置,这些配置你也不需要记,官方说,你要配置,需要在项目的根目录下面创建一个webpack.config.js文件,如下:

1673660309809

1673660233180

开始打包,如下:

1673660364026

看一下,打包后文件,如下:

1673660391773

需要webpack.config.js文件名变了,打包时,需要手动指定,如下:

1673660464891

还可以配置一个脚本,如下:

1673660553421

运行脚本,如下:

1673660585890

需要通过yarn,是不需要run,直接yarn build就OK。

# 3,入口和出口

入口有三种写法,上面的是第一种写法,使用的是相对路径,也可以使用绝对路径,如下:

1673661641543

入口还可以写成对象的形式,如下:

1673661775303

看一上vue打包后资源如下:

1673661929507

然后指定出口,如下:

1673662038621

出口必须指定绝地路径,如下:

1673662103800

最好还是叫dist,有的地方,叫build,我们就叫dist。也可以在出口中指定打包后的文件叫什么,如下:

1673662233526

说一下单词,如下:

1673662338838

filename可以指定一个格式化字符串,如下:

1673662420436

如果使用了格式化字符串,可以指定hash值,如下:

1673662770690

说白了,输入的JS模块所依赖的源码发生了变化,打包时,hash值也会发生变化,用于解决浏览器缓存导致页面不刷新的问题。

能不能把打后的js文件,放到js文件夹下面的,可以的,如下:

1673663047618

# 4,配置开发服务器

前面打包是把包打包到硬盘上的。在开发时,需要配置一个开发服务器,这个开发服务器可以直接让我们在内存中打包,速度是远远高于硬盘的。我们之前用的脚手架,都是在内存中打开。

安装一个开发服务器,叫webpack-dev-server,如下:

1673663252238

安装之,如下:

1673663339984

配置之,如下:

1673663431092

之前打包是使用webpack进行打包的,直接是在硬盘上的打包,现在我们需要使用内存打,如下:

1673663511595

访问之,如下:

1673663566036

可以配置一个脚本,如下 :

1676859460511

执行脚本,如下:

1673663640267

不管是硬盘打包还是内存打包,都会报一个警告,如下:

1673663722742

可以指定mode,如下:

1673663807147

再看一下,还有没有警告,如下 :

1673663841520

# 5,创建页面,把打包后的js插入页面

创建一个页面,如下:

1673664039068

我们在内存中打包,如下:

1673664081862

访问之,如下:

1673664098622

你要知道,你刚才是内存打包,在内存是有打包后的js文件的,能不能把打包的的js插入到上面的页面中呢?看一下,如下 :

1673664212392

结论,并没有把打包后的js文件,插入到页面中,那个我们就使用一个插件,叫html-webpack-plugin,如下:

1673664330859

安装之,如下:

1673664388709

使用之,如下:

1673664618892

再次在内存中打包,如下:

1673664640822

测试之,如下:

1673664668353

在硬盘上打包试一下,如下:

1673664720986

再一下vue脚手架,如下:

1673664811692

# 6,区分硬盘打包和内存打包

打包分两种,一种是开发时的打包,一种是生产时的打包。不同的打包方式,是有不同的配置的,现在有两种打包方式,也就是说有两种配置,但是这两种配置中有一些公共的配置,把这些配置区分出来,创建如下的文件,如下:

1673665746786

先写公共的配置,如下:

1673666013275

开发配置,如下:

1673666029890

生产配置,如下:

1673666046511

在webpack.config.js中使用之,如下:

1673666141646

配置脚本,如下:

1673666211528

在webpack.config.js中就可以得到env,如下:

1673666494716

简写如下:

1673666622157

不能使用原生js合并,需要使用来合并,如下:

1673666689625

安装之,如下:

1673666738019

使用之,如下:

1673666892530

测试之,如下:

1673667005415

1673667040989

1673667053076

# 7,html-webpack-plugin

之前,在硬盘上打包,都会生成dist,下一次打包还会生成dist,但是之前dist下面的文件并不会自动删除,如果你想每一次打包都删除上次dist下面的文件,配置如下:

1673676622102

测试如下:

1673676602290

接下来,讲webpack-html-plugin这个插件。看官网:

1673676726465

上午我们已经安装这了,并使用了。如下:

1673676752040

上面配置了template,是用来指定页面的位置,可以使用绝对路径,如下:

1673676829843

默认它把打包后js插入到了head标签中,打包查看如下:

1673676862108

1673676907077

看一下vue脚手架,它是把js插入到了什么方,如下:

1673677002900

配置如下:

1673677057736

测试如下:

1673677080383

1673677105235

还可以做一些基本的配置,如下:

1673677199181

还需要在页面中title标签位置写如下代码:

1673677374506

测试如下:

1673677389895

还可以配置一个小icon,制作一个icon,如下:

1673677538282

1673677687106

在页面中就可以使用之,如下:

1673677814563

# 8,ProgressPlugin

是webpack内置的插件,如下:

1673678117414

使用之,如下:

1673678208418

再次打包,如下:

1673678271822

配置hander,如下:

1673678509624

# 9,babel

在入口中写一点ES6+的代码如下:

1673678715947

1673678758206

打包,测试浏览器能不能识别,如下:

1673678807166

1673678838900

发现,谷歌浏览器可以识别。但是有的浏览器是不认识的。再一个更新的语法,如下:

1673679123934

再次打包,如下:

1673679190229

1673679212266

也就是说,webapck对于ES6+中的一些语法,它也不能直接转化成ES5,不能转化成ES5,浏览器对ES5的兼容性是最好,我们需要使用loader,loader就是把webpack不能识别的模块,转化成webpack可以识别的模块。如下:

1673679312728

JS模块中有高级语法,高级语法,如何转化成低级语法,让webpack识别呢?

答:最最最最最厉害的就是babel。

要使用babel,就需要安装babel,如下:

1673679401018

1673679485946

安装之,如下:

1673679518847

1673679565258

配置配置,如下:

1673679849638

再次打包,如下:

1673679918976

ES6中的语法,非常多,你要转化语法,需要安装对应插件,如你要把箭头函数转化成普通函数,那你就需要安装一个箭头函数转普通函数的插件,如你要把let转化成var,你需要安装一把let转成var的插件。也就说如果项目中用到了非常多的ES6语法,都需要转化,那就可以安装500个插件,babel给我们封装了很多预设,预设是插件集合,也就是集合中包含了很多的插件,如有一个预设,它可以把ES6中的大部分语法,转化成ES5,这个预设叫@babel/preset-evn。预设并不是转化所有语法,仅仅是大部分的,个别语法转化不了,需要单独安装插件。我们先去安装 预设,如下:

1673680181490

然后需要配置,如下:

1673680496226

再次打包,如下:

1673680539475

说明,你上面使用的预设不能打包装饰器,需要单独去安装对应的插件(打补丁),如下:

1673680686018

1673680700095

安装如下:

1673680736153

1673680966006

使用如下:

1673680793320

配置如下:

1673680874406

安装完后,打包如下:

1673681009332

1673681033080

后面我们需要学习一堆的loader,去转化不同的模块(使用loader来处理)。

  • .js
  • .vue vue-loader
  • .jsx
  • .ts
  • .png
  • .less
  • .sass
  • .css
  • .json
  • .....

后面我们也需要学习一堆的插件,插件是用来增强webpack。

# 10,打包JSX模块

react也是一个模块,如下:

1674958543598

看一下版本,如下 :

1674958578405

安装之,如下:

1674958665655

还需要安装一个react-dom模块,如下:

1674958697634

创建一个App.jsx组件,如下:

1674959113648

在main.js中引入,并渲染,如下:

1674959132595

打包main.js,你要知道,main.js中引入了一个jsx模块,如下:

1674959177747

说明,webpack,默认情况下是不能处理jsx文件的,此时,就需要使用babel进行编译,说到babel就要想到预设和插件,此时,jsx就需要一个预设来处理,如下:

1674959304739

安装预设,如下:

1674959354319

进行配置,如下:

1674959516418

再进行打包,如下:

1674959623861

还需要配置一个loder,如下:

1674959857628

再次打包,如下:

1674959929721

使用浏览器访问之,如下:

1674959972627

是在main.js中报错了。但是我们在main.js中并没有使用React,说明人家背后使用到了react,所以我们需要引入React,如下:

1674960069387

在浏览器中再次测试之,如下:

1674960095199

到此,打包jsx(react中的组件)就OK了,你可以尝试打包一下vue文件,你就创建一个App.vue,尝试打包,100%打包不成功。因为webpack压根不认识.vue文件,你需要安装对应的loader和预设,使用loader加载你的.vue文件,使用预设去翻译你的vue代码。

# 11,配置source-map

先看一个问题,代码如下:

1674961402306

看一下控制台,如下:

1674961523900

如果想让代码的报错位置正确,需要配置一个devtool,如下:

1674961636130

1674961699005

不同的配置代表的含义是不一样的。配置如下:

1674961931658

此时报错的位置和控制台中就保持一样的了,如下:

1674961976036

在生产中,配置如下 :

1674962049314

在硬盘上打包,如下:

1674962305448

# 12,ProvidePlugin

分析:

1674962593931

如何把某些包放到全局中,此时需要使用ProvidePlugin,如下:

1674962652639

配置之,如下:

1674962855026

动了配置文件,需要重新打包,再去访问之,如下:

1674962932591

打包时,我们不希望webpack去打包node_module,配置如下:

1674963048930

# 13,把第三方包抽离出来

现在尝试去打包,如下:

1674963277817

你可以看一下,你之前,打包vue,生成的js文件,如下:

1674963453350

现在就需要把第三方包抽离出来,如下:

1674963819323

再次打包如下:

1674963877101

1674963918603

# 14,打包css和sass

写一点样式,如下:

1674964140239

在入口文件中,引入css文件,如下:

1674964183914

不用想,webpack肯定不能加载css文件,肯定是需要一个loader进行加载的,测试如下:

1674964256933

此时,就需要安装对应的loader,如下:

1674964300700

对css模块处理,需要安装两个laoder,如下:

1674964347214

1674964373916

开始配置,如下:

1674964578410

看浏览器控制台:

1674964616308

在生产打包时,需要把css抽离出来,此时我们需要用到一个插件,这个插件中带了一个loader,安装一下:

1674972259424

1674972285597

配置如下:

1674972491105

打包如下:

1674972508653

看打包后的资源如下:

1674972527430

在内存中打包如下:

1674972546662

测试如下:

1674972610403

现在希望把打包后的样式放到css文件夹,并且加上hash值,解决缓存问题,如下:

1674972769539

打包如下:

1674972781538

测试如下 :

1674972799109

1674972828477

也就是说,在开发时,样式,采用的是内部样式,在上线时,样式采用的是外部样式。

然后打包scss,创建scss文件,如下 :

1674973077715

在入口文件中,引入,如下:

1674973110071

尝试打包,如下:

1674973161722

此时,就需要使用sass-loader来加载编译scss代码,安装如下:

1674973279683

配置如下:

1674973408799

看一下,是否可以处理scss代码,如下:

1674973440174

浏览器测试之,如下:

1674973455304

同理,如果是less也是一样的,需要使用less-loader来处理。

# 15,打包图片

在webpack眼中,一切都是模块,图片当然也是模块。准备一张图片,如下:

1674973572295

在App组件中,使用图片,如下:

1674973744010

测试如下:

1674973791860

在webpack4中,有两个laoder可以处理,在wabpack5中这两个laoder就淘汰了,这两个laoder如下:

  • url-loader
  • file-loader

我们还是简单去演示一下,如何使用,安装之如下:

1674973977528

配置如下:

1674974079533

测试如下 :

1674974112995

在硬盘上打包如下:

1674974147604

生成的文件如下:

1674974187441

使用url-loader再测试一下,如下 :

1674974231601

打包如下:

1674974298995

在硬盘上测试如下:

1674974383534

在webpack5中上面的两个laoder就淘汰了,对于图片的处理,webpack都内置好了,处理如下:

1674974519074

打包如下 :

1674974532438

测试如下:

1674974548839

可以进一步优化如下:

1674974684166

打包完,测试后,如下:

1674974706600

使用react写一个计算器,如下:

1674975118085

效果如下:

1674975129353

# 16,ESLint

eslint是用来进行代码检测。也非常重要,在很多公司,都是要求使用eslint的,如果代码写的不符合要求,有可能代码就提交到不到仓库。在很早之前,有一个laoder,叫eslint-loader来校验代码,现在这个laoder已经淘汰了。现在使用的是一个插件,如下:

1674976413669

1674976461582

安装之,如下:

1674976499427

还需要安装eslint,eslint里面包含了很多的校验规则,安装如下:

1674976746554

这个插件不能进行校验,这个插件是把eslint集成到webpack中的。代码校验是在开发时进行校验的,配置就需要配置到开发环境中,如下:

1674977038825

尝试打包一下,如下 :

1674977055732

在浏览器中看效果如下:

1674977119075

上面的插件仅仅是把eslint集成到webpack中,对于eslint的配置文件,还需要单独配置,打开eslint的官网,如下:

1674977194294

1674977282458

创建eslint的配置文件,有多种方式,如下:

1674977436794

创建一个eslint的配置文件,如下:

1674977677359

只要动了配置文件,都需要重启开发服务器,如下:

1674977700238

测试如下:

1674977825501

修改之如下:

1674977888992

同现main.js中也修改之,如下:

1674977916604

再次测试之,如下:

1674977934177

注释掉刚才的规则,如下:

1674978050297

现在尝试不加分号,如下:

1674978083566

动了配置文件,需要重启服务器,测试如下 :

1674978126605

eslint中都有哪些规则呢?如下:

1674978212118

再尝试使用一个,如下:

1674978285116

现在在代码中就写一个console,如下:

1674978326812

重启服务器,测试如下:

1674978380724

修改之,如下:

1674978429976

测试如下:

1674978458372

还需要知道,在控制台中也会给出提示,如下:

1674978503265

可以关闭规则,如下:

1674978568181

如果是警告提示,不弹出模态框,如下:

1674978641536

配置如下:

1674978700477

规则如下 :

1674978759577

重启,测试如下:

1674978810185

1674978836101

1674978854513

对于react代码中的jsx的校验,eslint规则并不完善,有一个公司,推出一个校验包,叫eslint-config-arbnb,如下:

1674979035556

直接下载eslint-config-airbnb不好下载,需要把它内置的其它都下载下来,如下:

1674979181235

看文档,如下:

1674979353387

集成airbnb对react代码的检测,如下:

1674979463197

此时,再打包,会报大量的错误,如下:

1674979498833

1674979518436

如果不想让eslint检测我们的src下面所有的代码,可以创建一个eslintignore的配置文件,如下:

1674980064389

在eslint中提供了一些注释,可以忽略对某一行或某一片代码的查检,如下:

1674980303499

总结解决eslint后错的方式:

  1. 创建一个eslint的配置文件,修改rules,rules是自定义规则。
  2. 使用eslint注释,非常多,临时地忽略检测
  3. 在项目的根目录下面创建一个.eslintignore的文件,里面写src/*,可以忽略对src下面的所有的文件的检测
  4. 老老实实找到错误的位置,把代码写规范了,前提是需要熟悉公司中使用了哪些规则

最后说一下,对于ES6中新的语法检测,还有一个包,叫@babel/eslint-parser。需要安装:

1674980677710

配置如下:

1674980749721

# 17,使用vue脚手架中的eslint

创建vue脚手架创建项目,如下:

1674980906892

1674980954209

1674981040377

1674981152022

1674981184744

弹出vue脚手架中webpack的配置,如下:

1674981794542

# 18,配置路径相关

配置如下:

1676949476381

使用之,如下:

1676949501684

效果如下:

1676949512114

# 19,搭建Vue的开发环境

参考地址:https://blog.csdn.net/qq_40412456/article/details/122334286

# 20,打包less

自行研究

# 21,打包字体图标

自行研究

# 22,Webpack相关面试题

看八股文篇章

Last Updated: 2/27/2023, 10:05:39 PM