build: use local mancala.js and @mancala/core packages

- Apps and @mancala/core depend on the packages in this repo through
  link: dependencies instead of the npm releases, so changes no longer
  need a publish
- Root package.json gets a build:packages script that installs and
  builds both packages
- Backend and frontend Docker images are built from the repo root so
  they can include the packages; compose builds them that way
- Metro watches the packages folder and resolves their imports from the
  app's node_modules
This commit is contained in:
Halit Aksoy 2026-10-14 02:09:05 +03:00
parent 30ad51c493
commit e165b0a0eb
18 changed files with 98 additions and 63 deletions

7
.dockerignore Normal file
View File

@ -0,0 +1,7 @@
# Images for apps/backend and apps/frontend are built with the repo root as context.
**/node_modules
**/dist
**/.parcel-cache
.git
apps/mobile
apps/keycloak

View File

@ -1,3 +1,20 @@
### Mancala
Mancala is an open source application for playing mancala game online.
## Development
The apps use the local `packages/mancala.js` and `packages/core` through `link:` dependencies, so build those first:
```sh
yarn build:packages # from the repo root
```
After changing a package, rebuild it (or run `yarn dev` in it to rebuild on change); the apps pick up the new `dist`.
Docker images for the backend and frontend are built from the repo root:
```sh
docker build -f apps/backend/Dockerfile -t jhalitaksoy/mancala-backend .
docker build -f apps/frontend/Dockerfile -t jhalitaksoy/mancala-frontend .
```

View File

@ -1 +0,0 @@
node_modules

View File

@ -1,16 +1,23 @@
# Build from the repo root: docker build -f apps/backend/Dockerfile .
FROM node:lts-buster-slim
ENV PORT=6000
# Create app directory
WORKDIR /usr/src/app
# Local packages the backend links to
COPY package.json package.json
COPY yarn.lock yarn.lock
COPY packages packages
RUN yarn build:packages
WORKDIR /usr/src/app/apps/backend
COPY apps/backend/package.json package.json
COPY apps/backend/yarn.lock yarn.lock
RUN yarn
COPY . .
COPY apps/backend .
RUN yarn build

View File

@ -25,7 +25,7 @@ yarn start
### Development Dependencies
This package depends on the local packages `@mancala/core` and `mancala.js`. Refer to their documentation for further instructions.
This package links the local packages `@mancala/core` and `mancala.js`. Build them first with `yarn build:packages` in the repo root.
## Authentication

View File

