コンテンツにスキップ

@remix-run/dev CLI

このコンテンツはまだ日本語訳がありません。

Remix CLI

Remix CLI 来自 @remix-run/dev 包。它还包括编译器。确保它位于您的 package.json devDependencies 中,这样它就不会部署到您的服务器。

要获取可用命令和标志的完整列表,请运行:

Terminal window
npx @remix-run/dev -h

remix vite:build

使用 Remix Vite 构建您的应用以供生产。此命令会将 process.env.NODE_ENV 设置为 production,并压缩部署的输出。

Terminal window
remix vite:build
FlagDescriptionTypeDefault
--assetsInlineLimitStatic asset base64 inline threshold in bytesnumber4096
--clearScreenAllow/disable clear screen when loggingboolean
--config, -cUse specified config filestring
--emptyOutDirForce empty outDir when it’s outside of rootboolean
--logLevel, -lUse specified log level"info" | "warn" | "error" | "silent" | string
--minifyEnable/disable minification, or specify minifier to useboolean | "terser" | "esbuild""esbuild"
--mode, -mSet env modestring
--profileStart built-in Node.js inspector
--sourcemapClientOutput source maps for client buildboolean | "inline" | "hidden"false
--sourcemapServerOutput source maps for server buildboolean | "inline" | "hidden"false

remix vite:dev

使用 Remix Vite 以开发模式运行您的应用。

Terminal window
remix vite:dev
FlagDescriptionTypeDefault
--clearScreenAllow/disable clear screen when loggingboolean
--config, -cUse specified config filestring
--corsEnable CORSboolean
--forceForce the optimizer to ignore the cache and re-bundleboolean
--hostSpecify hostnamestring
--logLevel, -lUse specified log level"info" | "warn" | "error" | "silent" | string
--mode, -mSet env modestring
--openOpen browser on startupboolean | string
--portSpecify portnumber
--profileStart built-in Node.js inspector
--strictPortExit if specified port is already in useboolean

经典 Remix 编译器命令

此文档仅在使用 Classic Remix 编译器 时相关。

remix build

使用 Classic Remix Compiler 构建您的应用以供生产。此命令会将 process.env.NODE_ENV 设置为 production,并压缩部署的输出。

Terminal window
remix build

选项

Optionflagconfigdefault
Generate sourcemaps for production build--sourcemapN/Afalse

remix dev

在监视模式下运行 Classic Remix Compiler 并启动您的应用服务器。

Remix 编译器将:

  1. NODE_ENV 设置为 development
  2. 观察应用代码是否有变化并触发重建
  3. 重建成功后,重新启动应用服务器
  4. 通过 Live Reload 和 HMR + 热数据重新验证将代码更新发送到浏览器

🎥 有关 Remix 中的 HMR 和 HDR 的介绍和深入了解,请查看我们的视频:

什么是热数据重新验证

与 HMR 一样,HDR 是一种无需刷新页面即可热更新应用的方式。 这样,当您的编辑应用于应用时,您可以保持应用状态。 HMR 处理客户端代码更新,例如当您更改应用中的组件、标记或样式时。 同样,HDR 处理服务器端代码更新。

这意味着,每当您在当前页面上更改 loader(或您的 loader 所依赖的任何代码)时,Remix 都会从更改的加载器中重新获取数据。 这样,您的应用始终能够更新最新的代码更改,无论是客户端还是服务器端。

要了解有关 HMR 和 HDR 如何协同工作的更多信息,请查看 Pedro 在 Remix Conf 2023 上的演讲

使用自定义应用服务器

