Webpack book --- 开发篇

栏目: 编程语言 · 发布时间: 5年前

内容简介:看了 @SurviveJS 上 webpack book 这本书,书中内容详实,条理非常清晰,收获很多。所以选择将它翻译一下,并分享出来。要不然平常在配置项目里的 webpack 时,总是在网上 google 一段,要不是官方教程里查一查。在加上 webpack 的生态也越来越庞大,loader、plugin 也越来越多,导致整体的配置很迷。在开始之前,请确保你使用的是最新版本的Node。 应该至少使用最新的LTS(长期支持)版本。本书的配置考虑了 LTS Node 所包含的功能。同时你的终端还应该支持 n

看了 @SurviveJS 上 webpack book 这本书,书中内容详实,条理非常清晰,收获很多。所以选择将它翻译一下,并分享出来。要不然平常在配置项目里的 webpack 时,总是在网上 google 一段,要不是官方教程里查一查。在加上 webpack 的生态也越来越庞大,loader、plugin 也越来越多,导致整体的配置很迷。

原文地址: survivejs.com/webpack/dev…

在开始之前,请确保你使用的是最新版本的Node。 应该至少使用最新的LTS(长期支持)版本。本书的配置考虑了 LTS Node 所包含的功能。同时你的终端还应该支持 node 和 npm 命令。也可以利用 Yarn 来代替 npm,同样适用于本教程。

Getting Started

配置项目

首先运行基本指令,为项目创建一个目录并配置 package.json,利用 npm 来管理项目依赖项。

mkdir webpack-demo
cd webpack-demo
npm init -y # -y generates *package.json*, skip for more control
复制代码

你也可以手动生成的 package.json 以对其进行更改。 官方文档更详细地解释了package.json 选项。

安装 Webpack

尽量避免全局安装 Webpack (npm install webpack -g),但最好将其作为项目的依赖项进行维护。这样你可以控制正在运行的版本,从而避免问题。

这种方法同样也适用于持续集成(CI)设置。 CI系统可以安装本地依赖项,使用它们编译项目,然后将结果推送到服务器。

执行以下命令,将 webpack 添加到项目中

npm install webpack webpack-cli --save-dev
复制代码

安装成功之后,在 package.json 的 devDependencies 中会出现一个 webpack 项。除了在 node_modules 目录下安装了软件包之外,npm 也会为可执行文件生成一个入口。

可以用 --save-dev--save 来区分应用和开发的依赖项。使用前者会写入 package.json 的 dependencies 字段,而后者则会写到 devDependencies 中。

webpack-cli 附带了其他功能,包括 init 和 migrate 命令,使你可以快速创建新的 webpack 配置,并从旧版本更新到新版本。

执行Webpack

你可以使用 npm bin 来获取可执行文件的绝对路径。一般为 ./node_modules/.bin。

npm bin // C:\Users\Gepangz\Desktop\webpack-demo\developing\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 没有找到可编译的资源。并且 WARNING 还提示缺少参数 mode ,它主要用来区分开发环境和生产环境。

为了使得 webpack 能够成功运行,我们应该解决这两个问题:

console.log("Hello world")
node_modules/.bin/webpack --mode development

尝试使用 --mode production 来对比结果。

配置资源

为了使构建更加复杂,我们可以向项目添加另一个模块并着手开发一个小应用程序:

src/component.js

export default (text = "Hello world") => {
  const element = document.createElement("div");

  element.innerHTML = text;

  return element;
};
复制代码

我们还必须修改原始文件以导入新文件并通过 DOM 呈现应用程序:

src/index.js

import component from "./component";

document.body.appendChild(component());
复制代码

运行构建指令 node_modules / .bin / webpack --mode development ,检查输出 dist/ 目录。你应该看到 Webpack 写入 dist 目录的 main.js 中打包了 src 中的两个模块。

要使输出更清晰,请将 --devtool false 参数传递给 Webpack。 默认情况下,Webpack 将生成基于 eval 的源映射,这样做会禁用该行为。 有关详细信息,请参阅。

