本文提供Webpack的7分钟快速入门指南,涵盖从环境搭建、全局与本地安装,到核心概念如模块打包、Loader转换器及插件系统的详细解析。通过实战示例演示如何配置entry、output、module及plugins,并介绍url-loader、BannerPlugin等常用工具的使用方法及模块别名技巧,帮助开发者快速掌握Webpack基础应用。
Webpack 概述与核心优势
一、Webpack 概述
Webpack 本质上是一个模块打包工具。它能够对项目中模块之间的依赖关系进行静态分析,并依据预设规则将这些模块处理生成最终的静态资源文件。

Webpack 工作原理示意图
二、为何选择 Webpack
现有的许多模块管理和打包工具在面对大型项目,特别是单页 Web 应用时显得力不从心。主要挑战在于如何在庞大的代码库中有效管理模块资源的分割与存储,维护复杂的依赖关系,并无缝整合生成适合浏览器加载的静态资源。Webpack 凭借以下优势解决了这些问题:
1. 支持按需加载的依赖树拆分:Webpack 提供同步和异步两种模块依赖组织方式。异步依赖会被视为分割点,从而形成新的代码块。优化依赖树后,每个异步区块都会打包为独立文件。
2. 最小化初始加载耗时:Webpack 利用异步 I/O 技术和多级缓存机制显著提升运行效率,使其能够以极快的速度进行增量编译。
3. 将各类静态资源视为模块:虽然 Webpack 原生仅支持 JavaScript 模块,但通过 loader 转换器,它可以处理各种类型的资源并将其转换为 JavaScript 模块。这意味着任何资源都能成为 Webpack 处理的对象。
4. 强大的第三方库整合能力:Webpack 拥有智能解析器,能处理 CommonJS、AMD 或普通 JS 文件等多种形式的第三方库。甚至在加载依赖时,也支持使用动态表达式,例如 require("./templates/" + name + ".jade")。
5. 自定义打包逻辑:Webpack 具备功能丰富的插件系统,其核心功能大多基于此运行。开发者可以开发或使用开源插件,以满足多样化的定制需求。
6. 适用于大型项目:无论是单页应用还是多页应用,Webpack 都能提供有效的支持。
Webpack 安装与环境准备
三、安装 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 分支上的测试版。测试版包含一些实验性功能且与稳定版不兼容,正式项目应使用稳定版。
# 查看 webpack 版本信息
$ npm info webpack
# 安装指定版本的 webpack
$ npm install webpack@1.12.x --save-dev
Webpack 基础使用与模块打包
四、在项目中使用 Webpack
首先准备一个静态页面 index.html:
<!-- index.html -->
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script src="bundle.js"></script>
</body>
</html>
接着创建一个 JS 入口文件 entry.js:
// entry.js
pico entry.js
// 进入编辑器输入
document.write('It works.');
// 保存并退出
然后编译 entry.js 并打包输出到 bundle.js,运行命令:
$ webpack ./entry.js bundle.js
若成功,打包过程将显示如下日志:
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]
点击访问测试链接将打开新窗口,页面应显示 'It works.'。
注意:后续课程中创建和编辑文件均使用 pico 编辑器。
接下来,将部分代码移至额外文件 content.js 并修改入口 entry.js:
// content.js
pico content.js
// 编辑内容
module.exports = "It works from content.js.";
// 修改entry.js
//document.write('It works.');
document.write(require("./content.js")); // 添加content.js
编译文件
$ webpack ./entry.js bundle.js
刷新浏览器窗口,应看到文本 'It works from content.js.'。
执行成功,终端将显示:
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]
Webpack 会分析入口文件,解析包含依赖关系的各个文件。这些模块最终打包到 bundle.js 中。Webpack 为每个模块分配唯一 ID,并通过该 ID 索引和访问模块。页面启动时先执行 entry.js 代码,其他模块则在运行 require 时执行。
Loader 转换器详解
五、Loader 介绍与使用
Webpack 原生仅能处理 JavaScript 模块,若需处理其他类型文件,必须使用 loader 进行转换。
Loader 可视为模块和资源的转换器,它是一个函数,接收源文件作为参数并返回转换结果。通过 require 即可加载任何类型的模块或文件,如 CoffeeScript、JSX、LESS 或图片。
Loader 具备以下特性:
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 可分发附加的任意文件。
假设我们希望在应用中添加一个 CSS 文件。
由于 Webpack 仅能处理 JavaScript,我们需要 css-loader 来处理 CSS,并需要 style-loader 将样式应用到页面中。
安装 Loader:
npm install css-loader style-loader
注意:安装 Loaders(只需本地安装,无需 -g)将创建 node_modules 文件夹,Loaders 将在其中激活。
我们要引入一个 CSS 文件 style.css,首页将 style.css 视为模块,使用 css-loader 读取它,再通过 style-loader 将其插入页面。
添加一个 style.css 文件
body {
background: blue;
}
修改 entry.js:
+ require("!style!css!./style.css"); // 载入 style.css
document.write(require("./content.js"));
重新编译并刷新浏览器,应看到蓝色背景。
扩展名自动绑定 Loader
若每次 require CSS 文件时都要写 Loader 前缀,将非常繁琐。
我们可以根据模块类型(扩展名)自动绑定所需的 Loader,这样只需写 require("./style.css")。
修改 entry.js
- require("!style!css!./style.css");
+ require("./style.css");
document.write(require("./content.js"));
注意:- 表示删除或注释该行,+ 表示新增内容。
编译:
webpack ./entry.js bundle.js --module-bind "css=style!css"
注意:! 在 Shell 中有特殊意义,需进行转义,这样写才能成功执行。
webpack ./entry.js bundle.js --module-bind "css=style!css"
Webpack 配置文件与输出优化
六、配置文件
Webpack 执行时,除命令行传入参数外,还可通过指定配置文件执行。默认情况下,Webpack 会搜索当前目录的 webpack.config.js 文件。该文件是一个 Node.js 模块,返回 JSON 格式的配置信息对象,或通过 --config 选项指定配置文件。
我们将配置选项移至配置文件中,创建 webpack.config.js:
module.exports = {
entry: "./entry.js",
output: {
path: __dirname,
filename: "bundle.js"
},
module: {
loaders: [
{ test: /.css$/, loader: "style!css" }
]
}
};
现在只需运行:
webpack
若成功,将返回运行结果。该命令尝试在当前目录加载 webpack.config.js 文件。
此处对 Webpack 的打包行为进行了配置,主要分为几个部分:
- entry:指定打包入口文件,每个键值对代表一个入口文件
- output:配置打包结果,path 定义输出文件夹,filename 定义打包结果文件名
- module:定义模块处理逻辑,此处可通过 loaders 定义一系列加载器及正则。当加载文件匹配 test 正则时,调用后续 Loader 处理文件,这正是 Webpack 强大的原因。
美化输出
随着项目增长,编译时间可能变长。因此我们需要显示进度条和颜色信息。
我们可以这样操作
webpack --progress --colors
插件系统与高级配置
七、插件
插件可完成 Loader 无法实现的功能。
插件的使用通常在 Webpack 配置信息的 plugins 选项中指定。
Webpack 内置了一些常用插件,也可通过 npm 安装第三方插件。
接下来,利用最简单的 BannerPlugin 内置插件实践插件配置与运行,该插件作用是为输出文件头部添加注释信息。
修改 webpack.config.js,添加 plugins:
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')
]
}
然后运行 webpack,打开 bundle.js,可见文件头部出现了指定的注释信息:
/! This file is created by mutouren /
/**/ (function(modules) { // webpackBootstrap
/**/ // The module cache
/**/ var installedModules = {};
// 后面代码省略......
以 url-loader 为例,它会将样式中引用的图片转为模块处理,使用该 Loader 需先安装:
npm install url-loader
修改 style.css 文件
body {
color:#fff;
background: url('./logo.png');
}
配置 webpack.config.js 文件
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" } // 添加到这
]
}
};
注意后面的 limit 参数,当图片大小小于此限制时,会自动启用 Base64 编码图片。
我们再次运行
webpack
将看到背景图片设置成功。
模块别名与全局变量暴露
八、在 Webpack 中使用别名
模块别名定义方便后续直接引用,无需书写长路径。例如,我们想要将 scripts/jquery.min.js 压缩文件打包。
别名(resolve.alias)是 Webpack 的配置项,作用是将用户请求重定向至另一路径。例如通过修改 webpack.config.js 配置文件,为 jquery 添加别名:
resolve: {
alias: {
jquery: "./scripts/jquery.min.js"
}
}
例如之前不使用别名,在 entry.js 中想要打包 jquery
require('./scripts/jquery.min.js');
设置别名后,可修改为
require('jquery');
这样待打包脚本中的 require('jquery'); 等价于 require('./scripts/jquery.min.js');。使用别名在本例中可减少近一半的打包时间。
我们将 jquery 打包后,前台页面仍无法直接使用,需将其暴露出来。
若在全局中使用了压缩版 jquery,为修复此问题可安装暴露全局的 Loader
npm install expose-loader --save-dev
然后像下面这样修改 entry.js:
require('expose?$!jquery');
将 $ 作为 jquery 的别名暴露到全局上下文中。
现在页面中即可使用 $,例如:
$('h1').text();
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。