-
Notifications
You must be signed in to change notification settings - Fork 8
Description
Summary
Enable developers to work on frontend apps (e.g., frontend-app-authn, frontend-app-learner-dashboard) and frontend-base itself locally, using npm workspaces. This applies both to site templates like frontend-template-site and to individual apps developing against a local frontend-base.
Note that this method is likely to fit nicely with tutor dev, since it also relies on bind mounts. I actually arrived at this proposal while researching a way to make app forks work with Tutor in production mode: it just so happens that it works for development (and without Tutor) just as well.
Problem
Currently, developing changes to frontend apps requires publishing to npm or using workarounds such as autoinstall, which currently only works for frontend-base, or yalc, which while generic, is unmaintained upstream. Both workarounds also make changes to package.json in target repos, which is painful since they should never be committed. Both are also comparatively slow, and are not particularly suited for Docker-based development.
Thus, there's no simple and efficient workflow for iterating on multiple packages simultaneously in the context of a running site, or for developing an app against a local copy of frontend-base.
Proposed Approach
Use npm workspaces with a packages/ directory (gitignored) to hold local checkouts of packages being developed. These are development-only overrides of the npm-published versions: no dependency-specific changes need to be made to package.json. If a package doesn't have a local checkout in packages/, the regular dependency is used.
This applies at two levels:
-
Site template —
frontend-template-sitecan have any combination offrontend-baseand frontend apps as workspace packages, with Turborepo orchestrating builds in dependency order. -
Individual apps — Apps like
frontend-app-learner-dashboardcan havefrontend-baseas a workspace package for independent development, usingconcurrentlyfor orchestration (sufficient for the simpler dependency tree, but we can always go with Turborepo here too).
Key pieces:
-
Workspace configuration —
"workspaces": ["packages/*"]inpackage.json, withpackages/in.gitignore. -
Mounting local checkouts — Since symlinks cause module resolution failures (Node.js/TypeScript resolve to the real path, breaking hoisted dependency resolution), local checkouts should be made available via bind mounts (
sudo mount --bindor FUSE'sbindfs) or Docker volume mounts, both of which present the directory as a real path within the project tree. -
Build orchestration — At the site template level, workspace packages must be built in dependency order (e.g.,
frontend-basebefore apps that depend on it). Turborepo handles this viadependsOn: ["^build"]inturbo.json. At the app level,concurrentlyis sufficient since there's only one dependency (frontend-base). TheopenedxCLI could eventually provide this natively. -
Watch mode without race conditions — The current
make buildtarget starts withrm -rf dist, which causes race conditions when watch scripts and the dev server run concurrently. Thecleantarget must be decoupled frombuild, so that watch rebuilds overwrite in place without wipingdist/. Theprepackscript should explicitly runclean && buildto preserve clean builds for publishing.
Changes Required
In frontend-base:
- Decouple
cleanfrombuildin the Makefile - Update
prepackto explicitly runclean && build - Add a
watch:buildnpm script and a genericnodemon.json
In frontend apps (frontend-app-authn, frontend-app-learner-dashboard, etc.):
- Same Makefile decoupling of
cleanfrombuild - Add
workspacesfield,packages/to.gitignore - Add
concurrently,nodemonas dev dependencies - Add workspace-aware scripts (
build:packages,dev:packages,watch:build) - Add
nodemon.jsonfor watch configuration
In frontend-template-site:
- Add
workspacesfield,packages/to.gitignore - Add
turbo.jsonfor build orchestration - Add workspace-aware scripts (
build:packages,clean:packages,dev:packages)
PRs
- frontend-base: feat: support npm workspaces for local development #185
- frontend-app-authn: feat: support npm workspaces for local development frontend-app-authn#1643
- frontend-app-learner-dashboard: feat: support npm workspaces for local development frontend-app-learner-dashboard#805
- frontend-template-site: feat: support npm workspaces for local development frontend-template-site#7
Trying it out
If you have all of the above checked out cleanly as siblings (like many of us often do):
cd frontend-template-site
mkdir -p packages/{frontend-base,frontend-app-authn,frontend-app-learner-dashboard}
cd packages
for i in *; do sudo mount --bind ../../${i} ${i}; done
cd ..
npm install
npm run dev:packagesThis should get you a tutor dev-compatible site deployment, in such a way that if you make changes to any of the dependencies, they'll show up automatically on the page.
For the future
If we for some reason start disliking the additional devDependencies (concurrently or turbo), we can consider adding the specific features we want out of them to the openedx CLI.
I don't recommend doing this now - or maybe ever - because more modern package managers (pnpm, etc) may handle our workspace needs without custom code or dependencies. In other words: let's wait and see.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status