但仍存在一个问题。 我们如何在浏览器中测试应用程序?

安装 Configuring html-webpack-plugin 插件

可以通过编写,并引入生成的文件的 index.html 文件来解决该问题。 但是我们可以使用插件和 Webpack 配置来实现这一目标,而不是自己做。

首先,安装 html-webpack-plugin

npm install html-webpack-plugin --save-dev
复制代码

连接该插件和 webpack,在与 package.json 同级的目录上,创建 webpack.config.js 文件。

webpack.config.js

const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      title: "Webpack demo",
    }),
  ],
};
复制代码

现在配置已完成,可以尝试以下操作:

  1. 运行 node_modules / .bin / webpack --mode production 来构建项目,也可以尝试开发模式 --development
  2. 进入打包之后的文件 cd dist
  3. 在该目录下运行 serve 指令(npm i serve -g);
  4. 通过 Web 浏览器检查结果。 你应该看到 src 内脚本的内容。
Webpack book --- 开发篇

检查输出

如果你执行 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 - 构建的哈希,可以使用此选项通过[hash] 占位符使资源无效。具体见 添加 Hashes 到文件名中
  • 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" - 这是与插件相关的输出。 在这种情况下,html-webpack-plugin自己创建这个输出。

仔细检查 dist/ 目录下面的打包后的文件。如果仔细观察,可以在源代码中看到相同的 ID。

除了配置对象之外,webpack 还接受一系列配置。 甚至还可以返回 Promise并最终解析为配置。

如果你想要一个替代 html-webpack-plugin 的替代品,请参阅mini-html-webpack-plugin。 它功能相对较少,理解起来也更简单。

添加构建快捷方式

每次打包都需要执行 node_modules/.bin/webpack,这种方式十分的繁琐。所以,需要做些什么来简化操作。向 package.json 中添加

package.json

"scripts": {
  "build": "webpack --mode production"
}
复制代码

在终端中运行 npm run build 会发现得到的结果与之前一致。npm 临时地将 node_modules/.bin 添加到了运行此命令的路径中。所以,你可以直接执行 build,而不再需要编写 node_modules/.bin/webpack

你可以通过 npm run 执行此类脚本,并且可以在项目中的任何位置使用。如果仅运行 npm run ,终端中就会罗列出可用脚本。

想要更进一步的话,请在终端配置中使用 alias 命令设置系统级别名。 例如,可以将 nrb 映射到 npm run build。

HtmlWebpackPlugin 扩展

虽然你可以用自己的模板来代替 HtmlWebpackPlugin 模板,也可以采用一些有预制模板的插件,例如 html-webpack-template 或 html-webpack-template-pug。

这里有一些特殊的插件可以扩展 HtmlWebpackPlugin 的功能:

总结

现在你已经设法启动并运行webpack,但它还没有那么多功能。而且它用来开发应用程序也是比较痛苦,因为每次开发完应用程序的时候,都必须要 npm run build ,然后再刷新游览器。所以,我们要着手使用 webpack 更高级的功能。

回顾一下,本章重点

  • 本地安装 webpack 代替全局安装,从而方便控制版本。本地依赖项也适用于持续集成环境;
  • Webpack 通过 webpack-cli 包提供命令行界面。 即使没有配置,也可以使用它,但任何高级用法都需要配置;
  • 要编写更复杂的设置,很可能必须编写单独的 webpack.config.js 文件;
  • HtmlWebpackPlugin 可用于生成应用程序的 HTML 入口点,在Multiple Pages中,将了解如何使用它生成多个单独的页面;
  • 使用 npm package.json 脚本来管理 webpack 很方便。可以将它用作轻量的任务运行器并使用 webpack 之外的系统功能。

在下一章中,将学习如何通过启用自动浏览器刷新来改善开发人员体验。

webpack-dev-server

现在有一些工具,像 LiveReload、Browsersync 都允许你在开发应用程序时刷新浏览器,并且避免因为 CSS 更改而刷新 。可以通过安装 browser-sync-webpack-plugin ,同时设置 Browsersync 以在 webpack 中使用这项功能,但是在 webpack 商店中有更好的解决方法。

