开发

Parcel 内置了一个开发服务器,开箱即用,支持热重载、HTTPS、API 代理等功能。

开发服务器

#

当您运行默认的 parcel 命令时,Parcel 的内置开发服务器会自动启动,它是 parcel serve 的快捷方式。默认情况下,它会在 http://localhost:1234 上启动一个服务器。如果端口 1234 已经被占用,则会使用备用端口。Parcel 启动后,开发服务器监听的位置会打印到终端。

开发服务器支持多种选项,您可以通过 CLI 选项指定这些选项

热重载

#

当您对代码进行更改时,Parcel 会自动重建已更改的文件并在浏览器中更新您的应用。默认情况下,Parcel 会完全重新加载页面,但在某些情况下,它可能会执行热模块替换 (HMR)。HMR 通过在运行时更新浏览器中的模块来改善开发体验,而无需整个页面刷新。这意味着当您更改代码中的小部分内容时,应用程序状态可以保留。

CSS 更改会通过 HMR 自动应用,无需页面重新加载。当使用具有内置 HMR 支持的框架时,例如 React(通过 Fast Refresh)和 Vue,也是如此。

如果您没有使用框架,可以使用 module.hot API 选择加入 HMR。这将阻止页面重新加载,而是就地应用更新。module.hot 仅在开发中可用,因此您需要在使用它之前检查它是否存在。

if (module.hot) {
module.hot.accept();
}

HMR 通过替换模块的代码,然后重新评估它及其所有父级来工作。如果您需要自定义此过程,可以使用 module.hot.acceptmodule.hot.dispose 方法来挂钩它。这些方法允许您在模块的新版本中保存和恢复状态。

module.hot.dispose 接受一个回调函数,该函数在该模块即将被替换时调用。使用它将任何状态保存到在提供的 data 对象中模块的新版本中恢复的状态,或清理将在新版本中重新创建的计时器等内容。

module.hot.accept 接受一个回调函数,该函数在该模块或其任何依赖项更新时执行。您可以使用它从旧版本模块中恢复状态,使用存储在 module.hot.data 中的数据。

if (module.hot) {
module.hot.dispose(function (data) {
// module is about to be replaced.
// You can save data that should be accessible to the new asset in `data`
data.updated = Date.now();
});

module.hot.accept(function (getParents) {
// module or one of its dependencies was just updated.
// data stored in `dispose` is available in `module.hot.data`
let { updated } = module.hot.data;
});
}

开发目标

#

使用开发服务器时,一次只能构建一个目标。默认情况下,Parcel 使用支持现代浏览器的开发目标。这意味着禁用针对旧版浏览器的现代 JavaScript 语法的转译。

如果您需要在旧版浏览器中测试,可以提供 --target CLI 选项来选择要构建的目标。例如,要构建在您的 package.json 中定义的“legacy”目标,请使用 --target legacy。如果您没有定义任何显式目标,并且您的 package.json 中只有 browserslist,则可以使用隐式默认目标 --target default。这将导致您的源代码像在生产中一样被转译。

有关更多信息,请参阅 目标 文档。

延迟模式

#

在开发中,等待整个应用程序构建完成才能启动开发服务器可能会令人沮丧。这在处理具有许多页面的大型应用程序时尤其如此。如果您只在一个功能上工作,则无需等待所有其他功能构建完成,除非您导航到它们。

您可以使用 --lazy CLI 标志告诉 Parcel 延迟构建文件,直到它们在浏览器中被请求,这可以显着减少开发构建时间。服务器快速启动,当您第一次导航到页面时,Parcel 只构建该页面所需的必要文件。当您导航到另一个页面时,该页面将按需构建。如果您导航回之前构建的页面,它会立即加载。

parcel 'pages/*.html' --lazy

这也适用于动态 import(),而不仅仅是单独的入口。因此,如果您有一个页面包含动态加载的功能,则该功能将不会构建,直到它被激活。当它被请求时,Parcel 会急切地构建所有依赖项,而无需等待它们被请求。

缓存

#

Parcel 将它构建的所有内容缓存到磁盘。如果您重新启动开发服务器,Parcel 只会重建自上次运行以来已更改的文件。Parcel 会自动跟踪构建中涉及的所有文件、配置、插件和开发依赖项,并在发生更改时细粒度地使缓存失效。例如,如果您更改了一个配置文件,所有依赖于该配置的源文件都将被重建。

默认情况下,缓存存储在项目中的 .parcel-cache 文件夹中。您应该将此文件夹添加到您的 .gitignore(或等效项)中,以便它不会在您的仓库中提交。您也可以使用 --cache-dir CLI 选项覆盖缓存的位置。

