React Router v7 已發布。 查看文件
@remix-run/dev CLI
本頁內容

Remix CLI

Remix CLI 來自於 @remix-run/dev 套件。它也包含編譯器。請確保它在您的 package.jsondevDependencies 中,這樣它就不會被部署到您的伺服器。

要取得可用指令和標記的完整列表,請執行

npx @remix-run/dev -h

remix vite:build

使用 Remix Vite 為您的應用程式建置生產版本。此指令會將 process.env.NODE_ENV 設定為 production,並縮減輸出以進行部署。

remix vite:build
標記 描述 類型 預設值
--assetsInlineLimit 靜態資源 base64 行內閾值(以位元組為單位) 數字 4096
--clearScreen 允許/停用記錄時清除螢幕 布林值
--config, -c 使用指定的設定檔 字串
--emptyOutDir 強制清空 root 外部的 outDir 布林值
--logLevel, -l 使用指定的記錄層級 "info" | "warn" | "error" | "silent" | 字串
--minify 啟用/停用最小化,或指定要使用的最小化器 布林值 | "terser" | "esbuild" "esbuild"
--mode, -m 設定環境模式 字串
--profile 啟動內建的 Node.js 偵錯工具
--sourcemapClient 輸出用戶端建置的原始碼對應 布林值 | "inline" | "hidden" false
--sourcemapServer 輸出伺服器建置的原始碼對應 布林值 | "inline" | "hidden" false

remix vite:dev

使用 Remix Vite 在開發模式下執行您的應用程式。

remix vite:dev
標記 描述 類型 預設值
--clearScreen 允許/停用記錄時清除螢幕 布林值
--config, -c 使用指定的設定檔 字串
--cors 啟用 CORS 布林值
--force 強制最佳化工具忽略快取並重新打包 布林值
--host 指定主機名稱 字串
--logLevel, -l 使用指定的記錄層級 "info" | "warn" | "error" | "silent" | 字串
--mode, -m 設定環境模式 字串
--open 在啟動時開啟瀏覽器 布林值 | 字串
--port 指定連接埠 數字
--profile 啟動內建的 Node.js 偵錯工具
--strictPort 如果指定的連接埠已被使用,則退出 布林值

傳統 Remix 編譯器指令

此文件僅在您使用傳統 Remix 編譯器時相關。

remix build

使用 傳統 Remix 編譯器 為您的應用程式建置生產版本。此指令會將 process.env.NODE_ENV 設定為 production,並縮減輸出以進行部署。

remix build

選項

選項 標記 設定 預設值
為生產建置產生原始碼對應 --sourcemap 不適用 false

remix dev

在監看模式下執行 傳統 Remix 編譯器,並啟動您的應用程式伺服器。

Remix 編譯器將會

  1. NODE_ENV 設定為 development
  2. 監看您的應用程式程式碼變更並觸發重新建置
  3. 在重新建置成功時重新啟動您的應用程式伺服器
  4. 透過 Live Reload 和 HMR + 熱資料重新驗證將程式碼更新傳送到瀏覽器

🎥 如需了解 Remix 中 HMR 和 HDR 的簡介和深入探討,請查看我們的影片

什麼是「熱資料重新驗證」?

與 HMR 類似,HDR 是一種熱更新應用程式的方式,而無需重新整理頁面。這樣一來,您可以在應用程式中應用編輯時保持應用程式狀態。HMR 處理用戶端程式碼更新,例如當您變更應用程式中的元件、標記或樣式時。同樣地,HDR 處理伺服器端程式碼更新。

這表示當您變更目前頁面上的 loader(或您的 loader 所依賴的任何程式碼)時,Remix 將會從您變更的 loader 重新提取資料。這樣一來,您的應用程式始終會使用最新的程式碼變更進行更新,無論是用戶端還是伺服器端。

若要深入了解 HMR 和 HDR 如何協同運作,請查看 Pedro 在 Remix Conf 2023 的演講

使用自訂應用程式伺服器

如果您使用範本開始,希望它已經與 remix dev 開箱即用整合。如果沒有,您可以按照這些步驟將您的專案與 remix dev 整合

  1. 取代 package.json 中的開發指令碼,並使用 -c 來指定您的應用程式伺服器指令

    {
      "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(`👉 https://127.0.0.1:${port}`);
    
      if (process.env.NODE_ENV === "development") {
        broadcastDevReady(build);
      }
    });
    

    對於 CloudFlare,請使用 logDevReady 而不是 broadcastDevReady

    為什麼?broadcastDevReady 使用 fetch 將就緒訊息傳送到 Remix 編譯器,但 CloudFlare 不支援在請求處理之外的 fetch 等非同步 I/O。

選項

選項優先順序為:1. 標記、2. 設定、3. 預設值。

選項 標記 設定 預設值 描述
指令 -c / --command 指令 remix-serve <伺服器建置路徑> 用於執行應用程式伺服器的指令
手動 --manual 手動 false 請參閱手動模式指南
連接埠 --port 連接埠 動態選擇的開啟連接埠 Remix 編譯器用於熱更新的內部連接埠
TLS 金鑰 --tls-key tlsKey 不適用 用於設定本機 HTTPS 的 TLS 金鑰
TLS 憑證 --tls-cert tlsCert 不適用 用於設定本機 HTTPS 的 TLS 憑證

例如