Webpack watch 模式以及webpack-dev-server

构建良好体验的开发环境,第一步就是要使用 webpack 的 watch 模式。你可以通过将在命令后面添加 --watch 来激活该模式。

npm run build -- --watch
复制代码

启用之后,在 watch 模式下,webpack 检测文件的变动。如果发生了改变,则会自动重新编译。webpack-dev-server(WDS)也是实现了一种 watch 模式,甚至功能更加强大。

WDS 是在 内存中 运行的开发服务器,这意味着打包的结果不会写入文件但会 存储在内存中 。 在尝试调试代码和样式时,这点很重要。

默认情况下,WDS 会在你开发应用程序时自动在浏览器中刷新内容,无需手动执行此操作。 同时它也支持高级 Webpack 功能,模块热更换(HMR)。

HMR 允许在没有完全刷新的情况下更新浏览器状态,这使得它非常适合 React 这类前端框架,因为更新会破坏应用程序状态。具体请见 Hot Module Replacement

WDS 提供了一个界面,可以动态修改代码,但为了使其高效工作,就必须为客户端代码实现此接口。对 CSS 之类的语言来说,这可能是微不足道的,因为它是无状态的,但 JavaScript 框架和库的来说这个问题很重要。

从 WDS 中发送文件

尽管从性能方面来考虑,WDS 最好是运行在内存中,但是有时候也需要将文件发送到文件系统。如果你希望在其他服务器上查找一些文件,这就会变的至关重要。 write-file-webpack-plugin 可以帮你实现这个功能。

你必须要知道 WDS 要严格用于开发环境中。如果想要托管应用程序,请考虑其他的解决方案,例如 Apache 或者 Nginx。

WDS入门

首先安装 webpack-dev-server

npm install webpack-dev-server --save-dev
复制代码

同之前一样,安装之后,会在 npm bin 目录下生成一个命令,可以在那里运行 webpack-dev-server。运行 WDS 后,你就有一个运行在 http:// localhost:8080 的开发服务器。

将 WDS 添加到项目中

要将 WDS 集成到项目中,就需要定义用于启动它的 npm 脚本。要遵循 npm 约定,请将其称为start,如下所示:

"scripts": {
  "start": "webpack-dev-server --mode development",
  "build": "webpack --mode production"
},
复制代码

WDS 像 webpack 一样会选择配置。适用相同的规则。

当你在终端运行 npm run start 以及 npm start 时,会打印出来

> webpack-dev-server --mode development

ℹ 「wds」: Project is running at http://localhost:8080/
ℹ 「wds」: webpack output is served from /
ℹ 「wdm」: Hash: eb06816060088d633767
Version: webpack 4.1.1
Time: 608ms
Built at: 3/16/2018 3:44:04 PM
     Asset       Size  Chunks                    Chunk Names
   main.js    338 KiB    main  [emitted]  [big]  main
index.html  181 bytes          [emitted]
Entrypoint main [big] = main.js
...
复制代码

服务器已经运行,如果你在游览器中访问 http://localhost:8080/ ,会看到如下场景

Webpack book --- 开发篇

如果你尝试修改代码,在终端中就会看到对应输出,同时游览器还会执行硬刷新。

WDS 尝试在另一个端口运行,以防占用默认端口。 终端输出打印出它最终运行的位置。 您可以使用 netstat -na |等命令调试情况 grep 8080。如果8080 端口上运行了某些东西,它应该在Unix上显示一条消息。

除了生产和开发之外,还有第三种模式,none,它禁用所有内容,并且接近 webpack 4 之前的行为。

利用 Webpack.config.js 来配置 WDS

可以通过 webpack 配置中的 devServer 字段来自定义 WDS 功能。也可以利用 CLI设置大多数项。两种方法相比较,还是通过 webpack 管理它们是一种不错的方法。

启用其他功能,具体如下

webpack.config.js

