在开始之前,请确保您使用的是最新版本的 Node,建议至少使用最新的 LTS(长期支持)版本。本书的配置基于一些 LTS Node 特性。您应该在终端上提供node
和npm
命令。Yarn 是 npm 的一个很好的替代品,也适用于本教程。
通过使用 Docker,Vagrant 或 nvm 等解决方案,可以获得更加可控的环境。Vagrant 因依赖虚拟机而受到性能损失,但 Vagrant 在团队中很有价值:每个开发人员都可以拥有相同的接近生产的环境。
完整的配置可以在 GitHub 上获得
设置项目
首先,创建一个项目目录并生成 package.json。npm 使用它来管理项目依赖项。以下是基本命令:
mkdir webpack-demo
cd webpack-demo npm init -y # -y 跳过交互直接生成 *package.json*
您可以手动调整生成的 package.json 以对其进行进一步更改,另外,部分操作也会自动为您修改该文件。官方文档更详细地解释了 package.json 选项。
你可以在 ~/.npmrc 中设置 npm init 时的默认项
安装 Webpack
尽管 Webpack 可以全局安装(npm install webpack -g
),但最好将其作为项目的依赖项进行维护,因为这样您就可以控制正在运行的确切版本。该方法也适用于持续集成(CI)设置。CI 系统可以安装本地依赖项,使用它们编译项目,然后将结果推送到服务器。
要将 Webpack 添加到项目中,请执行:
npm install webpack webpack-cli --save-dev
在此之后,您应该在 package.json devDependencies
部分看到 Webpack 。除了在 node_modules 目录下本地安装软件包以外,npm 还会为可执行文件生成一个入口。
您可以使用
--save
和--save-dev
分离应用程序和开发依赖项。前者安装和写入 package.jsondependencies
字段,而后者写入devDependencies
。
WebPack-CLI 附带了一些功能,包括
init
和migrate
,允许你快速创建新的 WebPack 配置以及从旧版本迁移到新版本。
运行 Webpack
您可以在 npm bin
下指定 Webpack 的执行路径。它最有可能的指向是 ./node_modules/.bin。尝试使用 node_modules/.bin/webpack
或类似命令在终端运行 Webpack。
运行后,可以看到一些版本信息,以及可用的命令选项。
$ node_modules/.bin/webpack
Hash: 6736210d3313db05db58
Version: webpack 4.1.1
Time: 88ms Built at: 3/16/2018 3:35:07 PM
WARNING in configuration
The 'mode' option has not been set. Set 'mode' option to 'development' or 'production' to enable defaults for this environment.
ERROR in Entry module not found: Error: Can't resolve './src' in '.../webpack-demo'
上述输出结果表明 Webpack 找不到要编译的源代码,另外,它还缺少 mode
参数来表明到底是开发环境还是生产环境。
我们可以通过以下手段来解决这些问题:
- 新建 src/index.js 文件,并写入一串代码
console.log("Hello world");
。 - 执行
node_modules/.bin/webpack --mode development
,Webpack 将按内部约定发现源文件。 - 检查 dist/main.js。您将看到一些 Webpack 引导代码,在引导代码后面会发现你熟悉的东西。
尝试
--mode production
,并比较输出
设置资源
为了能构建更多的东西,我们可以向项目添加另一个模块并开始开发一个小型应用程序:
src/component.js
export default (text = "Hello world") => {
const element = document.createElement("div");
};
在 building(node_modules/.bin/webpack --mode development
)之后检查输出,您应该可以看到 dist
目录的 bundle 中的两个模块。
要使输出更清晰,我们可以给 Webpack 传递 --devtool false
参数。 默认情况下,Webpack 将生成基于源代码的映射,传递该参数可以禁用这个行为。有关详细信息,请参阅“Source Maps”一章。
但仍存在一个问题,我们如何在浏览器中测试应用程序呢?
配置 html-webpack-plugin
我们可以生成一个 index.html 文件来解决该问题,通过使用插件和 Webpack 配置来实现这一目标。
首先,安装 html-webpack-plugin:
npm install html-webpack-plugin --save-dev
然后,配置 Webpack
webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
plugins: [
new HtmlWebpackPlugin({
title: 'Webpack demo'
})
]
}
现在配置已完成,我们可以尝试以下操作:
- 使用命令
node_modules/.bin/webpack --mode production
构建项目,您也可以尝试使用development
模式。 - 使用命令
cd dist
进入构建目录。 - 使用
serve
(npm i serve -g
)或类似命令运行服务器。 - 通过 Web 浏览器检查结果,你应该可以看到熟悉的东西。
检查输出
如果执行 node_modules/.bin/webpack --mode production
,你应该看到以下输出:
Hash: aafe36ba210b0fbb7073
Version: webpack 4.1.1
Time: 338ms
Built at: 3/16/2018 3:40:14 PM
Asset Size Chunks Chunk Names
main.js 679 bytes 0 [emitted] main
index.html 181 bytes [emitted]
Entrypoint main = main.js
[0] ./src/index.js + 1 modules 219 bytes {0} [built]
| ./src/index.js 77 bytes [built]
| ./src/component.js 142 bytes [built]
Child html-webpack-plugin for "index.html":
1 asset
Entrypoint undefined = index.html
[0] (webpack)/buildin/module.js 519 bytes {0} [built]
[1] (webpack)/buildin/global.js 509 bytes {0} [built]
+ 2 hidden modules
我们来看看上述输出的含义:
Hash: aafe36ba210b0fbb7073
- 构建的哈希值,通过哈希占位命名,我们在部署时可以使旧的资源失效。哈希将会在“ 给文件名添加哈希值”一章中详细讨论。Version: webpack 4.1.1
- Webpack 版本。Time: 338ms
- 构建所花费的时间。main.js 679 bytes 0 [emitted] main
- 生成资源的名称、大小、与其相关的块的 ID、生成方式的状态信息以及块的名称。index.html 181 bytes [emitted]
- 另一份资源的生成信息。[0] ./src/index.js + 1 modules 219 bytes {0} [built]
- 入口资源的ID、名称、大小、入口块 ID 以及生成方式。Child html-webpack-plugin for "index.html":
- 这是与插件相关的输出。它表示 index.html 是由 html-webpack-plugin 创建的。
仔细观察 dist/
目录下的输出结果,可以在源代码中看到相同的 ID。
Webpack 除了接受配置对象以外,还可以接受配置数组,以及最终返回配置的 Promise 对象
如果你想要寻找一个 html-webpack-plugin 的轻量级替代品,可以看看 mini-html-webpack-plugin,它功能较为简单,也更容易理解。
HtmlWebpackPlugin 扩展
虽然您可以使用自己的模板替换 HtmlWebpackPlugin
模板,但这里还有一些已经写好的模板,比如 html-webpack-template、html-webpack-template-pug。
还有一些扩展 HtmlWebpackPlugin
功能的插件:
- favicons-webpack-plugin 能够生成 favicon。
- script-ext-html-webpack-plugin 使您可以更好地控制 script 标签,并允许您进一步调整脚本的加载。
- style-ext-html-webpack-plugin 将 CSS 引用转换为内联 CSS,这项技术可以把那些重要的 CSS 作为初始内容的一部分发送给客户端。
- resource-hints-webpack-plugin 为您的 HTML 文件添加资源提示,以提升加载速度。
- preload-webpack-plugin 支持脚本的
rel=preload
属性并有助于懒加载,并且它与本书“ 构建”部分中讨论的技术能够很好的结合。 - webpack-cdn-plugin 允许您指定哪些依赖项通过 CDN (内容交付网络)加载,这种技术常用于加载流行库。
- dynamic-cdn-webpack-plugin 实现了类似 webpack-cdn-plugin 的功能。
结论
虽然 Webpack 已经启动运行了,但是它的功能远不止于此。基于现有的 Webpack 功能进行开发是痛苦的。每次更新应用程序时,都必须手动构建它 ,然后刷新浏览器。其实这些都可以交给 Webpack 来做,这是它的高级特性之一。
回顾一下:
- 相较于全局安装 Webpack,本地安装会更好一些;这样你就可以使用特定的版本了,而且作为本地依赖项,更利于持续集成。
- Webpack 通过 webpack-cli 包提供了命令行界面。即使没有配置,您也可以使用它,但任何高级用法都需要配置。
- 如果配置比较复杂,您应该编写一个单独的 webpack.config.js 文件。
HtmlWebpackPlugin
可用于生成应用程序的 HTML 入口点。在“多页”一章中,您将了解如何使用它生成多个单独的页面。- 使用 npm package.json 脚本来管理 Webpack 很方便。您可以使用它处理一些轻量级的任务以及 Webpack 之外的系统功能。
在下一章中,您将学习如何通过启用自动浏览器刷新来改善开发体验。