什么是webpack?

一、面向过程的前端开发

首先,让我们来看一段面向过程的前端开发的代码:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="webContent"></div> <script> var webContent = document.getElementById(webContent); var header = document.createElement(div); header.innerText = 网页标题; webContent.appendChild(header); var content = document.createElement(div); content.innerText = 网页主体; webContent.appendChild(content); var footer = document.createElement(div); footer.innerText = 网页页脚; webContent.appendChild(footer); </script> </body> </html>

网页结果:

这种面向过程的代码整合方式,使得所有JS代码都"挤"在一个地方,代码混乱,不具备代码层次化,难于调试。

二、面向对象的前端开发(代码模块化)

所谓面向对象的前端开发,就是将整块混合的代码分割成一块一块,使得代码模块化,从而一个代码模块负责一部分的页面逻辑。

让我们来看将上面的示例模块化后的代码:

header.js:

function Header(){ var header = document.createElement(div); header.innerText = 网页标题; webContent.appendChild(header); }

content.js:

function Content(){ var content = document.createElement(div); content.innerText = 网页主体; webContent.appendChild(content); }

footer.js:

function Footer(){ var footer = document.createElement(div); footer.innerText = 网页页脚; webContent.appendChild(footer); }

index.js:

var webContent = document.getElementById(webContent); new Header(); new Content(); new Footer();

dist.html:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="webContent"></div> <script src="./header.js"></script> <script src="./content.js"></script> <script src="./footer.js"></script> <script src="./index.js"></script> </body> </html>

网页结果:

这样将代码模块化后,使得代码的逻辑变得清晰,更能呈现出业务场景。

但是,这种方式的模块化也存在缺点:

①页面加载速度变慢:

由于增加了js文件的数量,所以网页需要发起更多次的http请求,导致了页面加载速度变慢。

②无法直接在js代码中看出js文件之间相互的存储位置的关系,必须要通过dist.html文件才能查看。

③js文件必须按规定顺序加载:

在dist.html文件中,header.js、content.js以及footer.js文件都必须在index.js文件之前加载完毕:

假如我们把header.js文件,放在index.js文件后面进行加载:

网页的控制台就会报错:

三、使用webpack打包器

为了解决上面那种模块化方式存在的缺点,我们依据ES module的规则改写一点代码,然后结合webpack来解决。

首先,我们来看改写后的代码:

header.js:

function Header(){ var webContent = document.getElementById(webContent); var header = document.createElement(div); header.innerText = 网页标题; webContent.appendChild(header); } export default Header;

content.js:

function Content(){ var webContent = document.getElementById(webContent); var content = document.createElement(div); content.innerText = 网页主体; webContent.appendChild(content); } export default Content;

footer.js:

function Footer(){ var webContent = document.getElementById(webContent); var footer = document.createElement(div); footer.innerText = 网页页脚; webContent.appendChild(footer); } export default Footer;

index.js:

import Header from ./header.js; import Content from ./content.js; import Footer from ./footer.js; new Header(); new Content(); new Footer();

dist.html:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="webContent"></div> <script src="./dist/main.js"></script> </body> </html>

接下来,进入到上面这些文件的根目录,我这里是进入到e:\webpack-demo,然后初始化npm环境(注意:做这些操作之前必须要先安装node环境,可以参考这篇文章:

https://www.npmjs.com.cn/getting-started/installing-node/):www.npmjs.com.cn/getting-started/installing-node/%EF%BC%89%EF%BC%9A

接下来,一直回车就好。

然后,安装webpack:

最后,运行npx webpack命令(Node 8.2+ 版本提供的 npx 命令,可以运行在初始安装的 webpack 包(package)的 webpack 二进制文件,就是可以调用webpack中的webpack二进制文件程序):

此时,会发现根目录中出现了一个新的文件夹:

查看dist文件夹中的内容,可以发现有一个main.js文件,其实这个main.js文件是webpack将index.js、header.js、content.js、footer.js打包在一起的一个文件。

用浏览器直接打开dist.html文件,可以发现和原先的模块化方法得到相同的结果:

四、webpack究竟是什么呢?

通过上面的示例,我们应该可以很清楚的知道webpack是一个打包器(bundler),它能将多个js文件打包成一个文件(其实不止能打包js文件,也能打包其他类型的文件,比如css文件,json文件等)。

可以查看官方文档,官方文档也明确表明webpack是一个打包器:

但是webpack不是一个翻译器,它只能理解诸如"imort"、"from"等模块导入语句,其他的JS语句等它是不能够识别理解的。