module.exports = {
  ...
  devServer: {
    // Display only errors to reduce the amount of output.
    stats: "errors-only",
    // Parse host and port from env to allow customization.
    //
    // If you use Docker, Vagrant or Cloud9, set
    // host: "0.0.0.0";
    //
    // 0.0.0.0 is available to all network devices
    // unlike default `localhost`.
    host: process.env.HOST, // Defaults to `localhost`
    port: process.env.PORT, // Defaults to 8080
    open: true, // Open the page in browser
  },
  ...
};
复制代码

完成此更改后,也可以通过修改环境参数来配置服务器主机和端口选项(例如:PORT = 3000 npm start)。

dotenv 允许你通过修改 .env 文件来定义环境变量。dotenv 允许你快速控制设置的主机和端口设置。

如果在项目中使用 HTML5 History API,则需要启用 devServer.historyApiFallback。

启用错误覆盖

WDS 提供了一个 overlay 字段,用于捕获与编译相关的警告和错误:

webpack.config.js

module.exports = {
  devServer: {
    ...
    overlay: true,
  },
  ...
};
复制代码

立即运行服务器(npm start)并中断代码以在浏览器中查看:

Webpack book --- 开发篇

如果你想要更清晰的错误提示,可以采用 error-overlay-webpack-plugin ,它可以更好地定位到错误。

WDS overlay 不会捕获应用程序的运行时错误。

启用热模块更换

模块热更换是 webpack 与众不同的功能之一。实现它需要在服务器端和客户端上进行额外的工作。 Hot Module Replacement 更详细地讨论这个注意,如果需要将 HMR 集成到项目中,请自行查看。

访问远程服务器

可以通过设置环境变量来定义主机和端口(即,在 Unix export PORT = 3000 或在Windows 上 SET PORT = 3000)。大多数平台上的默认设置已足够。

要想访问你的服务器,就需要明确机器的 IP。在Unix上,这可以使用 ifconfig | grep inet 来实现。在Windows上,可以使用 ipconfig 。npm 包,例如 node-ip也派上用场。特别是在 Windows 上,你需要设置 HOST 来匹配 IP 以使其可访问。

快速开发配置

WDS 的功能是,当我们修改打包文件时会自动重启这个服务,但是如果我们修改了 webpack 的配置呢?每一次修改配置之后,都需要重新启动开发服务器,显然这项操作是冗余的。如 GitHub 中所讨论的那样,可以使用 nodemon 工具自动执行该过程。

首先安装 nodemon 工具

npm install nodemon --save-dev
复制代码

之后,利用它监听 webpack 配置的改变,并在重启 WDS 。

package.json

"scripts": {
  "start": "nodemon --watch webpack.config.js --exec \"webpack-dev-server --mode development\"",
  "build": "webpack --mode production"
},
复制代码

WDS 在未来的某个版本可能会支持这个功能,具体 will support the functionality 。如果你想让它在更改配置时实现重新加载,那么现在就应该实现此解决方法。

利用轮询代替监听文件变化

在旧版本的 Windows,Ubuntu,Vagrant 和 Docker 上使用 WDS 可能会出现问题,有时修改文件却没有反应。这时可以启用轮询:

webpack.config.js

const path = require("path");
const webpack = require("webpack");

module.exports = {
  devServer: {
    watchOptions: {
      // Delay the rebuild after the first change
      aggregateTimeout: 300,

      // Poll using interval (in ms, accepts boolean too)
      poll: 1000,
    },
  },
  plugins: [
    // Ignore node_modules so CPU usage with poll
    // watching drops significantly.
    new webpack.WatchIgnorePlugin([
      path.join(__dirname, "node_modules")
    ]),
  ],
};
复制代码

轮询设置虽然更耗费资源,但是也有它所适用的场景。

webpack-dev-server 的代替方法

你可以选择在终端中传递 WDS 的参数,因为这样有助于保持 package.json 的整洁。通过也可以很明确的表明,具体发生了什么事情,而不需要去查看 webpack。

或者,你也可以设置 Express 服务器并使用中间件。有几种选择

如果你想要更高的灵活度,可以使用Node API 。

