初识Webpack

     这几天连着巴拉巴拉发了好多关于前端的文章。。。。呃呃 ,因为作为一个全站开发人员,前后端分离必然是大势所趋。。。所以只能顺势而为了。。。

什么是Webpack

Webpack是一个模块打包器,它的主要目标是将JavaScript文件打包在一起,打包后的文件用于在浏览器中使用。 —-Webpack中文文档

说白了,它最大的用处就是分析一个网页的各种依赖,并且自动化地将这些依赖打包在一起并且压缩,供网页使用。当然它的功能不止如此,比如依赖loader,它还可以将JavaScript ES6(很多老浏览器不一定支持)转换成支持更加多浏览器的老版本JavaScript。

Webpack示意图

总之,它在前端的模块化开发中占有重要的作用,如果想让自己的项目变得更加整洁,开发更加有效率,Webpack有必要一学。

在开始之前

在介绍Webpack之前,很有必要先介绍一下Node.js和npm,如果你已经对着两者有着深刻的了解,可以直接跳过,看下一节,如果你之前从未听说过Node.js,可以仔细看看这一节对这两者的介绍,Webpack的使用一定程度上依赖着这两者。

Node.js是一个基于Chrome V8引擎驱动的JavaScript运行时。Node.js使用高效、轻量级的事件驱动、非阻塞I/O模型。它的包生态系统,npm,是目前世界上最大的开源库生态系统。 —-Node.js官网

看了是不是感觉Node.js官网的介绍,感觉这玩意十分高深莫测,说实话我第一次看到的时候也没有太看懂。接下来用人话给大家翻译一下,众所周知,JavaScript是Web开发中不可或缺的语言,它可以为网页添加许多动态效果,也能为网页添加更多可能性,如果连JavaScript都不知道,请先学习一下Web开发御三家(html, css, js),但是JavaScript的硬伤是只能在浏览器上运行,脱离浏览器,就无法运行。而Node.js就解决了这么一个问题,它将Chrome V8的JavaScript引擎提取出来,使得JavaScript能够脱离浏览器而运行,这样就为JavaScript提供了无限的可能性。至于它的更多,现在先不用了解那么深,对于Node.js,你现在只需要了解到这里就行了。

而npm,则是Node.js自带的包管理系统,npm的作用跟python的pip很像,你只需要敲一行命令,就能获取到世界上任何一个角落的人发布在其上的源码并且使用。显然,JavaScript开发模块化,npm也在其中做出了很大贡献。

接下来,先安装Node.js吧,打开Node.js的官网Node.js

Node.js官网

简单粗暴的页面,你可以选择稳定版LTS和最新版Current下载,自行安装即可。当安装完成后,你可以在命令行输入

如果正确显示了Node.js的版本号,就说明你的Node.js成功安装了,当然,npm是Node.js的一部分,Node.js安装成功的同时,npm也就可以使用了。

开始学习Webpack

如果你还没有安装Node.js,请移步上一节并认真安装好Node.js,如果你已经安装了Node.js,就可以开始学习Webpack了。

首先,先建立一个文件夹,用来作为学习Webpack的项目文件夹,文件夹名随意,接着在项目使用命令行中初始化npm

运行该命令会询问你你这一个项目的基本信息,比如项目名、作者、描述、Git仓库等等,这是因为init指令实际上是将项目文件夹变成一个npm包,你甚至在日后可以将这个npm包发布给他人使用,当然,我们现在只是学习,一路回车就行,如果你实在比较较真,也没关系,这些东西日后可以在配置文件中修改。如果你不想敲回车,也可以直接使用

当npm初始化完成之后,项目下会自动生成一个package.json文件,上面详细说明了你这一个npm包中的信息,我们暂时可以不用关注这些内容。接下来在项目中安装Webpack。

这两行命令会为你的项目安装webpack和webpack-cli包,前者是webpack的核心库,后者是分离出来的webpack命令行功能,我们需要使用webpack-cli来进行项目的打包等操作。

不使用Webpack时,项目的问题

我们先看一下不使用webpack进行构建时,项目的缺陷。

先在项目文件夹中创建几个目录和文件,项目结构如下图所示,前面带加号的是需要你自己创建的文件和目录:

