十分钟上手webpack包教包会
前言
最近有一个项目使用了Vue框架,组件开发是Vue里面的重要思想之一,而官方文档上推荐的最佳实践是通过webpack+vue构建工程,所以在使用Vue之前,我们需要了解webpack这个打包工具。
在此之前,笔者稍微从requirejs的r.js领略了一点点打包思想,因为只需要简单的打包功能,网上很多文章说了一大堆,什么ES6,什么AMD、CMD,什么shimming、公共模块,相信对于什么都不知道的初学者,说到后面就会蒙蔽,所以本文主要介绍webpack的最简单的用法,适合新手入门。
webpack是什么鬼
webpack 是德国开发者 Tobias Koppers 开发的模块加载器兼打包工具,在webpack中,它可以把各种资源当成一个模块,例如JS(含JSX)、coffee、样式(含less/sass)、图片等都作为模块来使用和处理。不同的模块,他们有对应不同的加载器,称之为loader。
这个图我都看过不下10遍了(看不懂没关系,照做就行,写代码这东西,多实践几次就知道了)
Paste_Image.pngwebpack的优势:
- 可以将任何文件类型模块化,不仅仅是js
- webpack 可以通过commonJS 的形式开发,支持 AMD和CMD
- 打包、压缩混淆、图片转base64等,图片转base64也是图片模块化的思想
- 反正就是很厉害啦~
安装node和npm
在安装webpack
之前,我们需要先安装npm
,安装npm
的之前呢,我们又必须安装nodejs
。因为Node.js 自带了软件包管理器 npm,Webpack 需要 Node.js v0.6 以上支持,建议使用最新版 Node.js。PS:总之要用webpack前,先把node装好。
有几个方法安装node的:
第一种方法:下载安装包
下载安装包或者源码包安装
https://nodejs.org/en/
在Windows上安装时务必选择全部组件,包括勾选Add to Path。
第二种方法:使用nvm安装nodejs(强烈推荐!!)
nvm全称Node Version Manager,是通过shell脚本实现的,通过nvm可以轻松地安装多个版本,随意切换版本,根据喜好和依赖自由选择,省去了很多安装繁琐过程,强烈推荐大家使用。
安装方式有两种:
$ curl https://raw.github.com/creationix/nvm/v0.4.0/install.sh | sh
或者
$ wget -qO- https://raw.github.com/creationix/nvm/v0.4.0/install.sh | sh
nvm安装完成之后,可以用以下命令来安装node
$ nvm install 7.6.0
使用指定的node版本
$ nvm use 7.6.0
查看当前已经安装的版本
$ nvm ls
v4.2.2 *
-> v7.6.0 *
default -> stable (-> v7.6.0 *)
node -> stable (-> v7.6.0 *) (default)
stable -> 7.6 (-> v7.6.0 *) (default)
iojs -> N/A (default)
lts/* -> lts/boron (-> N/A)
lts/argon -> v4.8.0 (-> N/A)
lts/boron -> v6.10.0 (-> N/A)
在看看npm:
npm -v
4.1.2
可以看到笔者安装了两个版本的node,目前使用的是v7.6.0,上面有小箭头指向你正在使用的版本,并且npm也准备就绪。
nvm管理node简单清爽,帮你减去了维护各种依赖的繁琐环节,你值得拥有。
安装webpack
全局安装:
npm install webpack -g
查看webpack版本:
webpack -v
2.2.1
webpack已经安装成功!
不过你应该将webapck安装到当前的项目依赖中,这样可以根据本地项目使用对应版本的webpack
首先,我们创建一个测试目录:
mkdir testapp
然后通过npm初始化该目录:
npm init
name: (testapp) hello
npm初始化的时候会创建一系列的基础信息,包括name、version、description、main、author、licence,你只要写上name和author就可以了,一路回车不要停。
完成后,该目录会生成package.json
配置文件。
1 {
2 "name": "hello",
3 "version": "1.0.0",
4 "description": "test webpack",
5 "main": "index.js",
6 "scripts": {
7 "test": "echo \"Error: no test specified\" && exit 1"
8 },
9 "author": "dada",
10 "license": "ISC"
11 }
上面提到,可以将webpack安装在当前目录下:
npm install webpack --save-dev
# 可以缩写:npm i webpack -D
# –save:模块名将被添加到dependencies,可以简化为参数-S。
# –save-dev: 模块名将被添加到devDependencies,可以简化为参数-D。开发环境一般使用--save-dev就可以了
安装完成后,会出现一个node_modules目录,这里面会存放通过npm安装的模块。
webpack打第一个包
在testapp目录下创建index.html
<!-- index.html -->
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<h1 id="app"></h1>
<script src="build.js"></script>
<!-- 注意这里引入的不是我们创建的文件,而是用webpack生成的文件 -->
</body>
</html>
创建app.js(一会儿我们用webpack打包这个js,命名无所谓)
/*** app.js ***/
document.getElementById('app').innerHTML="hello world!";
现在开始打包!激动!
webpack app.js build.js
打包完成后,有如下信息:
Version: webpack 2.3.2
Time: 96ms
Asset Size Chunks Chunk Names
build.js 2.71 kB 0 [emitted] main
[0] ./app.js 76 bytes {0} [built]
查看当前文件夹,出现如下:
app.js
build.js
index.html
node_module
package.json
可以看到build.js就是通过webpack生成的。
我们打开浏览器看看的index.html看看:
a1.png没错!我们看见了经典程序——Hello world!
然后查看源码:
a2.png查看build.js:
a3.png我们拉到底部,看见了我们的app.js,就这样被包含进来了。
这就是第一个用webpack打包的程序。
一些朋友要说这有卵用!我就innerHTML直接写在index.html里面不就好了吗?搞毛webpack啊。
Keep Calm and Carry On . 我们再多做几个实验,看有没有卵用。
在app.js中引入一个button.js工具包,它可以帮我们增加一个button按钮。
/*create a button*/
var button = document.createElement("button");
button.innerHTML ="Click me!";
document.body.appendChild(button);
然后在app.js 中引入button.js
/*** app.js ***/
document.getElementById('app').innerHTML="hello world!";
require("./button.js");
再打包一次:
webpack app.js build.js
刷新浏览器,页面多了一个按钮
a4.png查看build.js,可以看到button.js的代码也被打包进去,这就是按钮为什么也显示出来。
a5.pngwebpack 会自动分析我们的入口文件,我们这里用app.js
做为一个被打包文件,里面require
了button,js
,webpack这个时候会分析找到依赖的js文件,一并打包进来,生成一个全新的build.js。
webpack就这点能耐?如果是的话,它应该火不起来,因为这个功能大多数打包工具都有。
牛逼哄哄的loader
webpack 本身只能处理 JavaScript 模块,如果要处理其他类型的文件,就需要使用 loader 进行转换。可以理解为是模块和资源的转换器,它本身是一个函数,接受源文件作为参数,返回转换的结果。这样,我们就可以通过require来加载任何类型的模块或文件,比如VUE、JSX、SASS 或图片。
安装css的loader
css的转换,需要引入两个loader,css-loader
和style-loader
npm install css-loader style-loader --save-dev
查看package.json,其中devDependencies
多了css-loader
和style-loader
{
"name": "hello",
"version": "1.0.0",
"description": "test webpack",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "dada",
"license": "ISC",
"devDependencies": {
"css-loader": "^0.28.0",
"style-loader": "^0.16.1",
"webpack": "^2.3.2"
}
}
加载css
新增一个test.css
把字变成白色,背景变成黑色
h1 {
color:#fff
}
body{
background:#000;
}
然后在app.js里面引入test.css,其中style-loader!css-loader表示引入的资源依赖这两个loader
/*** app.js ***/
require("style-loader!css-loader!./test.css");
document.getElementById('app').innerHTML="hello world!";
require("./button.js");
打包:
webpack app.js build.js
查看变化,css已经生效,背景色变成黑色,h1字体变成白色
a6.png控制台查看,我们的test.css已经载入了
a7.png以下这种写法很不优雅,难道加载一个css,前面就要加上“style-loader!css-loader”吗?
require("style-loader!css-loader!./test.css");
可以换种方式实现:
require("./test.css");
然后命令行添加--modulle-bind参数,我们把background改成pink
试试
webpack app.js build.js --module-bind "css=style-loader\!css-loader"
执行没问题,背景应该变成粉红色,注意:这里的css-loader前面要加一个反斜线,表示转义,否则无法编译通过。
加载图片
js和css都已经可以正常引入、打包、加载了,那么图片能否做到呢?
首先图片需要url-loader这个加载器:
npm install url-loader --save-dev
修改css,增加一张叮当猫的图片作背景
h1 {
color:#fff
}
body{
background:url('./dingdang.jpg');
}
然后再打包,因为加载两种文件类型的loader,一个是css,一个是图片,所以我们写下各自的--module-bind配置
webpack app.js build.js
\--module-bind "css=style-loader\!css-loader"
\--module-bind "jpg=url-loader?mimetype=image/jpg"
背景图出现叮当猫:
234.png查看源码,图片已经变成base64编码
a9.png再看一次index.html源码,它由此至终都只引入了一个build.js,不会引入任何其他的js或者css文件,减少了HTTP请求。
a8.png发现问题
如果我们加载的资源类型多了,每次输入一大串带有--module-bind参数的命令很烦,怎么办?
如果我的图片太大,不想转为base64编码,怎么办?
如果每次开发完,都要运行一次webpack很烦,怎么办?
如果想用webpack结合vue写超简约代码,怎么办?
如果我记不住哪个文件用哪个loader,怎么办?
如果package.json里面不知道配置,怎么办?
这些都不是本文要讲的,一次练习一件事儿,本文只练习css,js、图片打包方法。
欲知上面那些怎么办,请听下回分解。o(∩_∩)o