开发
Parcel 内置了开发服务器,支持热重载、HTTPS、API 代理等功能。
开发服务器
#当您运行默认的 parcel
命令(parcel serve
的快捷方式)时,Parcel 会自动启动内置的开发服务器。默认情况下,它在 http://localhost:1234 启动服务器。如果端口 1234
已被占用,则会使用备用端口。Parcel 启动后,开发服务器监听的位置将打印到终端。
开发服务器支持多个选项,您可以通过 CLI 选项指定:
-p
,--port
– 覆盖默认端口。也可以使用PORT
环境变量设置端口。--host
– 默认情况下,开发服务器接受所有接口的连接。您可以覆盖此设置,指定只接受来自特定主机的连接。--open
– Parcel 启动后自动在默认浏览器中打开入口。您还可以传递浏览器名称以打开不同的浏览器,例如--open safari
。
热重载
#当您更改代码时,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.accept
和 module.hot.dispose
方法挂接。这些方法允许您在模块的新版本中保存和恢复状态。
module.hot.dispose
接受一个回调,该回调在模块即将被替换时调用。使用它在提供的 data
对象中保存要在模块新版本中恢复的任何状态,或清理在新版本中将重新创建的计时器等。
module.hot.accept
接受一个回调函数,该函数在模块或其任何依赖项更新时执行。您可以使用它通过 module.hot.data
中存储的数据从模块的旧版本恢复状态。
if (module.hot) {
module.hot.dispose(function (data) {
// 模块即将被替换。
// 您可以在 `data` 中保存应在新资源中访问的数据
data.updated = Date.now();
});
module.hot.accept(function (getParents) {
// 模块或其依赖项刚刚更新。
// 在 `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
或 .proxyrc.ts
文件中指定应代理到另一个服务器(例如您的实际 API 服务器或本地测试服务器)的路径。
.proxyrc
/ .proxyrc.json
#在此 JSON 文件中,您指定一个对象,其中每个键是与 URL 匹配的模式,值是 http-proxy-middleware
选项对象:
{
"/api": {
"target": "http://localhost:8000/",
"pathRewrite": {
"^/api": ""
}
}
}
此示例会导致 http://localhost:1234/api/endpoint
被代理到 http://localhost:8000/endpoint
。
.proxyrc.js
/.proxyrc.ts
#对于更复杂的配置,.proxyrc.js
或 .proxyrc.ts
文件允许您附加任何连接兼容的中间件。首先,确保在项目中安装 http-proxy-middleware
。此示例与上面的 .proxyrc
版本具有相同的行为。
const { createProxyMiddleware } = require("http-proxy-middleware");
module.exports = function (app) {
app.use(
"/api",
createProxyMiddleware({
target: "http://localhost:8000/",
pathRewrite: {
"^/api": "",
},
})
);
};
如果您希望将其编写为 ES 模块,可以使用 .proxyrc.mjs
文件,或在 package.json
中使用 "type": "module"
选项。
文件监视器
#为了支持最佳的缓存和开发体验,Parcel 利用了用 C++ 编写的非常快速的监视器,该监视器与每个操作系统的低级文件监视功能集成。使用此监视器,Parcel 监视项目根目录中的每个文件(包括所有 node_modules
)。基于这些文件的事件和元数据,Parcel 确定需要重新构建哪些文件。
文件监视的已知问题
#安全写入
#某些文本编辑器和 IDE 具有"安全写入"功能,通过在保存时复制文件并重命名来防止数据丢失。但是,此功能可能会阻止自动检测文件更新。
要禁用安全写入,请使用以下选项:
- Sublime Text 3:在用户首选项中添加
atomic_save: "false"
。 - IntelliJ:在首选项中搜索"安全写入"并禁用它。
- Vim:在设置中添加
:set backupcopy=yes
。 - WebStorm:在"首选项">"外观和行为">"系统设置"中取消选中"使用'安全写入'"。
- vis:在设置中添加
:set savemethod inplace
。
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 标志在开发期间禁用自动安装。