什么是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
简单粗暴的页面,你可以选择稳定版LTS和最新版Current下载,自行安装即可。当安装完成后,你可以在命令行输入
node -v
如果正确显示了Node.js的版本号,就说明你的Node.js成功安装了,当然,npm是Node.js的一部分,Node.js安装成功的同时,npm也就可以使用了。
开始学习Webpack
如果你还没有安装Node.js,请移步上一节并认真安装好Node.js,如果你已经安装了Node.js,就可以开始学习Webpack了。
首先,先建立一个文件夹,用来作为学习Webpack的项目文件夹,文件夹名随意,接着在项目使用命令行中初始化npm
npm init
运行该命令会询问你你这一个项目的基本信息,比如项目名、作者、描述、Git仓库等等,这是因为init指令实际上是将项目文件夹变成一个npm包,你甚至在日后可以将这个npm包发布给他人使用,当然,我们现在只是学习,一路回车就行,如果你实在比较较真,也没关系,这些东西日后可以在配置文件中修改。如果你不想敲回车,也可以直接使用
npm init -y
当npm初始化完成之后,项目下会自动生成一个package.json文件,上面详细说明了你这一个npm包中的信息,我们暂时可以不用关注这些内容。接下来在项目中安装Webpack。
npm install --save-dev webpack
npm install --save-dev webpack-cli
这两行命令会为你的项目安装webpack和webpack-cli包,前者是webpack的核心库,后者是分离出来的webpack命令行功能,我们需要使用webpack-cli来进行项目的打包等操作。
不使用Webpack时,项目的问题
我们先看一下不使用webpack进行构建时,项目的缺陷。
先在项目文件夹中创建几个目录和文件,项目结构如下图所示,前面带加号的是需要你自己创建的文件和目录:
webpack-learning
|- package.json
+ |- index.html
+ |- /src
+ |- index.js
src/index.js
function component() {
var element = document.createElement('div');
// Lodash(目前通过一个 script 脚本引入)对于执行这一行是必需的
element.innerHTML = _.join(['Hello', 'webpack'], ' ');
return element;
}
document.body.appendChild(component());
index.html
<!doctype html>
<html>
<head>
<title>Getting Started</title>
<script src="https://unpkg.com/lodash@4.16.6"></script>
</head>
<body>
<script src="./src/index.js"></script>
</body>
</html>
这里的Lodash是一个JavaScript库,这里引用的意味就是给大家展示一下我们平时使用第三方JavaScript库的做法,这样的做法会产生很多问题,因为通过index.html的联系,很明显,index.js对第三方库lodash产生了隐形依赖,之所以说是隐形依赖,是因为在lodash被引用之前,index.js中的双下划线变量(lodash提供的一个变量)还是未知的,只有在lodash被引用之后,这个变量才能发挥作用,显而易见,这样做的很危险的,这样会产生很多问题:
- 无法立即体现,脚本的执行依赖于外部扩展库(external library)。
- 如果依赖不存在,或者引入顺序错误,应用程序将无法正常运行。
- 如果依赖被引入但是并没有使用,浏览器将被迫下载无用代码。
Webpack的价值就这样体现出来了,当你的项目中引用的JavaScript文件,html页面越来越多,就会出现一些不可避免的依赖问题,而我们通过Webpack可以解决这一问题,对于一个html页面,我们可以该页面依赖的所有JavaScript文件打包在一起,构成一个JavaScript文件,这样,html页面只需要引用这一个JavaScript文件即可,上面说的问题,就可以完全被避免。当然自己打包也是可以的,不过通过Webpack这一神器,就没那么麻烦了,你只要告诉它,你需要把哪些文件打包,输出到哪里,它就可以自动分析所有JavaScript的依赖关系,然后帮你打包成一个文件。
接下来,我们就来打包一次试试。
使用Webpack打包
在打包之前,我们还需要做一点小小的调整----将开发环境和生产环境分开:
webpack-learning
|- package.json
+ |- /dist
+ |- index.html
- |- index.html
|- /src
|- index.js
这样一来,src文件夹里面,放的就是我们开发的环境,所有的代码编写都在这里进行,而相对稳定的html文件就直接放入dist文件夹中,作为生产环境的文件,这样有一个好处,每一次更新src之后,只需要把src中的东西重新打包,然后供生产环境中的html文件使用,就行了,而html文件本身,几乎不用被更改。
因为我们用到了lodash包,所以需要在npm中安装lodash依赖:
npm install --save lodash
细心的朋友可能注意到,这里使用的是--save而不是--save-dev,两者的区别是,--save是生产环境的依赖,也就是供给用户使用的依赖,而--save-dev是开发环境的依赖,比如Webpack,在代码完成并且打包之后,就不需要再使用到它了,显然用户是无需接触到Webpack的,所以这里Webpack属于开发环境的依赖。
添加lodash依赖之后,我们就可以在js文件中导入并且使用了:
src/index.js
+ import _ from 'lodash';
+
function component() {
var element = document.createElement('div');
- // Lodash, currently included via a script, is required for this line to work
+ // Lodash, now imported by this script
element.innerHTML = _.join(['Hello', 'webpack'], ' ');
return element;
}
document.body.appendChild(component());
因为接下来我们要使用Webpack打包所有的js,这样的话,我们就不需要再自己在html引入JavaScript库了,而只需要引入打包之后的文件就行了,我们先约定以后打包的文件名叫做bundle.js,那么接下来,修改html文件:
dist/index.html
<!doctype html>
<html>
<head>
<title>Getting Started</title>
- <script src="https://unpkg.com/lodash@4.16.6"></script>
</head>
<body>
- <script src="./src/index.js"></script>
+ <script src="bundle.js"></script>
</body>
</html>
这样的话,我们就可以开始打包了。
在命令行输入
webpack-cli src/index.js --output dist/bundle.js
如果不行的话,尝试
// linux
node_modules/.bin/webpack-cli src/index.js --output dist/bundle.js
// windows
node_modules\.bin\webpack-cli src/index.js --output dist/bundle.js
这一行的意思是执行Webpack命令行程序,将src/index.js作为入口文件,自动分析index.js的依赖,并且将所有依赖和index.js本身一起打包成一个文件,输出到dist/bundle.js,执行这一行,可以看到Webpack打包成功的输出信息:
Hash: 61bf2519e9ef5fa0eb5e
Version: webpack 4.1.0
Time: 4080ms
Built at: 2018-3-7 16:58:36
Asset Size Chunks Chunk Names
bundle.js 69.6 KiB 0 [emitted] main
Entrypoint main = bundle.js
[1] (webpack)/buildin/module.js 519 bytes {0} [built]
[2] (webpack)/buildin/global.js 509 bytes {0} [built]
[3] ./src/index.js 231 bytes {0} [built]
+ 1 hidden module
打包成功并且输出之后,你就可以打开html文件看看结果了:
html运行结果
可见打包之后的JavaScript能够成功运行,并且解决了之前说的几个问题,这就是Webpack的主要功能。
但是你可能会问,每次都要自己输入巴拉巴拉一大串命令,那也太麻烦了吧,Webpack显然想到了这一点,它是支持配置文件的,你只需要在项目根目录下新建一个配置文件webpack.config.js,并且按照Webpack中文文档给出的语法进行编写就行了。下面给出一个配置文件的例子:
webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
完成配置文件之后,你需要打包时,就不需要再自己输入入口和输出了,直接这样就行了
webpack-cli
// 如果不行尝试
// linux
node_modules/.bin/webpack-cli
// windows
node_modules\.bin\webpack-cli
NPM脚本
有了配置文件你可以还不满足,我既然有npm,为什么不能直接让npm帮我运行呢,答案是可以的,npm支持用户自定义脚本,用户可以在npm的配置文件中添加自己的脚本内容,然后使用下面给出的指令来运行用户的脚本
npm run 脚本名
这样的话,我们不是可以自己定义一个build脚本,让它完成Webpack打包的任务呢。
package.json
{
...
"scripts": {
"build": "webpack-cli"
},
...
}
这样一来,只要
npm run build
世界我有,打包全自动!
关于Webpack的更多
Webpack的功能当然还不止这些,这里只介绍Webpack的基本功能打包,当你阅读完这篇文章,对Webpack是什么,怎么用也知道个ABCD了,如果想了解更多,可以关注我,我会给大家继续更新一下Web前端的知识,当然也可以直接上Webpack中文文档上查更多的东西,把自己的项目变得更加自动化,让开发更加有效率。
网友评论