-
Notifications
You must be signed in to change notification settings - Fork 2
PCF Controls
Scaffold, build, test and deploy a Power Apps component framework control — including debugging the deployed control on a live form with hot reload, so you edit your code and watch the real form update.
| You need | Why |
|---|---|
pac (Power Platform CLI) and Node.js
|
Scaffolding, building and pushing go through pac and the project's local npm tooling (Requirements) |
| A connected environment | For Push, Add to Solution and live-form debugging |
| Microsoft Edge | Only for Debug on live form — the extension drives it to reach the deployed control |
Initialise Project → PCF Control, or + Add Component → PCF Control in an existing repo. Two
questions decide the scaffold, and they map straight onto pac pcf init:
| Question | Options | What it means |
|---|---|---|
| Template | Field / Dataset | A field control binds to one column; a dataset control binds to a grid or view |
| Framework | None / React | Plain DOM rendering, or React (pac pcf init --framework react) |
The result is a standard pac pcf init layout — worth knowing, because the manifest lives one level
down: ControlManifest.Input.xml sits inside a <Constructor>/ folder, and the project root (with
package.json and the .pcfproj) is its parent. Every command resolves the root from the manifest, so
the control works whichever of its folders you are in.
| Button | What it does |
|---|---|
| Push to {environment} | Builds and pushes the control straight into the environment — the quickest loop while developing |
| Local Build | Builds the bundle only; no environment involved |
| Run harness (hot reload) | The PCF test harness in a browser, rebuilding as you edit — no Dataverse needed |
| Debug on live form (hot) | Serves your local bundle to the deployed control on a real form (below) |
| Refresh Types | Regenerates the typings for your manifest's properties after you edit the manifest |
| Add to Solution | Adds the control to your solution so it ships with it |
| Add service-layer structure (overflow) | Adds a service/state scaffold plus snippets, so logic does not accumulate in the control class |
| Stop live-form debug (overflow) | Ends the live-form session and stops its watcher |
Run harness (hot reload) is the fast one. The harness renders your control in a browser with mock data and rebuilds on save. Nothing is deployed and no environment is touched — use it for layout, rendering and property behaviour.
Debug on live form (hot) is the honest one. Your control runs in the real app, on a real form, with real data and real context — but the bundle it loads is the one on your machine, so a save rebuilds and the form picks it up. Use it when the harness cannot reproduce something: form context, related records, security, or an interaction with another control.
The control has to be deployed once first (Push, then put it on a form), because the extension intercepts the request for that deployed bundle and answers with your local build.
A model-driven app serves web resources through a service worker, which caches them — so intercepting at page level alone is not enough. The live-form debugger bypasses the service worker, which is what makes the swap actually take effect.
Run Stop live-form debug when you are done: it ends the session and tree-kills the file watcher, so
no webpack --watch process is left running.
- Add to Solution — the control becomes part of your solution.
- Export/import that solution as usual, or keep a Solutions component in the same repo and pack/deploy from there.
"Couldn't find a ControlManifest.Input.xml" — the command ran outside a PCF component. Scaffold one, or select the PCF card in the panel first.
Types do not match the manifest — run Refresh Types after editing ControlManifest.Input.xml.
The live form does not pick up my changes — check that Stop live-form debug has not already been run, that the control really is on the form you are looking at, and that you are looking at the browser the extension launched (it uses its own Edge profile).
A build fails with "'webpack' is not recognized" — the toolchain is a project-local dependency, not a global one. Let the component finish its install/restore (the extension runs it when scaffolding).
-
Requirements —
pac,dotnet, Node - Web Resources — the other client-side surface, with the same hot-reload idea for form scripts
- FetchXML Generator — the query tools work inside PCF TypeScript too