Power Pages 支援整合使用次世代 AI 輔助工具(如 GitHub Copilot)所創建的單頁應用程式(SPA)程式碼。 這項功能讓開發者能透過自然語言作為程式介面,將現代化的元件式前端體驗帶入 Power Pages。
透過指導、測試和改進 AI 產生的程式碼,製作者可以將注意力從重複的實施任務轉移到更高層級的協調流程。 這使得開發更加直觀、更具創造性,同時保持企業級的品質和標準。
本文將教你如何:
- 使用 Power Platform CLI (PAC CLI) 建立並設定 Power Pages 的 SPA 專案。
- 上傳和下載程式碼素材到你的 Power Pages 網站。
- 建立安全且可維護的專案結構。
- 了解基於 SPA 與傳統 Power Pages 實作的主要差異。
Note
- SPA 網站是一種完全在使用者瀏覽器(用戶端渲染)中執行的 Power Pages 網站。 與傳統 Power Pages 網站不同,SPA 網站僅透過原始碼及命令列介面(CLI)工具來管理。
- Power Pages 的單頁應用程式(SPA)網站不支援 Power Platform Git 整合。
先決條件
開始之前,請確定您擁有:
- 一個Power Pages環境,擁有admin權限。
- 已安裝並驗證 Power Platform CLI (PAC CLI) 1.44.x 版或更新版本。
- 一個版本為 9.7.4.x 或更新版本的 Power Pages 網站。
- 允許在 Dataverse 環境中上傳 JavaScript 檔案。
- 一個本地的 Git 倉庫,裡面有你自訂的前端專案,例如 React、Angular 或 Vue。
允許上傳 JavaScript 檔案
預設情況下,部分 Dataverse 環境會阻擋 JavaScript (.js) 檔案的上傳。 如果你遇到 錯誤訊息「匯入失敗:附件要麼不是有效型別,要麼太大。無法上傳或下載。」,請更新你的環境設定以允許此檔案類型。
若要調整環境 Power Platform 系統管理中心中的設定,請依照下列步驟操作:
- 登入 Power Platform 系統管理中心。
- 在導覽窗格中,選擇管理。
- 在管理窗格中,選擇環境。
- 選取環境。
- 在命令欄中,選擇 設置。
- 展開產品,然後選擇隱私權 + 安全性。
- 在 「被阻擋附件 」區塊中,從檔案副檔名列表中移除
js。 - 選取 [儲存]。
建立並部署 SPA 網站
Power Pages SPA 站點由 PAC CLI 指令upload-code-site 和 download-code-site 管理。 上傳網站後,該網站會出現在Power PagesInactive sites清單中。 啟動該網站以使其可供使用者使用。
上傳 SPA 網站
請使用 pac pages upload-code-site 指令,將本地原始碼和編譯資產上傳到 Power Pages 環境。
Syntax
pac pages upload-code-site `
--rootPath <local-source-folder> `
[--compiledPath <build-output-folder>] `
[--siteName <site-display-name>]
Parameters
| 參數 | 別名 | Required | Description |
|---|---|---|---|
--rootPath |
-rp |
Yes | 包含您網站來源檔案的本機資料夾 |
--compiledPath |
-cp |
No | 已編譯資產的路徑,例如 build |
--siteName |
-sn |
No | Power Pages 網站的顯示名稱 |
Example
pac pages upload-code-site `
--rootPath "../your-project" `
--compiledPath "./build" `
--siteName "Contoso Code Site"
如果您沒有現有專案,請嘗試 使用 React、Angular 和 Vue 的 SPA 網站實作範例。
使用powerpages.config.json定義上傳參數
透過在您的網站中包含 upload-code-site 檔案來自訂 powerpages.config.json 命令的行為。 將此設定檔放在網站根資料夾中。 當您使用組態型的網站上傳時,只需使用 upload-code-site 參數執行 rootPath 命令。 此命令會自動從 powerpages.config.json 檔案讀取其他值,例如編譯資產路徑和網站顯示名稱。 如果同時提供命令列引數和設定值,則命令列引數優先。
範例 powerpages.config.json:
{
"siteName": "Contoso Bank",
"defaultLandingPage": "index.html",
"compiledPath": "C:\\PowerPages\\your-project\\dist"
}
下載 SPA 網站
使用 pac pages download-code-site 命令將現有網站的程式碼下載到本機目錄以進行編輯或備份。
Syntax
pac pages download-code-site `
[--environment <env-url-or-guid>] `
--path <local-target-folder> `
--webSiteId <site-guid> `
[--overwrite]
Parameters
| 參數 | 別名 | Required | Description |
|---|---|---|---|
--environment |
-env |
No | Dataverse 環境 (GUID 或完整 URL)。 預設為您的活動授權設定檔 |
--path |
-p |
Yes | 下載網站程式碼的本機目錄 |
--webSiteId |
-id |
Yes | Power Pages SPA 網點的網站記錄 GUID |
--overwrite |
-o |
No | 如果目標目錄中存在現有檔案,則覆蓋它們 |
Example
pac pages download-code-site `
--environment "https://contoso.crm.dynamics.com" `
--path "./downloaded-site" `
--webSiteId "11112222-bbbb-3333-cccc-4444dddd5555" `
--overwrite
啟動並測試您的網站
- 請前往Power Pages。
- 選取非作用中網站,找到您的網站,然後選取重新啟動。
- 當網站處於活動狀態時,請前往網站的 URL 來檢查部署情況。
Tip
任何後續的 upload-code-site 命令都會自動更新活動網站。
專案結構和設定
一致的專案版面配置有助於確保正確的上傳行為。
/your-project
│
├─ src/ ← Your source code, like React components
├─ build/ ← Compiled assets, output of the `npm run build` command
├─ powerpages.config.json ← Optional CLI configuration file
└─ README.md
使用可選的 powerpages.config.json 檔案來自訂 upload-code-site 命令的工作方式。
身份驗證與授權
Power Pages SPA 站點使用與傳統 Power Pages 站相同的 安全模型。
設定身份提供者
- 請前往Power Pages。
- 找到您的網站,然後選取編輯。
- 選取 安全性>識別提供者。
- 新增或設定 身份提供者,就像 Microsoft Entra ID。
- 每個新網站自動擁有預設的 Microsoft Entra ID 提供者。
在程式碼中存取使用者上下文
取得用戶端上的驗證中繼資料:
授權單位 URL:
Microsoft Entra ID 的權限或登入網址為:
https://login.windows.net/<tenantId>移至 Power Pages>
<your site>>安全性>識別提供者>組態設定,以尋找其他已設定識別提供者的授權單位 URL。使用者詳細資料:
window["Microsoft"].Dynamic365.Portal.User
React 流程範例
import { IconButton, Tooltip } from '@mui/material';
import {
Login,
Logout
} from '@mui/icons-material';
import React from 'react';
export const AuthButton = () => {
const username = (window as any)["Microsoft"]?.Dynamic365?.Portal?.User?.userName ?? "";
const firstName = (window as any)["Microsoft"]?.Dynamic365?.Portal?.User?.firstName ?? "";
const lastName = (window as any)["Microsoft"]?.Dynamic365?.Portal?.User?.lastName ?? "";
const tenantId = (window as any)["Microsoft"]?.Dynamic365?.Portal?.tenant ?? "";
const isAuthenticated = username !== "";
const [token, setToken] = React.useState<string>("");
React.useEffect(() => {
const fetchAntiForgeryToken = async (): Promise<string> => {
try {
const tokenEndpoint = "/_layout/tokenhtml";
const response = await fetch(tokenEndpoint, {});
if (response.status !== 200) {
throw new Error(`Failed to fetch token: ${response.status}`);
}
const tokenResponse = await response.text();
const valueString = 'value="';
const terminalString = '" />';
const valueIndex = tokenResponse.indexOf(valueString);
if (valueIndex === -1) {
throw new Error('Token not found in response');
}
const requestVerificationToken = tokenResponse.substring(
valueIndex + valueString.length,
tokenResponse.indexOf(terminalString, valueIndex)
);
return requestVerificationToken || '';
} catch (error) {
console.warn('[Impersonation] Failed to fetch anti-forgery token:', error);
return '';
}
};
const getToken = async () => {
try {
const token = await fetchAntiForgeryToken();
setToken(token);
} catch (error) {
console.error('Error fetching token:', error);
}
};
getToken();
}, []);
return (
<div className="flex items-center gap-4">
{isAuthenticated ? (
<>
<span className="text-sm">Welcome {firstName + " " + lastName}</span>
<Tooltip title="Logout">
<IconButton color="primary" onClick={() => window.location.href = "/Account/Login/LogOff?returnUrl=%2F"}>
<Logout />
</IconButton>
</Tooltip>
</>
) : (
<form action="/Account/Login/ExternalLogin" method="post">
<input name="__RequestVerificationToken" type="hidden" value={token} />
<Tooltip title="Login">
<IconButton name="provider" type="submit" color="primary" value={`https://login.windows.net/${tenantId}/`}>
<Login />
</IconButton>
</Tooltip>
</form>
)}
</div>
);
};
使用 Power Pages 網頁 API
開發者可以利用 Power Pages Web API 將內容載入介面,或建立、更新及刪除紀錄。 在使用這些 API 之前,請確保所需的 Web API 已啟用,並且適當的資料表權限和 Web 角色已正確設定。
// Create query to get all cards from Dataverse
const fetchCards = async () => {
const response = await fetch("/_api/cr7ae_creditcardses");
const data = await response.json();
const cards = data.value;
const returnData = [];
// Loop through the cards and get the name and id of each card
for (let i = 0; i < cards.length; i++) {
const card = cards[i];
const cardName = card.cr7ae_name;
const cardId = card.cr7ae_creditcardsid;
const features = card.cr7ae_features
?.split(',')
.map((feature: string) => feature.trim());
const type = card.cr7ae_type;
const image = card.cr7ae_image;
const category = card.cr7ae_category
?.split(',')
.map((cat: string) => cat.trim());
// ...additional processing/pushing to returnData...
}
return returnData;
};
透過使用 Microsoft Entra ID 認證,啟用 localhost 的 Web API 呼叫來設定本地開發
開發人員在建立應用程式時需要更快的迭代週期、本地調試和熱重載功能。 SPA 透過使用 Microsoft Entra ID (Azure AD) v1 驗證來啟用從localhost 發出的安全 Web API 呼叫,以支援這些工作流程。
此設定可讓您:
- 在本機執行您的應用程式,並支援完整的驗證。
- 使用 Vite 等現代開發工具進行熱重載和快速回饋。
- 避免呼叫 Power Pages Web API 時發生 CORS 問題。
- 加速開發,而無需將變更部署到入口網站。
此設定可為SPA提供高效的本機開發體驗,讓開發人員能夠透過完整的API存取和驗證支援快速建置、測試和反覆運算。
Important
- 驗證時只使用 Microsoft Entra v1 端點。
- 持有人驗證僅在入口網站 9.7.6.6 版或更新版本中受支援。
- 僅在開發環境中套用這些設定。
設定步驟
啟用 SPA 驗證
- 在 https://portal.azure.com 中,開啟為您的入口網站註冊的 Microsoft Entra 應用程式。
- 啟用 單頁應用程式 (SPA) 驗證。
- 使用單頁應用程式平台設定,將
localhost新增為重新導向 URI。 如需詳細資訊 ,請參閱如何在應用程式中新增重新導向 URI 。-
重新導向 URI:
http://localhost:<port>/。
-
重新導向 URI:
新增網站設定
- 在 Power Pages 中新增這些 網站設定 :
Authentication/BearerAuthentication/Enabled = true Authentication/BearerAuthentication/Protocol = OpenIdConnect Authentication/BearerAuthentication/Provider = AzureAD使用 ADAL.js 登入
- 使用 ADAL.js實作用戶端登入。
Note
MSAL.js 不相容,因為 Power Pages 使用Microsoft Entra v1 端點,而 MSAL 使用 v2。 發行者格式因版本而異。
新增授權標頭
- 在所有 Web API 要求中包含此標頭:
Authorization: Bearer <id_token>將網站可見度設定為 [公用]
- 此設定可讓您
localhost存取網站以進行開發和測試。
- 此設定可讓您
設定開發環境的代理伺服器
- 如果您使用 Vite,請將這段代碼新增到
vite.config.js以避免 CORS 問題:
export default defineConfig({ plugins: [react()], server: { proxy: { '/_api': { target: 'https://site-foo.powerappsportals.com', changeOrigin: true, secure: true } } } });- 如果您使用 Vite,請將這段代碼新增到
與現有 Power Pages 網站的差異
下表總結了使用此功能建立的 SPA 網站與傳統 Power Pages 網站的主要差異:
| Feature | SPA 網站行為 |
|---|---|
| 伺服器端重新整理 | 始終返回網站的根頁面,並且用戶端路由器呈現子路由。 |
| 路由衝突 | 用戶端路由優先,硬重新整理將後援到根路由。 |
| 頁面工作區 | 不支援頁面工作區。 使用用戶端路由和用戶端網站頁面。 對於頁面層級安全性,使用全域使用者物件檢查指派的 Web 角色,並有條件地呈現 UI。 |
| 樣式工作區 | 不支援使用樣式工作區進行樣式設定。 使用架構的樣式,例如 CSS、CSS-in-JS 或公用程式類別。 |
| 本地化 | 單一語言支援。 實作用戶端資源載入。 |
| Liquid 範本 | 不支援 Liquid 程式碼和 Liquid 範本。 使用框架的範本引擎和 Web API 存取資料。 |
FAQ
對單元和整合測試有哪些支援?
目前,沒有對單元和整合測試的內建支援。 製作者應該在本地或在他們的 CI/CD 管道中編寫和執行這些測試。
是否支援使用 WebAssembly 進行 Power Fx 整合?
目前不支援此功能。
Power Pages 有原始碼嗎?
目前,創作者可以使用 TypeScript 或 GitHub Copilot Agent 來建立網站。 編譯後的 JavaScript 與 CSS 檔案可在 Visual Studio Code 中存取並編輯。 但是,目前不支援直接和廣泛地編輯 HTML 檔案。
我可以用這個功能在外部建立元件,然後帶到 Power Pages 網站嗎?
不,你無法利用這個功能將外部產生的元件帶到現有的 Power Pages 網站。
我可以新增清單和表單等現成的元件嗎?
目前不支援新增清單和表單等開箱即用的元件。 但是,您可以使用 React 框架和 Web API 建立自訂表單和清單。
原始檔控制如何運作?
開發人員可以使用 Power Platform Git 整合進行原始檔控制。 但是,只有編譯後的 Web 檔案才會加入到存放庫,而不是完整的原始程式碼。
這些網站支援 SEO 嗎?
由於 SPA 網站是使用 React 框架建立的並使用用戶端渲染,因此 SEO 支援有限。
SPA 網站提供哪些安全與治理支援給 Power Pages?
Power Pages 對 Web API 呼叫強制執行資料表權限與安全網頁角色,確保資料存取與使用者角色相符。 使用 window["Microsoft"].Dynamic365.Portal.User 物件擷取基本使用者屬性並根據使用者角色自訂體驗。
此外,SPA 網站支援:
- 公共和私人網站設定
- 治理設定,包括對匿名資料存取的控制
- 驗證提供者設定
這些功能有助於確保自訂元件在 Power Pages 內的安全且合規整合。