前端自动化工具学习--webpack经典7分钟入门

一.什么是 Webpack
Webpack 是一个模块打包器。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。

webpack模式图

二.为什么使用webpack
市面上已经存在的模块管理和打包工具并不适合大型的项目,尤其单页面 Web 应用程序。最紧迫的原因是如何在一个大规模的代码库中,维护各种模块资源的分割和存放,维护它们之间的依赖关系,并且无缝的将它们整合到一起生成适合浏览器端请求加载的静态资源。而webpack有以下几个优点:
1.将依赖树拆分成按需加载的块:Webpack 有两种组织模块依赖的方式,同步和异步。异步依赖作为分割点,形成一个新的快。在优化了依赖树后,每一个异步区块都作为一个文件被打包。

2.初始化加载的耗时尽量少:Webpack 使用异步 I/O 和多级缓存提高运行效率,这使得 Webpack 能够以令人难以置信的速度快速增量编译。

3.各种静态资源都可以视作模块:Webpack 本身只能处理原生的 JavaScript 模块,但是 loader 转换器可以将各种类型的资源转换成 JavaScript 模块。这样,任何资源都可以成为 Webpack 可以处理的模块。

4.将第三方库整合成模块的能力:Webpack 有一个智能解析器,几乎可以处理任何第三方库,无论它们的模块形式是 CommonJS、 AMD 还是普通的 JS 文件。甚至在加载依赖的时候,允许使用动态表达式 require("./templates/" + name + ".jade")。

5.自定义打包逻辑的能力:Webpack 还有一个功能丰富的插件系统。大多数内容功能都是基于这个插件系统运行的,还可以开发和使用开源的 Webpack 插件,来满足各式各样的需求。

6.适合大项目,无论是单页还是多页的 Web 应用

三.安装webpack
首先要安装 Node.js, Node.js 自带了软件包管理器 npm,Webpack 需要 Node.js v0.6 以上支持,建议使用最新版 Node.js。

用 npm 安装 Webpack:
$ npm install webpack -g
此时 Webpack 已经安装到了全局环境下,本课程中我们已装好webpack,可以通过命令行 webpack -h 试试。

通常我们会将 Webpack 安装到项目的依赖中,这样就可以使用项目本地版本的 Webpack。
1.进入项目目录 2.确定已经有 package.json,没有就通过 npm init 创建 3.输入命令 $ npm install webpack --save-dev 安装 webpack 依赖
Webpack 目前有两个主版本,一个是在 master 主干的稳定版,一个是在 webpack-2 分支的测试版,测试版拥有一些实验性功能并且和稳定版不兼容,在正式项目中应该使用稳定版。
<pre>

查看 webpack 版本信息

$ npm info webpack

安装指定版本的 webpack

$ npm install webpack@1.12.x --save-dev
</pre>

四.在项目中使用webpack
首先有一个静态页面 index.html,
<pre>

<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script src="bundle.js"></script>
</body>
</html>
</pre>
现在创建一个 JS 入口文件 entry.js:
<pre>
// entry.js
pico entry.js
// 进入编辑器输入
document.write('It works.');
// 保存并退出
</pre>
然后编译 entry.js 并打包到 bundle.js,运行命令:
<pre>
$ webpack ./entry.js bundle.js
</pre>
如果成功,打包过程会显示日志:
<pre>
Hash: aeec068c58e1e78f0fb6
Version: webpack 1.12.9
Time: 70ms
Asset Size Chunks Chunk Names
bundle.js 1.48 kB 0 [emitted] main
[0] ./entry.js 87 bytes {0} [built]
</pre>
在点击访问测试将会打开一个新的窗口。它应该会显示It works.。

注意:下面的课程中创建编辑文件都是用pico 文件名。
下一步,我们将把一些代码移到一个额外的文件中content.js 并修改入口 entry.js:
<pre>
// content.js
pico content.js
// 编辑内容
module.exports = "It works from content.js.";
</pre>
<pre>
// 修改entry.js
//document.write('It works.');
document.write(require("./content.js")); // 添加content.js
</pre>
编译文件
<pre>
$ webpack ./entry.js bundle.js
</pre>
更新您的浏览器窗口,您应该看到文本It works from content.js.

