Allow UI Kit projects to be tunneled
The tunnel executor (starting from v6.0.1), does not handle UI Kit projects.
Unlike Custom UI, we cannot serve the UI Kit via a dev server (I believe). The Forge tunnel process expects the UI Kit to be part of the Forge app. One way to potentially make this work is to run the UI Kit app's build target in watch mode and continuously run the UI Kit app's package target.
Open questions:
- Can we run the
buildandpackagetargets in a coordinated manner, i.e. every time the build completes (build in watch mode), the package target runs
We could start by simulating this process manually to see if it works.
Hey tbinna! Posting this over here instead on the other tunnel issue. When I was working through some workarounds for the tunnel, I had a setup with Vite where I passed in a "mode" argument and that change the dist location output of the build (in this case build watch). That way we skipped the extra "package" step after doing a build. It just built straight into the existing resources folder of the forge app. I don't know if that works and can be universal across frontend app types, but just a suggestion for what we did with Vite.
Hey @tbinna, just curious if you have had time to look at this recently. I am going to try and figure out some workarounds since we have had a fair amount of UI Kit activity in our monorepo recently.
I did discover this week how to do Vite bundled UI Kit applications that work with the plugin well enough. If you are interested in seeing that config setup / diff between the base vite generated react app.
@tbinna Did some testing this morning and found a workaround for both webpack & vite bundled UI Kit frontend applications for tunneling correctly. The steps I did are below:
I typically run a package command first on the forge app just to make sure all the output is generated in the dist correctly.
Config changes for Vite apps:
Inside the vite.config.ts convert the defineConfig call to consume a function instead of an argument like so:
defineConfig(({ mode }) => ({
...
}));
In the build -> outputDir property change it from a single dist path to a ternary like below based off the mode arg:
build: {
outDir:
mode === 'tunnel'
? '../../dist/ui-kit-tunnel-test/backend/resources/ui-kit-tunnel-test-frontend'
: '../../dist/ui-kit-tunnel-test/frontend',
...
}
Config changes for Webpack apps:
Similar to the above we do a mode arg in the webpack config function instead of plain object:
module.exports = (_env, argv) => ({
output: {
path: join(
__dirname,
'../../../../../dist/ui-kit-tunnel-test/apps/',
argv.mode === 'tunnel' ? 'backend/resources/ui-kit-tunnel-test-frontend' : 'frontend/src'
),
},
...
});
Running the tunnel:
-
npx nx tunnel ui-kit-tunnel-test-backend(once this has fully started up and is idle) - In a separate terminal
npx nx build ui-kit-tunnel-test-frontend --watch --mode=tunnel
I assume the above code be done via the executor instead by overriding the config that is passed in for the build? Not 100% sure, but regardless I hope the above helps in some way.
Hey @zjkipping, thanks for the investigation and for sharing those details. This makes sense to me.
The tunnel executor already runs the package task once before it starts the Forge CLI tunnel command.
Based on your results above, I understand that the tunnel executor should run all UI Kit projects in "build watch" mode with the output directory set to the final location in the output directory of the "post-package" Forge app.
I believe this is doable since the interface for all the major builders has options to override the outputPath and enable watch mode without knowing the specifics about the builder configuration. Since the package executor writes into the Forge app output directory, UI Kit builds should probably only be started after the package task completes.
Am I missing anything here? It does not sound overly complicated, so I might try to implement this at the end of this week or early next week.
Thanks again for the investigation!
That solution sounds good to me @tbinna. Looking forward to testing anything you need on this.
Hey @tbinna, not trying to rush just curious if you have had time to take a stab at this implementation?
Hey @zjkipping, I did a quick draft a while back, but it did not work on the first try. The errors looked strange, so I was not sure if it was a setup issue or with the actual implementation. I will commit the updates and make a test release if you'd like to try it.