@ -14,7 +14,7 @@
"author": "",
"license": "ISC",
"dependencies": {
"@mancala/core": "0.0.2",
"@mancala/core": "link:../../packages/core",
"@types/cors": "^2.8.10",
"@types/morgan": "^1.9.3",
"@types/uuid": "^8.3.0",
@ -22,7 +22,7 @@
"cors": "^2.8.5",
"express": "^4.17.1",
"jose": "5.10.0",
"mancala.js": "^0.0.2-beta.3",
"mancala.js": "link:../../packages/mancala.js",
"morgan": "^1.10.0",
"uuid": "^8.3.2",
"ws": "^7.5.0"

View File

@ -525,15 +525,9 @@
"@jridgewell/resolve-uri" "^3.0.3"
"@jridgewell/sourcemap-codec" "^1.4.10"
"@mancala/core@0.0.2":
version "0.0.2"
resolved "https://registry.yarnpkg.com/@mancala/core/-/core-0.0.2.tgz#c50abb60f0598306cc78f36c799dfd8a9e7c274b"
integrity sha512-wnufrDxNMkdlXFYulxTtTe88Tw79j9RPC7iQh+W/c9V2yTUBoVk2FzdO0Wj9ZV2/nrrOqYI0IchjpoRyl3RDBQ==
dependencies:
"@types/uuid" "^9.0.8"
mancala.js "^0.0.2-beta.3"
tiny-emitter "^2.1.0"
uuid "^10.0.0"
"@mancala/core@link:../../packages/core":
version "0.0.0"
uid ""
"@sindresorhus/is@^0.14.0":
version "0.14.0"
@ -2627,10 +2621,9 @@ makeerror@1.0.12:
dependencies:
tmpl "1.0.5"
mancala.js@^0.0.2-beta.3:
version "0.0.2-beta.3"
resolved "https://registry.yarnpkg.com/mancala.js/-/mancala.js-0.0.2-beta.3.tgz#78edfa220e1a7172351a07f255eb81180845226a"
integrity sha512-LPmQ/VT4/JWFdp/YSB7k63zK7GyflApyh4M26t23a9uXFRSpBcWSePtNFpHU/xY2+1gVjlbOwQjup2QW3Tue7w==
"mancala.js@link:../../packages/mancala.js":
version "0.0.0"
uid ""
media-typer@0.3.0:
version "0.3.0"

View File

@ -1,6 +1,9 @@
services:
backend:
image: jhalitaksoy/mancala-backend:latest
build:
context: ..
dockerfile: apps/backend/Dockerfile
environment:
# Must match the iss claim, i.e. the public Keycloak URL; https://auth.playmancala.app/realms/mancala in production
KEYCLOAK_ISSUER: ${KEYCLOAK_HOSTNAME:-http://localhost:8080}/realms/mancala
@ -12,6 +15,9 @@ services:
- "5000:6000"
frontend:
image: jhalitaksoy/mancala-frontend:latest
build:
context: ..
dockerfile: apps/frontend/Dockerfile
ports:
- "3000:3000"
keycloak-db:

View File

@ -1,2 +0,0 @@
node_modules
dist

View File

@ -1,24 +1,32 @@
# Build from the repo root: docker build -f apps/frontend/Dockerfile .
FROM node:20-alpine3.19 AS build
ARG SERVER_ADDRESS WS_SERVER_ADDRESS
WORKDIR /app
# Local packages the frontend links to
COPY package.json ./
COPY packages packages
RUN yarn build:packages
COPY yarn.lock ./
WORKDIR /app/apps/frontend
COPY apps/frontend/package.json ./
COPY apps/frontend/yarn.lock ./
RUN yarn install
COPY . ./
COPY apps/frontend ./
RUN yarn build
FROM nginx:stable-alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY --from=build /app/apps/frontend/dist /usr/share/nginx/html
COPY nginx/nginx.conf /etc/nginx/conf.d/default.conf
COPY apps/frontend/nginx/nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 3000

View File

@ -13,7 +13,7 @@
"author": "",
"license": "ISC",
"dependencies": {
"@mancala/core": "0.0.2",
"@mancala/core": "link:../../packages/core",
"@szhsin/react-menu": "^3.1.2",
"@types/": "szhsin/react-menu",
"@types/eventemitter2": "^4.1.0",
@ -21,7 +21,7 @@
"@types/uuid": "^8.3.4",
"eventemitter2": "^6.4.7",
"i18next": "^23.11.5",
"mancala.js": "^0.0.2-beta.3",
"mancala.js": "link:../../packages/mancala.js",
"notyf": "^3.10.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",

View File

@ -313,15 +313,9 @@
resolved "https://registry.yarnpkg.com/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-2.5.2.tgz#28f643fbc0bec30b07fbe95b137879b6b4d1c9c5"
integrity sha512-zrBczSbXKxEyK2ijtbRdICDygRqWSRPpZMN5dD1T8VMEW5RIhIbwFWw2phDRXuBQdVDpSjalCIUMWMV2h3JaZA==
"@mancala/core@0.0.2":
version "0.0.2"
resolved "https://registry.yarnpkg.com/@mancala/core/-/core-0.0.2.tgz#c50abb60f0598306cc78f36c799dfd8a9e7c274b"
integrity sha512-wnufrDxNMkdlXFYulxTtTe88Tw79j9RPC7iQh+W/c9V2yTUBoVk2FzdO0Wj9ZV2/nrrOqYI0IchjpoRyl3RDBQ==
dependencies:
"@types/uuid" "^9.0.8"
mancala.js "^0.0.2-beta.3"
tiny-emitter "^2.1.0"
uuid "^10.0.0"
"@mancala/core@link:../../packages/core":
version "0.0.0"
uid ""
"@mischnic/json-sourcemap@^0.1.0":
version "0.1.0"
@ -1600,10 +1594,9 @@ loose-envify@^1.1.0, loose-envify@^1.4.0:
dependencies:
js-tokens "^3.0.0 || ^4.0.0"
mancala.js@^0.0.2-beta.3:
version "0.0.2-beta.3"
resolved "https://registry.yarnpkg.com/mancala.js/-/mancala.js-0.0.2-beta.3.tgz#78edfa220e1a7172351a07f255eb81180845226a"
integrity sha512-LPmQ/VT4/JWFdp/YSB7k63zK7GyflApyh4M26t23a9uXFRSpBcWSePtNFpHU/xY2+1gVjlbOwQjup2QW3Tue7w==
"mancala.js@link:../../packages/mancala.js":
version "0.0.0"
uid ""
mdn-data@2.0.14:
version "2.0.14"

View File

@ -1,3 +1,4 @@
const path = require('path');
const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
/**
@ -6,6 +7,13 @@ const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
*
* @type {import('metro-config').MetroConfig}
*/
const config = {};
const config = {
// @mancala/core and mancala.js are linked from the repo's packages folder.
watchFolders: [path.resolve(__dirname, '../../packages')],
resolver: {
// Lets the linked packages find modules that only the app installs, such as @babel/runtime.
nodeModulesPaths: [path.resolve(__dirname, 'node_modules')],
},
};
module.exports = mergeConfig(getDefaultConfig(__dirname), config);

View File

@ -10,13 +10,13 @@
"test": "jest"
},
"dependencies": {
"@mancala/core": "0.0.2",
"@mancala/core": "link:../../packages/core",
"@react-native/new-app-screen": "0.82.1",
"@react-navigation/native": "^6.1.17",
"@react-navigation/native-stack": "^6.9.26",
"@types/uuid": "^9.0.8",
"i18next": "^23.10.1",
"mancala.js": "^0.0.2-beta.3",
"mancala.js": "link:../../packages/mancala.js",
"react": "19.1.1",
"react-i18next": "^14.1.0",
"react-native": "0.82.1",

View File

@ -1340,15 +1340,9 @@
"@jridgewell/resolve-uri" "^3.1.0"
"@jridgewell/sourcemap-codec" "^1.4.14"
"@mancala/core@0.0.2":
version "0.0.2"
resolved "https://registry.yarnpkg.com/@mancala/core/-/core-0.0.2.tgz#c50abb60f0598306cc78f36c799dfd8a9e7c274b"
integrity sha512-wnufrDxNMkdlXFYulxTtTe88Tw79j9RPC7iQh+W/c9V2yTUBoVk2FzdO0Wj9ZV2/nrrOqYI0IchjpoRyl3RDBQ==
dependencies:
"@types/uuid" "^9.0.8"
mancala.js "^0.0.2-beta.3"
tiny-emitter "^2.1.0"
uuid "^10.0.0"
"@mancala/core@link:../../packages/core":
version "0.0.0"
uid ""
"@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1":
version "5.1.1-v1"
@ -4784,10 +4778,9 @@ makeerror@1.0.12:
dependencies:
tmpl "1.0.5"
mancala.js@^0.0.2-beta.3:
version "0.0.2-beta.3"
resolved "https://registry.yarnpkg.com/mancala.js/-/mancala.js-0.0.2-beta.3.tgz#78edfa220e1a7172351a07f255eb81180845226a"
integrity sha512-LPmQ/VT4/JWFdp/YSB7k63zK7GyflApyh4M26t23a9uXFRSpBcWSePtNFpHU/xY2+1gVjlbOwQjup2QW3Tue7w==
"mancala.js@link:../../packages/mancala.js":
version "0.0.0"
uid ""
marky@^1.2.2:
version "1.3.0"

7
package.json Normal file
View File

@ -0,0 +1,7 @@
{
"name": "mancala",
"private": true,
"scripts": {
"build:packages": "yarn --cwd packages/mancala.js install --frozen-lockfile && yarn --cwd packages/mancala.js build && yarn --cwd packages/core install --frozen-lockfile && yarn --cwd packages/core build"
}
}

View File

@ -16,7 +16,7 @@
"license": "MIT",
"dependencies": {
"@types/uuid": "^9.0.8",
"mancala.js": "^0.0.2-beta.3",
"mancala.js": "link:../mancala.js",
"tiny-emitter": "^2.1.0",
"uuid": "^10.0.0"
},

View File

@ -2334,10 +2334,9 @@ makeerror@1.0.12:
dependencies:
tmpl "1.0.5"
mancala.js@^0.0.2-beta.3:
version "0.0.2-beta.3"
resolved "https://registry.yarnpkg.com/mancala.js/-/mancala.js-0.0.2-beta.3.tgz#78edfa220e1a7172351a07f255eb81180845226a"
integrity sha512-LPmQ/VT4/JWFdp/YSB7k63zK7GyflApyh4M26t23a9uXFRSpBcWSePtNFpHU/xY2+1gVjlbOwQjup2QW3Tue7w==
"mancala.js@link:../mancala.js":
version "0.0.0"
uid ""
merge-stream@^2.0.0:
version "2.0.0"