内容简介:看了 @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", }), ], }; 复制代码
现在配置已完成,可以尝试以下操作:
- 运行
node_modules / .bin / webpack --mode production
来构建项目,也可以尝试开发模式--development
; - 进入打包之后的文件
cd dist
; - 在该目录下运行
serve
指令(npm i serve -g); - 通过 Web 浏览器检查结果。 你应该看到 src 内脚本的内容。
检查输出
如果你执行 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 的功能:
- 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 功能并帮助延迟加载,详情请见Building;
- webpack-cdn-plugin - 提供将指定内容分发到 CDN 的功能,常用于快速前端库、框架的加载速度;
- dynamic-cdn-webpack-plugin - 与 webpack-cdn-plugin 大体相同。
总结
现在你已经设法启动并运行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/
,会看到如下场景
如果你尝试修改代码,在终端中就会看到对应输出,同时游览器还会执行硬刷新。
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)并中断代码以在浏览器中查看:
如果你想要更清晰的错误提示,可以采用 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 还具备代理、配置请求头等功能。
在下一章中,您将学习如何组合配置,以便可以在本书后面进一步开发。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- ABP开发框架前后端开发系列---(14)基于Winform的ABP快速开发框架
- Java开发人员的Flex开发
- Java开发人员的Flex开发
- 行为驱动开发让开发做正确事
- 让开发者专注于应用开发,OpenCenter 3.0 开发者预览版发布
- 让开发者专注于应用开发,OpenCenter 3.0 开发者预览版发布
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
垃圾回收的算法与实现
中村成洋、相川光 / 丁灵 / 人民邮电出版社 / 2016-7-1 / 99.00元
★ Ruby之父Matz作推荐语:上古传承的魔法,彻底揭开垃圾回收的秘密! ★ 日本天才程序员兼Lisp黑客竹内郁雄审校 本书前半介绍基本GC算法,包括标记-清除GC、引用计数、复制算法的GC、串行GC的算法、并发GC的算法等。后半介绍V8、Rubinius、Dalvik、CPython等几种具体GC的实现。本书适合各领域程序员阅读。一起来看看 《垃圾回收的算法与实现》 这本书的介绍吧!