如果您使用模板开始使用,希望它已经与 remix dev 开箱即用地集成。 如果没有,您可以按照以下步骤将您的项目与 remix dev 集成:

  1. 替换 package.json 中的开发脚本并使用 -c 指定您的应用服务器命令:

    package.json
    {
    "scripts": {
    "dev": "remix dev -c \"node ./server.js\""
    }
    }
  2. 确保在应用服务器启动并运行时调用 broadcastDevReady

    import path from "node:path";
    import { broadcastDevReady } from "@remix-run/node";
    import express from "express";
    const BUILD_DIR = path.resolve(__dirname, "build");
    const build = require(BUILD_DIR);
    const app = express();
    // ... code for setting up your express app goes here ...
    app.all("*", createRequestHandler({ build }));
    const port = 3000;
    app.listen(port, () => {
    console.log(`👉 http://localhost:${port}`);
    if (process.env.NODE_ENV === "development") {
    broadcastDevReady(build);
    }
    });
    对于 CloudFlare,使用 `logDevReady` 而不是 `broadcastDevReady`。

    原因是什么?broadcastDevReady 使用 fetch 向 Remix 编译器发送就绪消息, 但 CloudFlare 不支持请求处理之外的异步 I/O(如 fetch)。

选项

选项优先级顺序为:1. 标志,2. 配置,3. 默认值。

Optionflagconfigdefaultdescription
Command-c / --commandcommandremix-serve <server build path>Command used to run your app server
Manual--manualmanualfalseSee guide for manual mode
Port--portportDynamically chosen open portInternal port used by the Remix compiler for hot updates
TLS key--tls-keytlsKeyN/ATLS key for configuring local HTTPS
TLS certificate--tls-certtlsCertN/ATLS certificate for configuring local HTTPS

例如:

remix.config.js
/** @type {import('@remix-run/dev').AppConfig} */
module.exports = {
dev: {
// ...any other options you want to set go here...
manual: true,
tlsKey: "./key.pem",
tlsCert: "./cert.pem",
},
};

设置自定义端口

remix dev --port 选项设置用于热更新的内部端口。 它不会影响您的应用运行的端口。

要设置应用服务器端口,请按照生产中的常规方式进行设置。 例如,您可能将其硬编码在 server.js 文件中。

如果您使用 remix-serve 作为应用服务器,则可以使用其 --port 标志来设置应用服务器端口:

Terminal window
remix dev -c "remix-serve --port 8000 ./build/index.js"

相比之下,remix dev --port 选项是需要对网络端口进行细粒度控制的用户的救生舱。 大多数用户不需要使用 remix dev --port

手动模式

默认情况下,每当重建发生时,remix dev 都会重新启动您的应用服务器。 如果您希望您的应用服务器在重建期间无需重新启动即可保持运行,请查看我们的手动模式指南

你可以通过比较 remix dev 报告的时间来看看应用服务器重启是否是你项目的瓶颈:

  • 重建(Xms) 👉 Remix 编译器花费 X 毫秒来重建您的应用
  • 应用服务器就绪(Yms) 👉 Remix 重新启动了您的应用服务器,并花费 Y 毫秒来启动新的代码更改

从其他软件包中获取更改

如果您使用的是 monorepo,您可能希望 Remix 不仅在您的应用程序代码发生更改时执行热更新,而且在您更改任何应用程序依赖项中的代码时执行热更新。

例如,您可能有一个在 Remix 应用(packages/app)中使用的 UI 库包(packages/ui)。 要获取 packages/ui 中的更改,您可以配置 watchPaths 以包含您的包。

如何设置 MSW

要在开发中使用 Mock Service Worker,您需要:

  1. 将 MSW 作为应用服务器的一部分运行
  2. 配置 MSW 以不向 Remix 编译器模拟内部开发就绪消息

确保在 -c 标志内为 应用服务器 设置模拟,以便 REMIX_DEV_ORIGIN 环境变量可用于模拟。 例如,在运行 remix-serve 时,您可以使用 NODE_OPTIONS 设置 Node 的 --require 标志:

package.json
{
"scripts": {
"dev": "remix dev -c \"npm run dev:app\"",
"dev:app": "cross-env NODE_OPTIONS=\"--require ./mocks\" remix-serve ./build"
}
}

如果您使用 ESM 作为默认模块系统,则需要设置 --import 标志而不是 --require

package.json
{
"scripts": {
"dev": "remix dev -c \"npm run dev:app\"",
"dev:app": "cross-env NODE_OPTIONS=\"--import ./mocks/index.js\" remix-serve ./build/index.js"
}
}