执行成功,会显示
<pre>
Hash: ef96fed65f6d3ebc0dd7
Version: webpack 1.12.9
Time: 91ms
Asset Size Chunks Chunk Names
bundle.js 1.7 kB 0 [emitted] main
[0] ./entry.js 133 bytes {0} [built]
[1] ./content.js 97 bytes {0} [built]
</pre>
Webpack 会分析入口文件,解析包含依赖关系的各个文件。这些文件(模块)都打包到 bundle.js 。Webpack 会给每个模块分配一个唯一的 id 并通过这个 id 索引和访问模块。在页面启动时,会先执行 entry.js 中的代码,其它模块会在运行 require 的时候再执行。

五.Loader介绍和使用

Webpack 本身只能处理 JavaScript 模块,如果要处理其他类型的文件,就需要使用 loader 进行转换。

Loader 可以理解为是模块和资源的转换器,它本身是一个函数,接受源文件作为参数,返回转换的结果。这样,我们就可以通过 require 来加载任何类型的模块或文件,比如 CoffeeScript、 JSX、 LESS 或图片。

loader 有以下这些特点:
<pre>
1.Loader 可以通过管道方式链式调用,每个 loader 可以把资源转换成任意格式并传递给下一个 loader ,但是最后一个 loader 必须返回 JavaScript。
2.Loader 可以同步或异步执行。
3.Loader 运行在 node.js 环境中,所以可以做任何可能的事情。
4.Loader 可以接受参数,以此来传递配置项给 loader。
5.Loader 可以通过文件扩展名(或正则表达式)绑定给不同类型的文件。
6.除了通过 package.json 的 main 指定,通常的模块也可以导出一个 loader 来使用。
7.Loader 可以访问配置。
8.插件可以让 loader 拥有更多特性。
9.Loader 可以分发出附加的任意文件。
</pre>

我们想要在应用中添加一个css文件。

WebPACK只能处理JavaScript本身,所以我们需要css-loader去处理 CSS。我们还需要style-loader去应用这个样式在CSS文件。

安装 loader:
<pre>
npm install css-loader style-loader
</pre>
注意:安装 loaders(只需要在本地安装,不需 -g)将会创建一个 node_modules 文件夹,在哪里 loaders 将会激活。

我们要在页面中引入一个 CSS 文件 style.css,首页将 style.css 也看成是一个模块,然后用 css-loader 来读取它,再用 style-loader 把它插入到页面中。

添加一个style.css文件
<pre>
body {
background: blue;
}
</pre>
修改 entry.js:
<pre>

  • require("!style!css!./style.css"); // 载入 style.css
    document.write(require("./content.js"));
    </pre>

重新编译并更新您的浏览器看到蓝色背景。

扩展名自动绑定loader
如果每次 require CSS 文件的时候都要写 loader 前缀,是一件很繁琐的事情。

我们可以根据模块类型(扩展名)来自动绑定需要的 loader这样写require("./style.css")。

修改entry.js
<pre>

  • require("!style!css!./style.css");
  • require("./style.css");
    document.write(require("./content.js"));
    </pre>
    注意:-表示这行删掉或者注释掉,+表示新增的内容。
    编译:
    <pre>
    webpack ./entry.js bundle.js --module-bind "css=style!css"
    </pre>
    注意:!在shell中有特殊意义,需要转义,这样写才会成功的
    <pre>
    webpack ./entry.js bundle.js --module-bind "css=style!css"
    </pre>

六.配置文件
Webpack 在执行的时候,除了在命令行传入参数,还可以通过指定的配置文件来执行。默认情况下,会搜索当前目录的 webpack.config.js 文件,这个文件是一个 node.js 模块,返回一个 json 格式的配置信息对象,或者通过 --config 选项来指定配置文件。

我们想将配置选项移动到配置文件中,创建一个配置文件 webpack.config.js:
<pre>
module.exports = {
entry: "./entry.js",
output: {
path: __dirname,
filename: "bundle.js"
},
module: {
loaders: [
{ test: /.css$/, loader: "style!css" }
]
}
};
</pre>
现在我们仅仅运行:
<pre>
webpack
</pre>
如果完成成功,将会返回运行结果,该命令将尝试WebPACK当前目录中加载文件webpack.config.js。

这里对Webpack的打包行为做了配置,主要分为几个部分:

entry:指定打包的入口文件,每有一个键值对,就是一个入口文件
output:配置打包结果,path定义了输出的文件夹,filename则定义了打包结果文件的名称
module:定义了对模块的处理逻辑,这里可以用loaders定义了一系列的加载器,以及一些正则。当需要加载的文件匹配test的正则时,就会调用后面的loader对文件进行处理,这正是webpack强大的原因。