也可以使用 --no-cache 标志禁用缓存。请注意,这只会禁用从缓存中读取 - .parcel-cache 文件夹仍然会创建。

HTTPS

#

有时,您可能需要在开发期间使用 HTTPS。例如,您可能需要使用特定主机名来进行身份验证 cookie,或者调试混合内容问题。Parcel 的开发服务器开箱即用地支持 HTTPS。您可以使用自动生成的证书,也可以提供您自己的证书。

要使用自动生成的自签名证书,请使用 --https CLI 标志。第一次加载页面时,您可能需要在浏览器中手动信任此证书。

parcel src/index.html --https

要使用自定义证书,您需要使用 --cert--key CLI 选项分别指定证书文件和私钥。

parcel src/index.html --cert certificate.cert --key private.key

API 代理

#

为了在开发 Web 应用程序时更好地模拟实际的生产环境,您可以在 .proxyrc.proxyrc.json.proxyrc.js 文件中指定应代理到另一个服务器(例如您的真实 API 服务器或本地测试服务器)的路径。

.proxyrc / .proxyrc.json

#

在此 JSON 文件中,您指定一个对象,其中每个键都是与 URL 匹配的模式,而值是 http-proxy-middleware 选项 对象

.proxyrc
{
"/api": {
"target": "http://localhost:8000/",
"pathRewrite": {
"^/api": ""
}
}
}

此示例将导致 http://localhost:1234/api/endpoint 被代理到 http://localhost:8000/endpoint

.proxyrc.js

#

对于更复杂的配置,.proxyrc.js 文件允许您附加任何与 connect 兼容的中间件。首先,确保您已将 http-proxy-middleware 安装到您的项目中。此示例与上面的 .proxyrc 版本具有相同的行为。

.proxyrc.js
const { createProxyMiddleware } = require("http-proxy-middleware");

module.exports = function (app) {
app.use(
createProxyMiddleware("/api", {
target: "http://localhost:8000/",
pathRewrite: {
"^/api": "",
},
})
);
};

如果您想将其编写为 ES 模块,可以使用 .proxyrc.mjs 文件,或者在您的 package.json 中使用 "type": "module" 选项。

文件观察者

#

为了支持最佳的缓存和开发体验,Parcel 利用了一个用 C++ 编写的非常快的观察者,它与每个操作系统的底层文件观察功能集成在一起。使用此观察者,Parcel 会观察项目根目录中的每个文件(包括所有 node_modules)。根据这些文件的事件和元数据,Parcel 会确定哪些文件需要重建。

文件观察已知问题

#
安全写入
#

一些文本编辑器和 IDE 具有“安全写入”功能,该功能通过复制文件并在保存时重命名文件来防止数据丢失。但是,此功能可能会阻止自动检测文件更新。

要禁用安全写入,请使用以下提供的选项

Linux:设备上没有空间
#

根据您的项目的规模和操作系统的观察者限制,当您在 Linux 上运行 Parcel 时,此错误可能会弹出。要解决此问题,请更改 sysctl 配置,以便 fs.inotify 具有更高的 max_user_watches 值。

您可以通过在 /etc/sysctl.conf 中添加或更改以下行来实现

fs.inotify.max_queued_events = 16384
fs.inotify.max_user_instances = 128
fs.inotify.max_user_watches = 16384

如果此错误仍然存在,您可以尝试进一步增加这些值。

使用 Dropbox、Google Drive 或其他云存储解决方案
#

最佳做法是不将 Parcel 项目放在使用 Dropbox 或 Google Drive 等工具同步到云的文件夹中。这些解决方案会创建大量文件系统事件,这些事件可能会干扰我们的观察者并导致不必要的重建。

自动安装

#

当您使用默认情况下未包含的语言或插件时,Parcel 会自动将必要的依赖项安装到您的项目中。例如,如果您包含一个 .sass 文件,Parcel 将安装 @parcel/transformer-sass 插件。发生这种情况时,您将在终端中看到一条消息,并且新依赖项将添加到您的 package.json 中的 devDependencies 中。

Parcel 会根据您的项目中的锁定文件自动检测您使用的包管理器。例如,如果找到 yarn.lock,则将使用 Yarn 来安装包。如果未找到锁定文件,则将根据系统上安装的内容选择包管理器。目前支持以下包管理器,按优先级排序:

默认情况下,自动安装仅在开发过程中发生。在生产构建过程中,如果缺少依赖项,构建将失败。您也可以使用 --no-autoinstall CLI 标志在开发过程中禁用自动安装。