Rush Stack商店部落格活動
跳至主要內容

部署專案

假設您的單一儲存庫包含一個我們想要部署到網頁伺服器的 Node.js 服務。例如,假設 Node.js 服務是一個名為 app1 的本機 Rush 專案,並且儲存庫的組織方式如下

  • apps/app1:
    • 相依於 ext-lib7 (來自 NPM) 和 lib3 (本機專案)
    • 開發相依性於 ext-tool8 (來自 NPM) 和 tool6 (本機專案)
  • apps/app2:相依於 lib3lib4
  • libraries/lib3:相依於 lib5
  • libraries/lib4:沒有相依性
  • libraries/lib5:對 ext-lib7 的同層級相依性
  • tools/tool6:沒有相依性

一種解決方案可能是執行 rush installrush build,然後將整個單一儲存庫複製到伺服器。但是,這可能會包含許多多餘的檔案和 NPM 套件。相反地,我們只想複製 app1 及其一般相依性 (ext-lib7lib3lib5)。我們不想包含開發相依性,例如 ext-tool8

rush deploy 指令會計算此檔案集並將它們複製到目標資料夾,然後您可以將該資料夾上傳到您的伺服器。

設定「rush deploy」

rush deploy 指令會從組態檔案 common/config/rush/deploy.json 讀取其設定。此組態檔案不是由 rush init 建立的。相反地,您可以使用 rush init-deploy 建立檔案。

繼續我們的範例,我們可以使用此指令建立檔案

# Create common/config/rush/deploy.json and configure it to deploy "app1"
rush init-deploy --project app1

建立檔案 deploy.json 之後,請在您的編輯器中開啟它,並根據需要調整設定。然後將此檔案提交到 Git。

準備部署

若要將檔案複製到部署目標資料夾,您可以使用下列指令

# Install dependencies
rush install

# Build the monorepo
rush build

# Copy app1 and its dependencies to the default target folder: common/deploy/
rush deploy

這會透過將 app1 及其相依性複製到目標資料夾來準備部署。複製的檔案會以類似於單一儲存庫的資料夾結構組織

  • common/deploy/apps/app1/...
  • common/deploy/common/temp/node_modules/ext-lib7/...
  • common/deploy/libraries/lib3/...
  • common/deploy/libraries/lib4/...

您可以從部署目標資料夾內執行 app1,以測試部署是否正確運作

# Change to the app1 location under the target folder
cd common/deploy/apps/app1

# Invoke the package.json script that starts the web service
rushx start

如果專案無法執行 (但在其原始位置 apps/app1 中正常運作),則您可能需要調整 deploy.json 中的設定。一旦您確認專案正常運作,下一步就是將 common/deploy 子樹上傳到您的伺服器機器。

common/deploy 子樹將會有 rush install 建立的符號連結。例如,如果您使用 PNPM 套件管理員,則 common/deploy/apps/app1/node_modules/ext-lib7 可能會是指向 common/deploy/common/temp/node_modules/.pnpm/... 路徑下資料夾的符號連結。正確複製這些連結可能會對 tarftp 等上傳工具有所困難。

deploy.json 組態檔案提供了一個設定 linkCreation,可讓您選擇如何處理連結

  • "default":在複製檔案時建立連結;這是預設行為。如果您的檔案複製工具可以正確處理連結,請使用此設定。
  • "script":名為 create-links.js 的 Node.js 指令碼會寫入目標資料夾。使用此設定可在檔案上傳後,在伺服器機器上建立連結。
  • "none":不執行任何動作;其他工具可能會稍後根據 deploy-metadata.json 檔案建立連結。

deploy-metadata.json 檔案會寫入部署目標資料夾,並包含需要建立之連結的完整清單。它看起來可能像這樣

{
"scenarioName": "deploy.json",
"mainProjectName": "app1",
"links": [
{
"kind": "folderLink",
"linkPath": "common/deploy/apps/app1/node_modules/ext-lib7",
"targetPath": "common/deploy/common/temp/node_modules/.pnpm/registry.npmjs.org/ext-lib7/1.0.0/node_modules/ext-lib7"
},
. . .
]
}

如果您指定 "linkCreation": "script",則 rush deploy 會建立 common/deploy 資料夾,而不包含任何連結。在您將此資料夾上傳到您的伺服器機器之後,您可以接著叫用此指令碼來建立連結

# Invoke this command on the server machine, after the files have been uploaded
node create-links.js create

注意:當使用 "linkCreation": "script" 時,目前實作尚未產生 node_modules/.bin 命令列二進位檔。如果您有興趣貢獻修復程式,請參閱 此 PR 評論 以取得建議的解決方案。

包含其他專案

繼續我們的範例,假設我們想要將 app1app2 一起包含為單一部署。由於 app2 不是 app1 的相依性,因此它不會自動包含在內。我們可以將 app1 視為「主要專案」(列在 deploymentProjectNames 中),然後將 app2 宣告為「其他專案」。組態檔案會像這樣

common/config/rush/deploy.json

{
. . .
// The main project
"deploymentProjectNames": ["app1"],
. . .
"projectSettings": [
{
"projectName": "app1",

// When deploying "app1", include "app2". We need to add this explicitly because
// "app2" is not a dependency of "app1".
"additionalProjectsToInclude": [ "app2" ]
}
]
}

使用相同組態檔案進行多個部署

繼續我們的範例,假設我們反而想要將 app1app2 分別部署到兩個不同的網頁伺服器。如果設定相同,我們可以簡單地將它們都新增到 deploymentProjectNames 陣列,如下所示

common/config/rush/deploy.json

  . . .
"deploymentProjectNames": [ "app1", "app2" ],
. . .

在執行部署時,--project 參數會選取要部署的專案。例如

# Copy app1 and its dependencies to /mnt/deploy/app1
rush deploy --project app1 --target-folder /mnt/deploy/app1

# Copy app2 and its dependencies to /mnt/deploy/app2
rush deploy --project app2 --target-folder /mnt/deploy/app2

--target-folder 參數會將檔案複製到自訂位置,而不是預設的 common/deploy/ 資料夾。

使用不同組態檔案進行多個部署

繼續我們的範例,假設 app2 會單獨部署,而且它需要的設定與 app1 不同。例如,假設我們想要將 app1"linkCreation": "default",以及 app2"linkCreation": "script"。我們將建立兩個組態檔案

  • common/config/rush/deploy.json - 預設情境檔案,我們將用於 app1
  • common/config/rush/deploy-app2-example.json -- app2-example 情境,我們將用於 app2

這兩個檔案都可以使用 rush init-deploy 建立

# Create common/config/rush/deploy.json
rush init-deploy --project app1

# Create common/config/rush/deploy-app2-example.json
rush init-deploy --project app2 --scenario app2-example

在編輯 deploy-app2-example.json 以指定 "linkCreation": "script" 之後,我們現在可以使用 rush deploy--scenario 參數

# Copy app1 and its dependencies to /mnt/deploy/app1
# Uses scenario file: common/config/rush/deploy.json
rush deploy --target-folder /mnt/deploy/app1

# Copy app2 and its dependencies to /mnt/deploy/app2
# Uses scenario file: common/config/rush/deploy-app2-example.json
rush deploy --target-folder /mnt/deploy/app2 --scenario app2-example

請注意,rush deploy 不需要 --project 參數,因為每個組態檔案在其 "deploymentProjectNames" 陣列中只有一個專案。

另請參閱