接下来,您可以使用 REMIX_DEV_ORIGIN 让 MSW 在 /ping 上转发内部 dev ready 消息:

import { http, passthrough } from "msw";
const REMIX_DEV_PING = new URL(
process.env.REMIX_DEV_ORIGIN
);
REMIX_DEV_PING.pathname = "/ping";
export const server = setupServer(
http.post(REMIX_DEV_PING.href, () => passthrough())
// ... other request handlers go here ...
);

如何与反向代理集成

假设你的应用服务器和 Remix 编译器都在同一台机器上运行:

  • 应用服务器 👉 http://localhost:1234
  • Remix 编译器 👉 http://localhost:5678

然后,在应用服务器前面设置反向代理:

  • 反向代理 👉 https://myhost

但是支持热更新的内部 HTTP 和 WebSocket 连接仍将尝试到达 Remix 编译器的非代理来源:

  • 热更新 👉 http://localhost:5678 / ws://localhost:5678

要使内部连接指向反向代理,可以使用 REMIX_DEV_ORIGIN 环境变量:

Terminal window
REMIX_DEV_ORIGIN=https://myhost remix dev

现在,热更新将被正确发送到代理:

  • 热更新 👉 https://myhost / wss://myhost

性能调优和调试

路径导入

目前,当 Remix 重建您的应用时,编译器必须处理您的应用代码及其任何依赖项。 编译器会从应用中对未使用的代码进行树形优化,这样您就不会将任何未使用的代码发送到浏览器,并尽可能精简您的服务器。 但编译器仍然需要_爬取_所有代码,以了解哪些代码要保留,哪些代码要进行树形优化。

简而言之,这意味着您执行导入和导出的方式会对重建应用所需的时间产生很大影响。 例如,如果您使用 Material UI 或 AntD 之类的库,则可以使用 path imports 来加快构建速度:

import { Button, TextField } from '@mui/material';
import Button from '@mui/material/Button';
import TextField from '@mui/material/TextField';

将来,Remix 可以在开发过程中预先捆绑依赖项,以完全避免此问题。 但现在,您可以使用路径导入来帮助编译器。

调试包

根据您的应用和依赖项,您可能需要处理比应用所需更多的代码。 查看我们的 bundle 分析指南 了解更多详细信息。

故障排除

HMR

如果您期待热更新但却得到整个页面重新加载, 请查看我们的关于热模块替换的讨论,以了解有关 React Fast Refresh 的局限性以及常见问题的解决方法的更多信息。

HDR:每次代码更改都会触发 HDR

Hot Data Revalidation 通过尝试捆绑每个加载器,然后为每个加载器采集内容指纹来检测加载器更改。 它依靠摇树来确定您的更改是否影响每个加载器。

为了确保 tree shake 可以可靠地检测到 loader 的变更,请确保你声明应用的软件包没有副作用:

package.json
{
"sideEffects": false
}
HDR:删除加载器数据时出现无害的控制台错误

当您删除加载器或移除该加载器返回的部分数据时,您的应用应该能够正确进行热更新。 但您可能会注意到浏览器中记录了控制台错误。

应用热更新时,React strict-mode 和 React Suspense 可能会导致多次渲染。 其中大多数渲染正确,包括您可见的最终渲染。 但中间渲染有时会将新的加载器数据与旧的 React 组件一起使用,这就是这些错误的来源。

我们正在继续调查潜在的竞争条件,看看能否解决这个问题。 与此同时,如果这些控制台错误让您感到困扰,您可以在发生错误时刷新页面。

HDR:性能

当 Remix 编译器构建(并重建)您的应用时,您可能会注意到速度略有减慢,因为编译器需要抓取每个加载器的依赖项。 这样,Remix 就可以在重建时检测到加载器的变化。

虽然初始构建速度减慢本质上是 HDR 的成本,但我们计划优化重建,以便 HDR 重建的速度不会出现明显的减慢。