漂亮的输出
如果该项目的增长,编译可能需要更长的时间。所以我们要展示一些进度条。我们想要的颜色…

我们可以这样
<pre>
webpack --progress --colors
</pre>

七.插件
插件可以完成更多 loader 不能完成的功能。

插件的使用一般是在 webpack 的配置信息 plugins 选项中指定。

Webpack 本身内置了一些常用的插件,还可以通过 npm 安装第三方插件。

接下来,我们利用一个最简单的 BannerPlugin 内置插件来实践插件的配置和运行,这个插件的作用是给输出的文件头部添加注释信息。

修改 webpack.config.js,添加 plugins:
<pre>
var webpack = require('webpack');
module.exports = {
entry: './entry.js',
output: {
path: __dirname,
filename: 'bundle.js'
},
module: {
loaders: [
{test: /.css$/, loader: 'style!css'}
]
},
plugins: [
new webpack.BannerPlugin('This file is created by mutouren')
]
}
</pre>
然后运行 webpack,打开 bundle.js,可以看到文件头部出现了我们指定的注释信息:
<pre>
/*! This file is created by mutouren */
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
// 后面代码省略......
</pre>

一个 url-loader 来说,它会将样式中引用到的图片转为模块来处理,使用该加载器需要先进行安装:
<pre>
npm install url-loader
</pre>

修改style.css文件
<pre>
body {
color:#fff;
background: url('./logo.png');
}
</pre>

配置webpack.config.js文件
<pre>
module.exports = {
entry: "./entry.js",
output: {
path: __dirname,
filename: "bundle.js"
},
module: {
loaders: [
{ test: /.css$/, loader: "style!css" },
{ test: /.(png|jpg)$/, loader: "url?limit=40000" } // 添加到这
]
}
};
</pre>

注意后面那个limit的参数,当你图片大小小于这个限制的时候,会自动启用base64编码图片。

我们还是运行
webpack
将会看到背景图片已设置成功。

八.在 Webpack 中使用别名
模块别名定义,方便后续直接引用别名,无须多写长长的地址,比如我们现在想要把scripts/jquery.min.jsjquery压缩文件打包.

别名(resolve.alias) 是 Webpack 的一个配置项,它的作用是把用户的一个请求重定向到另一个路径,例如通过修改 webpack.config.js 配置文件,jquery为别名加入:
<pre>
resolve: {
alias: {
jquery: "./scripts/jquery.min.js"
}
}
</pre>
例如我们之前不用别名,在entry.js中,想要把jquery打包
<pre>
require('./scripts/jquery.min.js');
</pre>
设置别名,就可以修改为
<pre>
require('jquery');
</pre>
这样待打包的脚本中的 require('jquery'); 其实就等价于 require('./scripts/jquery.min.js'); 。通过别名的使用在本例中可以减少几乎一半的时间。

我们把需要的jquery打包了,但是现在前台页面想要直接用还是不可以的,需要我们把jquery暴露出来。

你可能在全局中使用了一个压缩版本的 jquery,为了修复你可以安装这个暴露全局加载器
<pre>
npm install expose-loader --save-dev
</pre>

然后像下面这样修改entry.js:
<pre>
require('expose?$!jquery');
</pre>

把$作为别名为jquery的变量暴露到全局上下文中。

现在我们在页面就可以使用$,例如:
<pre>
$('h1').text();
</pre>

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

推荐阅读更多精彩内容

  • 版权声明:本文为博主原创文章,未经博主允许不得转载。 webpack介绍和使用 一、webpack介绍 1、由来 ...
    it筱竹阅读 11,025评论 0 21
  • GitChat技术杂谈 前言 本文较长,为了节省你的阅读时间,在文前列写作思路如下: 什么是 webpack,它要...
    萧玄辞阅读 12,669评论 7 110
  • 无意中看到zhangwnag大佬分享的webpack教程感觉受益匪浅,特此分享以备自己日后查看,也希望更多的人看到...
    小小字符阅读 8,134评论 7 35
  • 记得2004年的时候,互联网开发就是做网页,那时也没有前端和后端的区分,有时一个网站就是一些纯静态的html,通过...
    阳阳阳一堆阳阅读 3,270评论 0 5
  • 李连杰近日遭传出“突发性心肌梗塞,送院后不治身亡”的乌龙死讯,让众人相当惊讶。不过,向华强的妻子陈岚在29日下午出...
    上善若水sunny阅读 719评论 6 5