若是你如今还不懂 webpack,我相信你必定和我最开始同样,对官网的这张图一脸懵逼,就算如今,我仍是以为这张图对新手起了很大的误导做用。
咱们今天就从js发展的角度来讲明,到底什么是 webpack。
JS的设计初衷
——————
js 早期设计的目的是辅助页面交互和丰富页面样式,这使得 js 能进行 dom 操做。 好比下面这样。
<html>
<body></body>
<script>
const ele = document.createElement('DIV');
ele.style.background = 'red';
ele.style.width = '100px';
ele.style.height = '100px';
document.body.append(ele);
</script>
</html>
<html>
<body>
<div style="background:red;width:100px;height:100px"></div>
</body>
</html>
虽然使用 js 的写法很麻烦,可是至少表明了 js 有这方面的能力,他能在不依靠 html 和 css 的状况下,独立进行页面的显示。
IE最后的礼物
——————
IE 虽然一直让人诟病,可是有他留下的 xmlHttpRequest 确实是一大宝贝,他能在页面不刷新的状况下,请求和获取后端数据。 这个能力再配合js对于dom操做的能力,就能完成一些骚操做。 好比在页面不刷新的状况下,加载一篇新的文章、发布评论功能等等。 这也是最先单页面应用的雏形。
你可能不知道早期在论坛进行一次简单的评论,要通过2次页面的跳转。
Node让js突破能力的界限
———————————
node 他既不是开发语言,也不是什么框架,他是一个开发环境。 咱们原来的js是运行在浏览器,这注定他有不少事情作不了,最基本的就是,他不能在浏览器对你本地文件进行增删改。 而node他是运行在本地的,他没有在浏览器端那些限制,他有极高的权限,其中同样就是能够对本地文件进行增删改。
也正是这一特征,他让预处理语言获得了极大发展。 咱们能够本身制定一套语法,而后经过转换器(loader),编译成html能够理解的语言。 目前html主要就认识2种文件,css和js。
模块化的进化
——————
其实前端模块化一直都在,咱们将一个个js写好,而后在html里面一个个引用,这就是最先的模块化。 可是这产生了一个问题,这些引入关系都是写在html里面的,两个js文件之间要进行交互,也只能经过全局变量赋值的形式。
答案是能够的,目前比较主流的方式是 Node的common.js和ES6的ESModule两种方式,下面使用ESModule来改变一下以前的引用方式。
<html>
<body>
<script src="js/jquery.js"></script>
<script src="js/util.js"></script>
<script src="js/index.js"></script>z
</body>
</html>
<html>
<body>
<script src="js/index.js"></script>z
</body>
</html>
/* 这是index.js 的内容 */
import $ from 'jquery.js';
import util from 'util.js';
$('div').remove();
至此,咱们已经了解了使用webpack的四个先决条件了。
主角登场
————
如何构建一个单页面应用? 下面咱们从一个需求入手,来引出为啥须要webpack。
# 目录结构
index.html
index.js
<html>
<body>
<script src="index.js"></script>
</body>
</html>
function showIndex(){
document.body.innerText = '这是首页';
}
function showList(){
document.body.innerText = '这是列表页';
}
function showArticle(){
document.body.innerText = '这是内容页';
}
const arr = [
['首页',showIndex],
['列表页',showList],
['内容页',showArticle],
]
arr.forEach((item)=>{
const ele = document.createElement('DIV');
ele.innerText = item[0];
ele.onclick = item[1];
document.body.append(ele);
})
复制代码
代码逻辑很简单,就是在页面渲染一些内容,而后点击会跳转到不一样的页。 可是若是全部内容都写在index.js里,代码会变得很巨大,后期也很很差维护,
因此咱们对index.js进行功能拆分,而后使用引用的方式,将他们关联起来。
# 目录结构
pages
|__ home.js
|__ list.js
|__ article.js
index.js
index.html
import { showIndex } from 'js/home.js';
import { showList } from 'js/list.js';
import { showArticle } from 'js/article.js';
const arr = [
['首页',showIndex],
['列表页',showList],
['内容页',showArticle],
]
arr.forEach((item)=>{
const ele = document.createElement('DIV');
ele.innerText = item[0];
ele.onclick = item[1];
document.body.append(ele);
})
复制代码
function showIndex(){
document.body.innerText = '这是首页';
}
export showIndex;
可是有个问题,上面的代码在老版本的浏览器是没法运行的,由于老版本浏览器,不支持ES6模块,
因此咱们须要使用node对项目源代码进行分析打包,造成新的浏览器能够运行的代码,就变成了新的目录结构。
# 目录结构
dist
|__ index.js
|__ index.html
src
|__ pages
| |__ home.js
| |__ list.js
| |__ article.js
|__ index.js
|__ index.html
分析打包的过程就是,咱们须要写一个脚本,node执行这个脚本,脚本内容是去打开index.js文件,而后对代码进行解读,当遇到依赖引入的地方时,而后把代码复制进来,看下面这个动图就能够一清二楚。
固然咱们不须要本身写这个脚本,由于咱们有 webpack,
webpack的第一个功能,就是作上面的事情,从入口文件开始分析,对依赖进行合并,而后打包输出。
而webpack的第二个功能,就是他能够处理你引入任何格式的文件,注意,是任何格式。
前面介绍过,在前端有不少预处理语言,他们能极大方便咱们的开发,可是预处理语言须要进行编译,才能成为可以使用的语言。 而webpack,就能帮咱们进行编译。
webpack 当处理到不认识的文件格式时,会把他转化为字符串,而后使用loader对他进行转化,转化成js认识的格式。
以上面的项目为例子,咱们将被引用的几个脚本文件改成了ts的文件形式。
# 目录结构
dist
|__ index.js
|__ index.html
src
|__ pages
| |__ home.ts
| |__ list.ts
| |__ article.ts
|__ index.js
|__ index.html
js默认是不认识ts文件里的内容的,即便他们很像,因此webpack在解析ts文件时,要先作一个事情,就是先把ts转为js格式,而后在对转化后的js进行引入。
loader是能够拓展的,因此只要你有被引入文件的loader,理论上你能够引入任何文件格式。
webpack的第三个功能,就是插件。
插件就是webpack在执行分析打包任务时,你能够作一些额外的操做。
好比说,在引入css后对css进行自动添加适配前缀、对项目总体代码进行压缩等等,都是插件的功能体现。 由于说到底,代码就是字符串,webpack能获取到整个项目,包括依赖文件的代码(字符串),而后他在这个字符串作一些操做,也很好理解。
这就是webpack的三个主要功能,他的可拓展性,让他极具创造力,现在基本已经成为了全部web应用的基建部分,正所谓时势造英雄,他生在了前端最须要他的年代,我相信他构建的打包模式,不会是咱们前端的最终形态,只要js还在进步,还在变化,就会有新的模式出现。