src/index.js

index.html

 

这里的Lodash是一个JavaScript库,这里引用的意味就是给大家展示一下我们平时使用第三方JavaScript库的做法,这样的做法会产生很多问题,因为通过index.html的联系,很明显,index.js对第三方库lodash产生了隐形依赖,之所以说是隐形依赖,是因为在lodash被引用之前,index.js中的双下划线变量(lodash提供的一个变量)还是未知的,只有在lodash被引用之后,这个变量才能发挥作用,显而易见,这样做的很危险的,这样会产生很多问题:

1.无法立即体现,脚本的执行依赖于外部扩展库(external library)。

2.如果依赖不存在,或者引入顺序错误,应用程序将无法正常运行。

3.如果依赖被引入但是并没有使用,浏览器将被迫下载无用代码。

Webpack的价值就这样体现出来了,当你的项目中引用的JavaScript文件,html页面越来越多,就会出现一些不可避免的依赖问题,而我们通过Webpack可以解决这一问题,对于一个html页面,我们可以该页面依赖的所有JavaScript文件打包在一起,构成一个JavaScript文件,这样,html页面只需要引用这一个JavaScript文件即可,上面说的问题,就可以完全被避免。当然自己打包也是可以的,不过通过Webpack这一神器,就没那么麻烦了,你只要告诉它,你需要把哪些文件打包,输出到哪里,它就可以自动分析所有JavaScript的依赖关系,然后帮你打包成一个文件。

接下来,我们就来打包一次试试。

使用Webpack打包

在打包之前,我们还需要做一点小小的调整—-将开发环境和生产环境分开:

这样一来,src文件夹里面,放的就是我们开发的环境,所有的代码编写都在这里进行,而相对稳定的html文件就直接放入dist文件夹中,作为生产环境的文件,这样有一个好处,每一次更新src之后,只需要把src中的东西重新打包,然后供生产环境中的html文件使用,就行了,而html文件本身,几乎不用被更改。

因为我们用到了lodash包,所以需要在npm中安装lodash依赖:

细心的朋友可能注意到,这里使用的是–save而不是–save-dev,两者的区别是,–save是生产环境的依赖,也就是供给用户使用的依赖,而–save-dev是开发环境的依赖,比如Webpack,在代码完成并且打包之后,就不需要再使用到它了,显然用户是无需接触到Webpack的,所以这里Webpack属于开发环境的依赖。

添加lodash依赖之后,我们就可以在js文件中导入并且使用了:

src/index.js

因为接下来我们要使用Webpack打包所有的js,这样的话,我们就不需要再自己在html引入JavaScript库了,而只需要引入打包之后的文件就行了,我们先约定以后打包的文件名叫做bundle.js,那么接下来,修改html文件:

dist/index.html

这样的话,我们就可以开始打包了。

在命令行输入

如果不行的话,尝试

这一行的意思是执行Webpack命令行程序,将src/index.js作为入口文件,自动分析index.js的依赖,并且将所有依赖和index.js本身一起打包成一个文件,输出到dist/bundle.js,执行这一行,可以看到Webpack打包成功的输出信息:

打包成功并且输出之后,你就可以打开html文件看看结果了:

html运行结果

可见打包之后的JavaScript能够成功运行,并且解决了之前说的几个问题,这就是Webpack的主要功能。

但是你可能会问,每次都要自己输入巴拉巴拉一大串命令,那也太麻烦了吧,Webpack显然想到了这一点,它是支持配置文件的,你只需要在项目根目录下新建一个配置文件webpack.config.js,并且按照Webpack中文文档给出的语法进行编写就行了。下面给出一个配置文件的例子:

webpack.config.js

完成配置文件之后,你需要打包时,就不需要再自己输入入口和输出了,直接这样就行了

NPM脚本

有了配置文件你可以还不满足,我既然有npm,为什么不能直接让npm帮我运行呢,答案是可以的,npm支持用户自定义脚本,用户可以在npm的配置文件中添加自己的脚本内容,然后使用下面给出的指令来运行用户的脚本

这样的话,我们不是可以自己定义一个build脚本,让它完成Webpack打包的任务呢。

package.json

这样一来,只要

世界我有,打包全自动!