webpack-dev-server 的其他特性

WDS 提供的功能远不止以上这些。你还应该注意几个相关方面:

  • devServer.contentBase - 假设你没有动态生成 index.html,并且想要在特定的目录中维护它。可以配置 contentBase 来指向特定路径(例如,"build" 或者 ["build", "images"])。该值默认为项目根目录;
  • devServer.proxy - 如果你使用了多个服务器,那么就需要使用 WDS 的代理功能。代理设置接受一个映射(例如 { "/api": " http://localhost:3000/api " })将匹配的查询解析到另一台服务器。 默认情况下禁用代理设置;
  • devServer.headers - 附加一些信息到请求头中。

The official documentation 提供了更多选项。

webpack-plugin-serve - webpack-dev-server的替代方案

webpack-plugin-serve 是一个包含开发所需功能的 webpack 插件。假设你已经运行了 webpack 的 watch 模式。它与 webpack-dev-server 的功能十分相近,同时提供独特的功能,例如全功能模块热替换,即使在多编译器模式下使用 webpack 时(即,当你为其提供一系列配置时)。Status overlay 也是一个非常便利的功能。

方便开发的插件

webpack 插件生态系统是非常丰富的,有很多插件可以帮助专门开发:

  • case-sensitive-paths-webpack-plugin - 可以使你不用顾虑当前环境是否支持大小写(例如兼顾不区分大小写的开发环境 macOS 或 Windows 和 区分大小写的生产环境 Linux);
  • npm-install-webpack-plugin - 当你将新包导入项目时,允许 webpack 自动使用 npm 安装并连接到 package.json 中;
  • react-dev-utils - 包含在 Create React App 内的实用程序。尽管它的名字像似只能用于 React,但是其实它也可以用在其他方面。 如果只想要webpack 消息格式化,请考虑 webpack-format-messages;
  • start-server-webpack-plugin - 能够在 webpack 构建完成后启动服务器。

输出插件

还有一些插件可以让 webpack 输出更容易被注意和理解。

  • system-bell-webpack-plugin - webpack 失败时触发响铃;
  • webpack-notifier - 使用系统通知你,方便随时了解webpack状态;
  • nyan-progress-webpack-plugin - 整理构建过程中 webpack 的输出。 但是如果使用像 Travis 这样的持续集成(CI)系统,请小心,因为它们可以破坏输出;
  • friendly-errors-webpack-plugin - 改善了 webpack 的错误报告。 它捕获常见错误并以更友好的方式显示它们;
  • webpack-dashboard - 能够在终端上显示一个较为完成的仪表盘。如果你喜欢清晰的视觉输出,那么它就会排上用场。

WDS 总结

WDS 补充了 webpack,并通过提供很多面向开发的功能使其对开发者更友好。

回顾一下:

  • Webpack 的 watch 模式是迈向更好的开发体验的第一步。编辑源文件时,可以使用 webpack 重新编译包;
  • WDS 可以在更改时自动刷新浏览器,同时它还实现了模块热替换;
  • 默认配置的 WDS 在特定系统上可能存在问题。因此,消耗更多资源的轮询也是一种备选方案;
  • 可以使用中间件将 WDS 集成到现有服务器节点中。这样做比依赖命令行界面更容易控制;
  • WDS 还具备代理、配置请求头等功能。

在下一章中,您将学习如何组合配置,以便可以在本书后面进一步开发。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

垃圾回收的算法与实现

垃圾回收的算法与实现

中村成洋、相川光 / 丁灵 / 人民邮电出版社 / 2016-7-1 / 99.00元

★ Ruby之父Matz作推荐语:上古传承的魔法,彻底揭开垃圾回收的秘密! ★ 日本天才程序员兼Lisp黑客竹内郁雄审校 本书前半介绍基本GC算法,包括标记-清除GC、引用计数、复制算法的GC、串行GC的算法、并发GC的算法等。后半介绍V8、Rubinius、Dalvik、CPython等几种具体GC的实现。本书适合各领域程序员阅读。一起来看看 《垃圾回收的算法与实现》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具