开发
Parcel 包含一个开箱即用的开发服务器,支持热重载、HTTPS、API 代理等。
¥Parcel includes a development server out of the box supporting hot reloading, HTTPS, an API proxy, and more.
开发服务器
#¥Dev server
当你运行默认的 parcel
命令(这是 parcel serve
的快捷方式)时,Parcel 的内置开发服务器会自动启动。默认情况下,它在 http://localhost:1234 启动服务器。如果端口 1234
已被使用,则将使用备用端口。Parcel 启动后,开发服务器监听的位置将被打印到终端。
¥Parcel’s builtin dev server is automatically started when you run the default parcel
command, which is a shortcut for parcel serve
. By default, it starts a server at http://localhost:1234. If port 1234
is already in use, then a fallback port will be used. After Parcel starts, the location where the dev server is listening will be printed to the terminal.
开发服务器支持多个选项,你可以通过 CLI 选项指定:
¥The dev server supports several options, which you can specify via CLI options:
-
-p
、--port
– 覆盖默认端口。PORT
环境变量也可用于设置端口。¥
-p
,--port
– Overrides the default port. ThePORT
environment variable can also be used to set the port. -
--host
- 默认情况下,开发服务器接受所有接口上的连接。你可以覆盖此设置以指定只接受来自某些主机的连接。¥
--host
– By default, the dev server accepts connections on all interfaces. You can override this to specify that only connections from certain hosts should be accepted. -
--open
- Parcel 启动后自动在默认浏览器中打开该入口。你还可以传递浏览器名称来打开不同的浏览器,例如--open safari
。¥
--open
– Automatically opens the entry in your default browser after Parcel starts. You can also pass a browser name to open a different browser, e.g.--open safari
.
热重载
#¥Hot reloading
当你更改代码时,Parcel 会自动重建更改的文件并在浏览器中更新你的应用。默认情况下,Parcel 会完全重新加载页面,但在某些情况下,它可能会执行热模块替换 (HMR)。HMR 通过在运行时更新浏览器中的模块而无需刷新整个页面来改善开发体验。这意味着当你更改代码中的小内容时,可以保留应用状态。
¥As you make changes to your code, Parcel automatically rebuilds the changed files and updates your app in the browser. By default, Parcel fully reloads the page, but in some cases it may perform Hot Module Replacement (HMR). HMR improves the development experience by updating modules in the browser at runtime without needing a whole page refresh. This means that application state can be retained as you change small things in your code.
CSS 更改通过 HMR 自动应用,无需重新加载页面。当使用内置 HMR 支持的框架时也是如此,例如 React(通过快速刷新)和 Vue。
¥CSS changes are automatically applied via HMR with no page reload necessary. This is also true when using a framework with HMR support built in, like React (via Fast Refresh), and Vue.
如果你不使用框架,则可以使用 module.hot
API 选择使用 HMR。这将阻止页面重新加载,而是就地应用更新。module.hot
仅在开发中可用,因此你需要在使用之前检查它是否存在。
¥If you’re not using a framework, you can opt into HMR using the module.hot
API. This will prevent the page from being reloaded, and instead apply the update in-place. module.hot
is only available in development, so you'll need to check that it exists before using it.
if (module.hot) {
module.hot.accept();
}
HMR 的工作原理是替换模块的代码,然后重新评估它及其所有父模块。如果你需要自定义此过程,可以使用 module.hot.accept
和 module.hot.dispose
方法钩子。这些使你可以保存和恢复新版本模块内的状态。
¥HMR works by replacing the code for a module, and then re-evaluating it and along with all of its parents. If you need to customize this process, you can hook into it using the module.hot.accept
and module.hot.dispose
methods. These let you save and restore state inside the new version of the module.
module.hot.dispose
接受一个回调,当该模块即将被替换时调用该回调。使用它来保存要在提供的 data
对象的新版本模块中恢复的任何状态,或者清理将在新版本中重新创建的计时器等内容。
¥module.hot.dispose
accepts a callback which is called when that module is about to be replaced. Use it to save any state to restore in the new version of the module in the provided data
object, or cleanup things like timers that will be re-created in the new version.
module.hot.accept
接受一个回调函数,该函数在该模块或其任何依赖更新时执行。你可以使用 module.hot.data
中存储的数据来恢复旧版本模块的状态。
¥module.hot.accept
accepts a callback function which is executed when that module or any of its dependencies are updated. You can use this to restore state from the old version of the module using the data stored in 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;
});
}
开发目标
#¥Development target
使用开发服务器时,一次只能构建一个目标。默认情况下,Parcel 使用支持现代浏览器的开发目标。这意味着旧版浏览器的现代 JavaScript 语法转译被禁用。
¥When using the dev server, only a single target can be built at once. By default, Parcel uses a development target that supports modern browsers. This means that transpilation of modern JavaScript syntax for older browsers is disabled.
如果你需要在较旧的浏览器中进行测试,你可以提供 --target
CLI 选项来选择要构建的目标。例如,要构建 package.json 中定义的 "legacy" 目标,请使用 --target legacy
。如果你没有定义任何显式目标,并且 package.json 中只有 browserslist
,则可以将隐式默认目标与 --target default
一起使用。这将导致你的源代码像在生产环境中一样被转译。
¥If you need to test in a older browser, you can provide the --target
CLI option to choose which of your targets to build. For example, to build the "legacy" target defined in your package.json, use --target legacy
. If you don't have any explicit targets defined, and only have a browserslist
in your package.json, you can use the implicit default target with --target default
. This will result in your source code being transpiled just as it would be in production.
有关详细信息,请参阅 目标 文档。
¥See the Targets documentation for more information.
惰性模式
#¥Lazy mode
在开发过程中,在开发服务器启动之前等待整个应用构建可能会令人沮丧。在处理具有多个页面的大型应用时尤其如此。如果你只开发一项功能,则不需要等待所有其他功能都构建完成,除非你导航到它们。
¥In development, it can be frustrating to wait for your entire app to build before the dev server starts up. This is especially true when working on large apps with many pages. If you’re only working on one feature, you shouldn’t need to wait for all of the others to build unless you navigate to them.
你可以使用 --lazy
CLI 标志告诉 Parcel 推迟构建文件,直到浏览器中请求它们,这可以显着减少开发构建时间。服务器启动很快,当你第一次导航到某个页面时,Parcel 仅构建该页面所需的文件。当你导航到另一个页面时,该页面将根据需要构建。如果你导航回之前构建的页面,它将立即加载。
¥You can use the --lazy
CLI flag to tell Parcel to defer building files until they are requested in the browser, which can significantly reduce development build times. The server starts quickly, and when you navigate to a page for the first time, Parcel builds only the files necessary for that page. When you navigate to another page, that page will be built on demand. If you navigate back to a page that was previously built, it loads instantly.
parcel 'pages/*.html' --lazy
这也适用于动态 import()
,而不仅仅是单独的入口。因此,如果你的页面具有动态加载功能,则在激活该功能之前不会构建该功能。当请求时,Parcel 也会预构建所有依赖,而不等待它们被请求。
¥This also works with dynamic import()
, not just separate entries. So if you have a page with a dynamically loaded feature, that feature will not be built until it is activated. When it is requested, Parcel eagerly builds all of the dependencies as well, without waiting for them to be requested.
缓存
#¥Caching
Parcel 将其构建的所有内容缓存到磁盘上。如果重新启动开发服务器,Parcel 将仅重建自上次运行以来已更改的文件。Parcel 自动跟踪构建中涉及的所有文件、配置、插件和开发依赖,并在发生更改时精细地使缓存失效。例如,如果更改配置文件,则依赖该配置的所有源文件都将被重建。
¥Parcel caches everything it builds to disk. If you restart the dev server, Parcel will only rebuild files that have changed since the last time it ran. Parcel automatically tracks all of the files, configuration, plugins, and dev dependencies that are involved in your build, and granularly invalidates the cache when something changes. For example, if you change a configuration file, all of the source files that rely on that configuration will be rebuilt.
默认情况下,缓存存储在项目内的 .parcel-cache
文件夹中。你应该将此文件夹添加到你的 .gitignore
(或同等文件夹),以便它不会在你的存储库中提交。你还可以使用 --cache-dir
CLI 选项覆盖缓存的位置。
¥By default, the cache is stored in the .parcel-cache
folder inside your project. You should add this folder to your .gitignore
(or equivalent) so that it is not committed in your repo. You can also override the location of the cache using the --cache-dir
CLI option.
还可以使用 --no-cache
标志禁用缓存。请注意,这只会禁用从缓存中读取 - 仍会创建 .parcel-cache
文件夹。
¥Caching can also be disabled using the --no-cache
flag. Note that this only disables reading from the cache – a .parcel-cache
folder will still be created.
HTTPS
#有时,你在开发过程中可能需要使用 HTTPS。例如,你可能需要使用特定主机名进行身份验证 cookie,或调试混合内容问题。Parcel 的开发服务器支持开箱即用的 HTTPS。你可以使用自动生成的证书,也可以提供你自己的证书。
¥Sometimes, you may need to use HTTPS during development. For example, you may need to use a certain hostname for authentication cookies, or debug mixed content issues. Parcel’s dev server supports HTTPS out of the box. You can either use an automatically generated certificate, or provide your own.
要使用自动生成的自签名证书,请使用 --https
CLI 标志。第一次加载页面时,你可能需要在浏览器中手动信任此证书。
¥To use an automatically generated self-signed certificate, use the --https
CLI flag. The first time you load the page, you may need to manually trust this certificate in your browser.
parcel src/index.html --https
要使用自定义证书,你需要使用 --cert
和 --key
CLI 选项分别指定证书文件和私钥。
¥To use a custom certificate, you’ll need to use the --cert
and --key
CLI options to specify the certificate file and private key respectively.
parcel src/index.html --cert certificate.cert --key private.key
API 代理
#¥API proxy
为了在开发 Web 应用时更好地模拟实际生产环境,你可以在 .proxyrc
、.proxyrc.json
、.proxyrc.js
或 .proxyrc.ts
文件中指定应代理到另一台服务器(例如你的真实 API 服务器或本地测试服务器)的路径。
¥To better emulate the actual production environment when developing web apps, you can specify paths that should be proxied to another server (e.g. your real API server or a local testing server) in a .proxyrc
, .proxyrc.json
, .proxyrc.js
or .proxyrc.ts
file.
.proxyrc
/.proxyrc.json
#在此 JSON 文件中,你指定一个对象,其中每个键都是与 URL 匹配的模式,并且值是 http-proxy-middleware
选项 对象:
¥In this JSON file, you specify an object where every key is a pattern against which the URL is matched and the value is a http-proxy-middleware
options object:
此示例将导致 http://localhost:1234/api/endpoint
被代理到 http://localhost:8000/endpoint
。
¥This example would cause http://localhost:1234/api/endpoint
to be proxied to http://localhost:8000/endpoint
.
.proxyrc.js
/.proxyrc.ts
#对于更复杂的配置,.proxyrc.js
或 .proxyrc.ts
文件允许你附加任何与 connect 兼容的中间件。首先,确保将 http-proxy-middleware
安装到你的项目中。此示例与上面的 .proxyrc
版本具有相同的行为。
¥For more complex configurations, a .proxyrc.js
or .proxyrc.ts
file allows you to attach any connect-compatible middleware. First, make sure you install http-proxy-middleware
into your project. This example has the same behaviour as the .proxyrc
version above.
如果你想将其编写为 ES 模块,则可以使用 .proxyrc.mjs
文件或使用 package.json
中的 "type": "module"
选项来实现。
¥If you would like to write this as an ES module instead, you can do so using a .proxyrc.mjs
file, or by using the "type": "module"
option in your package.json
.
文件监视器
#¥File watcher
为了支持最佳的缓存和开发体验,Parcel 使用了一个用 C++ 编写的非常快的监视程序,该监视程序与每个操作系统的底层文件监视功能集成。使用此监视程序 Parcel 监视项目根目录中的每个文件(包括所有 node_modules
)。根据这些文件中的事件和元数据,Parcel 确定哪些文件需要重建。
¥To support an optimal caching and development experience Parcel utilizes a very fast watcher written in C++ that integrates with low-level file watching functionality of each operating system. Using this watcher Parcel watches every file in your project root (including all node_modules
). Based on events and metadata from these files, Parcel determines which files need to be rebuilt.
文件监视的已知问题
#¥Known issues with file watching
安全写入
#¥Safe Write
某些文本编辑器和 IDE 具有称为 "安全写入" 的功能,该功能通过获取文件副本并在保存时重命名来防止数据丢失。但是,此功能可能会阻止自动检测文件更新。
¥Some text editors and IDE's have a feature called "safe write" that prevents data loss by taking a copy of the file and renaming it when saved. However, this feature can prevent automatic detection of file updates.
要禁用安全写入,请使用下面提供的选项:
¥To disable safe write, use the options provided below:
-
Sublime Text 3:将
atomic_save: "false"
添加到你的用户首选项中。¥Sublime Text 3: add
atomic_save: "false"
to your user preferences. -
智能:使用首选项中的搜索找到 "安全写入" 并将其禁用。
¥IntelliJ: use search in the preferences to find "safe write" and disable it.
-
Vim:将
:set backupcopy=yes
添加到你的设置中。¥Vim: add
:set backupcopy=yes
to your settings. -
网络风暴:在首选项 > 外观和行为 > 系统设置中取消选中
Use "safe write"
。¥WebStorm: uncheck
Use "safe write"
in Preferences > Appearance & Behavior > System Settings. -
可见:将
:set savemethod inplace
添加到你的设置中。¥vis: add
:set savemethod inplace
to your settings.
Linux:设备上没有剩余空间
#¥Linux: No space left on device
根据项目的大小以及操作系统的观察程序限制,当你在 Linux 上运行 Parcel 时可能会弹出此错误。要解决此问题,请将 fs.inotify
的 sysctl
配置更改为 max_user_watches
具有更高的值。
¥Depending on the size of your project, and your operating system's watcher limit, this error might pop up when you're running Parcel on Linux. To resolve this issue, change the sysctl
configuration for fs.inotify
to have a higher value for max_user_watches
.
你可以通过在 /etc/sysctl.conf
中添加或更改以下行来完成此操作:
¥You can do this by adding or changing the following lines in /etc/sysctl.conf
:
fs.inotify.max_queued_events = 16384
fs.inotify.max_user_instances = 128
fs.inotify.max_user_watches = 16384
如果此错误仍然存在,你可以尝试进一步增加该值。
¥If this error persists you can try increasing the values even more.
使用 Dropbox、Google Drive 或其他云存储解决方案
#¥Using Dropbox, Google Drive or other cloud storage solutions
最佳实践是不要将 Parcel 项目放置在使用 Dropbox 或 Google Drive 等同步到云的文件夹中。这些解决方案会创建大量文件系统事件,这些事件可能会扰乱我们的观察程序并导致不必要的重建。
¥It is best practice to not place a Parcel project in a folder that is synced to the cloud using something like Dropbox or Google Drive. These solutions create a lot of file system events that can mess with our watcher and cause unnecessary rebuilds.
自动安装
#¥Auto install
当你使用默认未包含的语言或插件时,Parcel 会自动为你将必要的依赖安装到你的项目中。例如,如果你包含 .sass
文件,Parcel 将安装 @parcel/transformer-sass
插件。发生这种情况时,你将在终端中看到一条消息,并且新的依赖将添加到 package.json 中的 devDependencies
中。
¥When you use a language or plugin that isn’t included by default, Parcel will automatically install the necessary dependencies into your project for you. For example, if you include a .sass
file, Parcel will install the @parcel/transformer-sass
plugin. When this happens, you'll see a message in the terminal, and the new dependency will be added to the devDependencies
in your package.json.
Parcel 会根据锁定文件自动检测你在项目中使用的包管理器。例如,如果找到 yarn.lock
,则将使用 Yarn 来安装软件包。如果未找到锁定文件,则会根据系统上安装的内容选择包管理器。目前支持以下包管理器,按优先级顺序列出:
¥Parcel automatically detects which package manager you use in your project based on the lock file. For example, if yarn.lock
is found, then Yarn will be used to install packages. If no lock file is found, then the package manager is chosen based on what is installed on your system. The following package managers are currently supported, listed in priority order:
默认情况下,自动安装仅在开发期间发生。在生产构建过程中,如果缺少依赖,构建将会失败。你还可以使用 --no-autoinstall
CLI 标志在开发过程中禁用自动安装。
¥Auto install only occurs during development by default. During production builds, if a dependency is missing, the build will fail. You can also disable auto install during development using the --no-autoinstall
CLI flag.