十分钟上手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.png

webpack的优势:

  • 可以将任何文件类型模块化,不仅仅是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.png

webpack 会自动分析我们的入口文件,我们这里用app.js做为一个被打包文件,里面requirebutton,js,webpack这个时候会分析找到依赖的js文件,一并打包进来,生成一个全新的build.js。

webpack就这点能耐?如果是的话,它应该火不起来,因为这个功能大多数打包工具都有。

牛逼哄哄的loader

webpack 本身只能处理 JavaScript 模块,如果要处理其他类型的文件,就需要使用 loader 进行转换。可以理解为是模块和资源的转换器,它本身是一个函数,接受源文件作为参数,返回转换的结果。这样,我们就可以通过require来加载任何类型的模块或文件,比如VUE、JSX、SASS 或图片。

安装css的loader

css的转换,需要引入两个loader,css-loaderstyle-loader

npm install css-loader style-loader --save-dev

查看package.json,其中devDependencies多了css-loaderstyle-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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,045评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,114评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,120评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,902评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,828评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,132评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,590评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,258评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,408评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,335评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,385评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,068评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,660评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,747评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,967评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,406评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,970评论 2 341

推荐阅读更多精彩内容