/** @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 標記來設定應用程式伺服器連接埠

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

相較之下,remix dev --port 選項是為需要精細控制網路連接埠的使用者提供的應急方案。大多數使用者應該不需要使用 remix dev --port

手動模式

預設情況下,remix dev 會在每次重建發生時重新啟動您的應用程式伺服器。如果您希望在重建過程中保持應用程式伺服器運行而不重新啟動,請查看我們的手動模式指南

您可以比較 remix dev 報告的時間,以查看應用程式伺服器重新啟動是否為您的專案帶來瓶頸。

  • rebuilt (Xms) 👉 Remix 編譯器花費 X 毫秒來重建您的應用程式
  • app server ready (Yms) 👉 Remix 重新啟動您的應用程式伺服器,並花費 Y 毫秒來啟動新的程式碼變更

從其他套件中獲取變更

如果您正在使用單體儲存庫 (monorepo),您可能希望 Remix 不僅在您的應用程式程式碼變更時執行熱更新,而且在您變更任何應用程式的依賴項中的程式碼時也執行熱更新。

例如,您可能有一個 UI 程式庫套件 (packages/ui),該套件在您的 Remix 應用程式 (packages/app) 中使用。若要獲取 packages/ui 中的變更,您可以設定 watchPaths 以包含您的套件。

如何設定 MSW

若要在開發中使用 Mock Service Worker,您需要

  1. 將 MSW 作為您應用程式伺服器的一部分執行
  2. 設定 MSW 以不模擬傳送給 Remix 編譯器的內部「開發就緒」訊息

請確保您正在 -c 標記內為您的應用程式伺服器設定模擬,以便 REMIX_DEV_ORIGIN 環境變數可用於您的模擬。例如,您可以在執行 remix-serve 時使用 NODE_OPTIONS 設定 Node 的 --require 標記

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

如果您使用 ESM 作為預設模組系統,則需要設定 --import 標記而不是 --require

{
  "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 上轉發內部「開發就緒」訊息

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 編譯器都在同一部機器上執行

  • 應用程式伺服器 👉 https://127.0.0.1:1234
  • Remix 編譯器 👉 https://127.0.0.1:5678

然後,您在應用程式伺服器前面設定反向代理

  • 反向代理 👉 https://myhost

但為了支援熱更新的內部 HTTP 和 WebSocket 連線仍然會嘗試連線到 Remix 編譯器未經代理的來源

  • 熱更新 👉 https://127.0.0.1:5678 / ws://127.0.0.1:5678

若要使內部連線指向反向代理,您可以使用 REMIX_DEV_ORIGIN 環境變數

REMIX_DEV_ORIGIN=https://myhost remix dev

現在,熱更新將正確地傳送到代理

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

效能調整與偵錯

路徑導入

目前,當 Remix 重建您的應用程式時,編譯器必須處理您的應用程式程式碼及其任何依賴項。編譯器會從應用程式中剔除未使用的程式碼,以便您不會將任何未使用的程式碼傳送到瀏覽器,並使您的伺服器盡可能精簡。但是,編譯器仍然需要爬取所有程式碼,以了解要保留哪些程式碼以及要剔除哪些程式碼。

簡而言之,這表示您執行導入和導出的方式可能會對重建應用程式所需的時間產生很大影響。例如,如果您正在使用 Material UI 或 AntD 之類的程式庫,則可以透過使用路徑導入來加快建置速度

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

未來,Remix 可以在開發中預先綑綁依賴項,以完全避免此問題。但今天,您可以透過使用路徑導入來協助編譯器。

偵錯綑綁包

根據您的應用程式和依賴項,您可能會處理比應用程式需要的程式碼多得多的程式碼。請查看我們的綑綁包分析指南以了解更多詳細資訊。

疑難排解

HMR

如果您預期會進行熱更新,但卻得到完整頁面重新載入,請查看我們關於熱模組替換的討論,以了解有關 React Fast Refresh 的限制以及常見問題的解決方案的更多資訊。

HDR:每個程式碼變更都會觸發 HDR

熱資料重新驗證透過嘗試綑綁每個載入器,然後為每個載入器建立內容指紋來偵測載入器變更。它依靠剔除來判斷您的變更是否會影響每個載入器。

若要確保剔除可以可靠地偵測對載入器的變更,請確保您宣告您應用程式的套件沒有副作用

{
  "sideEffects": false
}
HDR:移除載入器資料時的無害主控台錯誤

當您刪除載入器或移除該載入器傳回的部分資料時,您的應用程式應該會正確地進行熱更新。但是您可能會注意到瀏覽器中記錄了主控台錯誤。

當套用熱更新時,React 嚴格模式和 React Suspense 可能會導致多次渲染。其中大多數渲染都正確,包括您可以看到的最終渲染。但是,中間渲染有時可能會使用帶有舊 React 元件的新載入器資料,這就是這些錯誤的來源。

我們正在繼續調查潛在的競爭條件,看看是否可以解決該問題。同時,如果這些主控台錯誤困擾您,您可以在它們發生時重新整理頁面。

HDR:效能

當 Remix 編譯器建置 (和重建) 您的應用程式時,您可能會注意到編譯器在需要爬取每個載入器的依賴項時,速度會稍微變慢。這樣,Remix 可以在重建時偵測載入器變更。

雖然初始建置速度變慢是 HDR 的固有成本,但我們計劃最佳化重建,以便 HDR 重建不會造成可察覺的速度變慢。

文件和範例依據授權 MIT