diff --git a/developing/.gitignore b/developing/.gitignore new file mode 100644 index 00000000..268f1285 --- /dev/null +++ b/developing/.gitignore @@ -0,0 +1,7 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib +bin/* \ No newline at end of file diff --git a/developing/DEVELOPMENT.md b/developing/DEVELOPMENT.md new file mode 100644 index 00000000..03958286 --- /dev/null +++ b/developing/DEVELOPMENT.md @@ -0,0 +1,305 @@ +# Development Guide with Tilt + +This directory contains the Tilt configuration for local development of the Kubeflow Notebooks workspace components (controller, backend, and frontend). + +## Table of Contents + +- [Prerequisites](#prerequisites) +- [Quick Start](#quick-start) +- [Configuration](#configuration) +- [Development Workflow](#development-workflow) +- [Frontend Development](#frontend-development) +- [Troubleshooting](#troubleshooting) +- [Best Practices](#best-practices) + +## Prerequisites + +Before using Tilt, ensure you have the following installed: + +- [Tilt](https://docs.tilt.dev/install.html) - v0.30.0 or later +- [Docker](https://docs.docker.com/get-docker/) - for building and running containers +- [Kubernetes cluster](https://kubernetes.io/docs/setup/) - a local cluster (e.g., [Kind](https://kind.sigs.k8s.io/)) +- [kubectl](https://kubernetes.io/docs/tasks/tools/) - configured to connect to your cluster +- [Go](https://golang.org/doc/install) - v1.21.0 or later (for controller and backend) +- [Node.js](https://nodejs.org/) - v20.0.0 or later (for frontend) + +### Verify Prerequisites + +```bash +# Check Tilt +tilt version + +# Check Docker +docker --version + +# Check kubectl +kubectl version --client + +# Check Go (for controller/backend) +go version + +# Check Node.js (for frontend, if enabled) +node --version +npm --version +``` + +### Install Kind + +**Note**: The Makefile will automatically create a Kind cluster named `tilt` if it doesn't exist. However, you still need to have `kind` installed. + +```bash +# macOS +brew install kind + +# Or follow instructions at: https://kind.sigs.k8s.io/docs/user/quick-start/#installation +``` + + +### Using Kind Provider (Optional) + +You can choose to set the `KIND_EXPERIMENTAL_PROVIDER` environment variable in your shell session: + +```bash +export KIND_EXPERIMENTAL_PROVIDER=podman +``` + +The Makefile will honor this environment variable when creating the Kind cluster. + +## Quick Start + +1. **Navigate to the developing directory**: + ```bash + cd developing + ``` + +2. **Start Tilt using the Makefile**: + ```bash + make tilt + ``` + + **Important**: Always use `make tilt` instead of running `tilt up` directly. The Makefile ensures: + - The Kind cluster exists and is properly configured + - The Kubernetes context is switched to `kind-tilt` + - Cert-manager is installed (required for webhooks) + - All prerequisites are met before Tilt starts + + This will: + - Set up the Kind cluster (if it doesn't exist) + - Install cert-manager + - Open the Tilt UI in your browser (usually http://localhost:10350) + - Build the controller and backend Docker images + - Deploy them to your Kubernetes cluster + - Run the frontend locally with webpack dev server (if enabled) + - Set up port forwards for easy access + - Enable live updates when you make code changes + +3. **Monitor the Build**: + + Watch the Tilt UI in your browser. You should see: + + 1. **Local Resources**: + - `controller-generate` - Generating manifests and code + - `install-crds` - Installing CRDs + - `workspaces-frontend` - Running webpack dev server (if enabled) + + 2. **Docker Resources** (building images): + - `workspaces-controller` + - `workspaces-backend` + + 3. **Kubernetes Resources** (deploying): + - Deployments, Services, etc. + + **Note**: The Kind cluster and cert-manager setup are handled by the Makefile before Tilt starts, so you won't see those as Tilt resources. + + Wait until all resources show green/healthy status. + +5. **Access the componenets**: + - Controller health: `http://localhost:8081/healthz` + - Backend API: [Swagger UI](http://localhost:4000/api/v1/swagger/) + - Frontend UI: `http://localhost:9000` (if enabled) + +6. **Stop Tilt**: + ```bash + # In the terminal where Tilt is running, press Ctrl+C + # Or in another terminal: + make tilt-down + # Or: + tilt down + ``` + + This will: + - Stop all Tilt-managed resources + - Clean up deployments (but not the namespace) + +### Optional: Clean up namespace + +```bash +kubectl delete namespace kubeflow-workspaces +``` + +### Optional: Delete Kind cluster + +```bash +kind delete cluster --name tilt +``` + +## Configuration + +### Makefile Targets + +The Makefile provides several targets for managing your development environment: + +- `make tilt` or `make` - Set up Kind cluster, install cert-manager, and start Tilt +- `make tilt-up` - Alias for `make tilt` +- `make tilt-down` - Stop Tilt +- `make setup-kind` - Set up the Kind cluster only (without starting Tilt) +- `make setup-cert-manager` - Install cert-manager only (requires Kind cluster) + +### Skipping Frontend + +To run Tilt without the frontend (useful for backend/controller-only development): + +```bash +ENABLE_FRONTEND=false make tilt +``` + +### Custom Ports + +Port forwards are configured in the Tiltfile. To change them, edit the `port_forwards` parameter in the `k8s_resource()` calls. + +## Development Workflow + +1. **Make code changes** in any of the workspace components + - Keep changes focused and small +2. **Tilt automatically detects changes**: + - Controller/Backend: Rebuilds Docker images and redeploys + - Frontend: Webpack dev server hot-reloads changes automatically +3. **View logs** in the Tilt UI or via `tilt logs ` +4. **Add tests** for any new features +5. **Run linting checks** to ensure code style consistency +5. **Ensure tests pass** before opening a PR +6. **Write meaningful commit messages** highlighting what your code contribution is doing +7. **Be responsive** to feedback on the PR + +## Frontend Development + +The frontend runs as a local resource using webpack dev server instead of being built into a Docker image. This provides: + +1. **Fast Hot Reloading**: Changes appear instantly in the browser without rebuilding Docker images +2. **Better Developer Experience**: Full webpack dev server features (source maps, hot module replacement, etc.) +3. **Faster Iteration**: No Docker build step needed for frontend changes +4. **Proxy Configuration**: Webpack dev server proxies API requests to the backend running in Kubernetes + +The frontend uses the `.env.tilt` file for configuration when running with Tilt, which sets it up for standalone mode with proper proxy settings to connect to the backend. + +## Troubleshooting + +### Build Failures + +If builds fail, check: + +```bash +# Controller build issues +cd workspaces/controller && make build + +# Backend build issues +cd workspaces/backend && make build + +# Frontend dev server issues (for Tilt development) +cd workspaces/frontend && npm ci && npm run start:tilt + +# Frontend production build issues (for testing production builds) +cd workspaces/frontend && npm ci && npm run build:prod +``` + +Also verify: +- All prerequisites are installed +- Makefiles can find their dependencies +- Go modules are downloaded (`go mod download` in controller/backend) +- Node modules are installed (`npm ci` in frontend) + +#### BuildKit + +If you see the following error while `Tilt` is trying to build an image: +``` +Build Failed: failed to dial gRPC: unable to upgrade to h2c, received 404 +``` + +Try disabling Docker BuildKit support in the terminal where you are running `tilt up`: +```bash +export DOCKER_BUILDKIT=0 +``` + + +### Kubernetes Connection Issues + +The Makefile automatically handles context switching to `kind-tilt`. If you encounter issues: + +1. **Verify the Kind cluster exists**: + ```bash + kind get clusters + ``` + +2. **Check the current context**: + ```bash + kubectl config current-context + # Should be: kind-tilt + ``` + +3. **If context is wrong, manually switch**: + ```bash + kubectl config use-context kind-tilt + ``` + +4. **Verify cluster is accessible**: + ```bash + kubectl cluster-info + ``` + +5. **Ensure you have permissions** to create resources in the `kubeflow-workspaces` namespace + +**Note**: If you're running `tilt up` directly (not via `make tilt`), you may be on the wrong Kubernetes context. Always use `make tilt` to ensure the correct context is set. + +### Port Already in Use + +If ports are already in use, you can: + +1. Stop the conflicting service +2. Or modify port forwards in the Tiltfile + +### CRD Installation Fails + +If CRDs fail to install: + +```bash +# Check if you have permissions +kubectl auth can-i create crds + +# Try installing manually +cd workspaces/controller && make install +``` + +Also check that you have cluster-admin permissions or appropriate RBAC. + +## Best Practices + +1. **Run tests before committing**: + ```bash + # Controller + cd workspaces/controller && make lint && make test + + # Backend + cd workspaces/backend && make lint && make test + + # Frontend + cd workspaces/frontend && npm run test + ``` + +2. **Keep dependencies up to date**: + - Go modules: `go mod tidy` in controller/backend + - Node modules: `npm ci` in frontend + +3. **Clean up resources**: + - Always run `make tilt-down` (or `tilt down`) when done + - Optionally: `kubectl delete namespace kubeflow-workspaces` + - Optionally: `kind delete cluster --name tilt` to remove the Kind cluster diff --git a/developing/Makefile b/developing/Makefile new file mode 100644 index 00000000..920f3545 --- /dev/null +++ b/developing/Makefile @@ -0,0 +1,77 @@ +.PHONY: check-tilt tilt-up tilt-down setup-kind setup-cert-manager kustomize + +# Variables +CLUSTER_NAME := tilt +KIND_CONTEXT := kind-$(CLUSTER_NAME) + +# Location to install dependencies to +LOCALBIN ?= $(shell pwd)/bin +$(LOCALBIN): + mkdir -p $(LOCALBIN) + +# Tool Binaries +KUSTOMIZE ?= $(LOCALBIN)/kustomize + +# Tool Versions +KUSTOMIZE_VERSION ?= v5.5.0 + +# Export KIND_EXPERIMENTAL_PROVIDER to honor it if set in user's environment +# (e.g., KIND_EXPERIMENTAL_PROVIDER=podman for podman support) +export KIND_EXPERIMENTAL_PROVIDER + +# Check if tilt is installed +.PHONY: check-tilt +check-tilt: + @if ! command -v tilt >/dev/null 2>&1; then \ + echo "ERROR: tilt is not installed. Please install tilt first:"; \ + echo " curl -fsSL https://raw.githubusercontent.com/tilt-dev/tilt/master/scripts/install.sh | bash"; \ + echo " or visit: https://docs.tilt.dev/install.html"; \ + exit 1; \ + fi + +# Ensure kind cluster exists and context is set before running tilt +setup-kind: + @echo "Setting up Kind cluster..." + @if [ -n "$$KIND_EXPERIMENTAL_PROVIDER" ]; then \ + echo "Using KIND_EXPERIMENTAL_PROVIDER=$$KIND_EXPERIMENTAL_PROVIDER"; \ + fi + @./scripts/setup-kind.sh + +# Install cert-manager (depends on kind cluster being set up) +setup-cert-manager: setup-kind + @echo "Setting up cert-manager..." + @./scripts/setup-cert-manager.sh + + +# Run tilt up with kind cluster and cert-manager setup +tilt-up: check-tilt setup-cert-manager kustomize + @echo "Starting Tilt..." + @tilt up + + +# Stop Tilt +tilt-down: check-tilt kustomize + @echo "Stopping Tilt..." + @tilt down + +# Install kustomize +kustomize: $(KUSTOMIZE) +$(KUSTOMIZE): $(LOCALBIN) + $(call go-install-tool,$(KUSTOMIZE),sigs.k8s.io/kustomize/kustomize/v5,$(KUSTOMIZE_VERSION)) + +# go-install-tool will 'go install' any package with custom target and name of binary, if it doesn't exist +# $1 - target path with name of binary +# $2 - package url which can be installed +# $3 - specific version of package +define go-install-tool +@[ -f "$(1)-$(3)" ] || { \ +set -e; \ +package=$(2)@$(3) ;\ +echo "Downloading $${package}" ;\ +rm -f $(1) || true ;\ +GOBIN=$(LOCALBIN) go install $${package} ;\ +mv $(1) $(1)-$(3) ;\ +} ;\ +ln -sf $(1)-$(3) $(1) +endef + diff --git a/developing/OWNERS b/developing/OWNERS new file mode 100644 index 00000000..d6cf9cc9 --- /dev/null +++ b/developing/OWNERS @@ -0,0 +1,5 @@ +labels: + - area/ci + - area/v2 +approvers: + - andyatmiami \ No newline at end of file diff --git a/developing/Tiltfile b/developing/Tiltfile new file mode 100644 index 00000000..104173e1 --- /dev/null +++ b/developing/Tiltfile @@ -0,0 +1,169 @@ +# Tiltfile for Kubeflow Notebooks development +# - Streamlines local development of controller, backend, and frontend components + +# Disable analytics +analytics_settings(False) + +# Enforce minimum Tilt version +version_settings(check_updates=True, constraint=">=0.33.0") + +# Increase timeout for k8s operations +update_settings(k8s_upsert_timeout_secs=120) + +# Allow kind-tilt context (set up by Makefile before tilt runs) +allow_k8s_contexts('kind-tilt') + +# Allow skipping frontend via environment variable +enable_frontend = os.getenv("ENABLE_FRONTEND", "true").lower() == "true" + +# Get paths relative to Tiltfile location +# Tilt evaluates paths relative to the Tiltfile directory +tilt_root = os.path.dirname(os.path.abspath(__file__)) +# Go up 1 level from Tiltfile location: developing -> repo root +workspace_root = os.path.dirname(tilt_root) + +# Define paths relative to workspace root +controller_dir = os.path.join(workspace_root, "workspaces/controller") +backend_dir = os.path.join(workspace_root, "workspaces/backend") +frontend_dir = os.path.join(workspace_root, "workspaces/frontend") + +# Kustomize binary path (installed by Makefile) +kustomize_bin = os.path.join(tilt_root, "bin/kustomize") + + +# Exclude generated files/directories from file watching to prevent rebuild loops +# This prevents rebuild loops when auto-generated files are updated +# Patterns are scoped to specific directories so they don't affect other components +watch_settings( + ignore=[ + # Controller generated files + os.path.join(controller_dir, "bin/**"), + os.path.join(controller_dir, "**/zz_generated.*"), + os.path.join(controller_dir, "config/crd/**"), + os.path.join(controller_dir, "config/webhook/manifests.yaml"), + # Backend generated files + os.path.join(backend_dir, "bin/**"), + os.path.join(backend_dir, "openapi/**"), + # Frontend generated files + os.path.join(frontend_dir, "bin/**"), + os.path.join(frontend_dir, "src/generated/**"), + ], +) + + + +# ============================================================================ +# Controller +# ============================================================================ +# Note: Kind cluster and cert-manager are set up by the Makefile before Tilt starts + + +# Docker build for controller using production Dockerfile +# The production Dockerfile builds the binary inside Docker, avoiding .dockerignore issues +# Note: kustomize replaces 'workspaces-controller' with 'ghcr.io/kubeflow/notebooks/workspaces-controller' +# so we build with that name to match the final YAML +docker_build( + "ghcr.io/kubeflow/notebooks/workspaces-controller", + dockerfile=os.path.join(controller_dir, "Dockerfile"), + context=controller_dir, +) + +# K8s deployment for controller - use kustomize to build and preprocess YAMLs +controller_kustomize_path = os.path.join(controller_dir, "config/default") + +# Build manifests with kustomize (using kustomize binary from Makefile) +manifests = kustomize(controller_kustomize_path, kustomize_bin=kustomize_bin) + +# Decode YAMLs to modify them for development +objects = decode_yaml_stream(manifests) + +# Modify the controller deployment for development +for o in objects: + # Defensive check: skip if missing kind/name + kind = o.get("kind") + name = o.get("metadata", {}).get("name") + if not kind or not name: + continue + + # Modify the controller Deployment for dev + if kind == "Deployment" and name == "workspaces-controller": + containers = o.get("spec", {}).get("template", {}).get("spec", {}).get("containers", []) + for container in containers: + if container.get("name") == "manager": + env = container.setdefault("env", []) + use_istio_found = False + for i, env_var in enumerate(env): + if env_var.get("name") == "USE_ISTIO": + env[i] = {"name": "USE_ISTIO", "value": "false"} + use_istio_found = True + break + if not use_istio_found: + env.append({"name": "USE_ISTIO", "value": "false"}) + +# Encode back to YAML and apply +# This applies all controller manifests: CRDs, RBAC, ConfigMaps, Deployment, etc. +overridden_manifests = encode_yaml_stream(objects) +k8s_yaml(overridden_manifests) + +# Configure k8s resource for the controller deployment +k8s_resource( + "workspaces-controller", + port_forwards=["8080:8080", "8081:8081"], # metrics and health probe + labels=["controller"], +) + +# ============================================================================ +# Backend +# ============================================================================ + +# Docker build for backend using production Dockerfile +docker_build( + "workspaces-backend", + dockerfile=os.path.join(backend_dir, "Dockerfile"), + context=os.path.dirname(backend_dir), # Production Dockerfile expects workspaces/ as context +) + +# K8s deployment for backend - use kustomize to build +# allow_duplicates=True because namespace is already defined by controller +backend_kustomize_path = os.path.join(backend_dir, "manifests/kustomize/base") +k8s_yaml( + kustomize(backend_kustomize_path, kustomize_bin=kustomize_bin), + allow_duplicates=True, +) + +# Configure k8s resource +# Backend waits for controller to be ready first +# Tilt automatically matches the image based on the image name in the YAML +k8s_resource( + "workspaces-backend", + port_forwards="4000", + resource_deps=["workspaces-controller"], + labels=["backend"], +) + +# ============================================================================ +# Frontend (optional) +# ============================================================================ + +if enable_frontend: + # Run frontend as local resource using webpack dev server + # This enables hot-reloading and faster development iteration + # Uses the start:tilt script which sets DEV_ENV=tilt to load .env.tilt + # Frontend will be available at http://localhost:9000 + # Note: This is a long-running process, so it will show as "Updating" in Tilt UI + # Frontend waits for backend to be ready to avoid 504 errors on initial page load + local_resource( + "workspaces-frontend", + serve_cmd="cd {} && npm run start:tilt".format(frontend_dir), + deps=[ + frontend_dir, + ], + ignore=[ + os.path.join(frontend_dir, "node_modules"), + os.path.join(frontend_dir, "dist"), + os.path.join(frontend_dir, "coverage"), + ], + resource_deps=["workspaces-backend"], + labels=["frontend"], + ) + diff --git a/developing/scripts/kind.yaml b/developing/scripts/kind.yaml new file mode 100644 index 00000000..da9d0c57 --- /dev/null +++ b/developing/scripts/kind.yaml @@ -0,0 +1,18 @@ +apiVersion: kind.x-k8s.io/v1alpha4 +kind: Cluster +# This is needed in order to support projected volumes with service account tokens. +kubeadmConfigPatches: + - | + apiVersion: kubeadm.k8s.io/v1beta3 + kind: ClusterConfiguration + metadata: + name: config + apiServer: + extraArgs: + "service-account-issuer": "kubernetes.default.svc" + "service-account-signing-key-file": "/etc/kubernetes/pki/sa.key" +nodes: +- role: control-plane + image: kindest/node:v1.33.1@sha256:050072256b9a903bd914c0b2866828150cb229cea0efe5892e2b644d5dd3b34f +- role: worker + image: kindest/node:v1.33.1@sha256:050072256b9a903bd914c0b2866828150cb229cea0efe5892e2b644d5dd3b34f \ No newline at end of file diff --git a/developing/scripts/setup-cert-manager.sh b/developing/scripts/setup-cert-manager.sh new file mode 100755 index 00000000..31e28570 --- /dev/null +++ b/developing/scripts/setup-cert-manager.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# Setup script for cert-manager +# This script checks if cert-manager is installed and installs it if needed +# Uses the same version as the e2e tests: v1.12.13 (LTS version) + +set -euo pipefail + +# Use LTS version of cert-manager (matches e2e tests) +CERT_MANAGER_VERSION="v1.12.13" +CERT_MANAGER_URL="https://github.com/jetstack/cert-manager/releases/download/${CERT_MANAGER_VERSION}/cert-manager.yaml" + +# Check if cert-manager is already installed +if kubectl get crd certificates.cert-manager.io >/dev/null 2>&1; then + echo "Cert-manager is already installed" + exit 0 +fi + +echo "Installing cert-manager ${CERT_MANAGER_VERSION}..." +kubectl apply -f "${CERT_MANAGER_URL}" + +echo "Waiting for cert-manager to be ready..." +# Wait for cert-manager webhook to be ready (this is the critical component) +kubectl wait --for=condition=ready pod \ + -l app.kubernetes.io/instance=cert-manager \ + -n cert-manager \ + --timeout=120s || { + echo "Warning: cert-manager pods may not be fully ready, but continuing..." +} + +# Also wait for the CRDs to be established +kubectl wait --for=condition=established crd/certificates.cert-manager.io --timeout=60s || true +kubectl wait --for=condition=established crd/issuers.cert-manager.io --timeout=60s || true +kubectl wait --for=condition=established crd/clusterissuers.cert-manager.io --timeout=60s || true + +echo "Cert-manager installation complete" + diff --git a/developing/scripts/setup-kind.sh b/developing/scripts/setup-kind.sh new file mode 100755 index 00000000..476d4ef6 --- /dev/null +++ b/developing/scripts/setup-kind.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +# Setup script for Kind cluster +# This script checks if a Kind cluster exists and creates it if needed + +set -euo pipefail + +CLUSTER_NAME="tilt" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +KIND_CONFIG="${SCRIPT_DIR}/kind.yaml" + +# Check if kind command exists +if ! command -v kind >/dev/null 2>&1; then + echo "ERROR: kind is not installed. Please install kind first:" + echo " brew install kind # macOS" + echo " or visit: https://kind.sigs.k8s.io/docs/user/quick-start/#installation" + exit 1 +fi + +# Check if cluster exists +if ! kind get clusters 2>/dev/null | grep -q "^${CLUSTER_NAME}$"; then + echo "Creating Kind cluster '${CLUSTER_NAME}' with config from ${KIND_CONFIG}..." + kind create cluster --name "${CLUSTER_NAME}" --config "${KIND_CONFIG}" --wait 60s + echo "Kind cluster created successfully" +else + echo "Kind cluster '${CLUSTER_NAME}' already exists" +fi + +# Ensure kubectl context is set to the Kind cluster +kubectl config use-context "kind-${CLUSTER_NAME}" || true + +echo "Kind cluster setup complete" + diff --git a/workspaces/backend/.gitignore b/workspaces/backend/.gitignore index ce6feea7..2e7f7630 100644 --- a/workspaces/backend/.gitignore +++ b/workspaces/backend/.gitignore @@ -5,13 +5,4 @@ *.so *.dylib bin/* -Dockerfile.cross - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Go workspace file -go.work \ No newline at end of file +Dockerfile.cross \ No newline at end of file diff --git a/workspaces/frontend/.env.tilt b/workspaces/frontend/.env.tilt new file mode 100644 index 00000000..af366e86 --- /dev/null +++ b/workspaces/frontend/.env.tilt @@ -0,0 +1,13 @@ +APP_ENV=development + +DEPLOYMENT_MODE=standalone +MOCK_API_ENABLED=false +MANDATORY_NAMESPACE=default +URL_PREFIX= +PUBLIC_PATH=/ + +# Proxy configuration for Tilt development +# Backend is port-forwarded by Tilt to localhost:4000 +PROXY_HOST=localhost +PROXY_PORT=4000 +PROXY_PROTOCOL=http diff --git a/workspaces/frontend/config/webpack.dev.js b/workspaces/frontend/config/webpack.dev.js index 777d55e1..1a2ed6b4 100644 --- a/workspaces/frontend/config/webpack.dev.js +++ b/workspaces/frontend/config/webpack.dev.js @@ -8,7 +8,8 @@ const SpeedMeasurePlugin = require('speed-measure-webpack-plugin'); const smp = new SpeedMeasurePlugin({ disable: !process.env.MEASURE }); -setupDotenvFilesForEnv({ env: 'development' }); +const env = process.env.DEV_ENV ?? 'development'; +setupDotenvFilesForEnv({ env }); const webpackCommon = require('./webpack.common.js'); const RELATIVE_DIRNAME = process.env._RELATIVE_DIRNAME; @@ -64,7 +65,7 @@ module.exports = smp.wrap( plugins: [ ...setupWebpackDotenvFilesForEnv({ directory: RELATIVE_DIRNAME, - env: 'development', + env, isRoot: IS_PROJECT_ROOT_DIR, }), ], @@ -82,7 +83,7 @@ module.exports = smp.wrap( port: PORT, compress: true, historyApiFallback: { - index: `${BASE_PATH}/index.html`, + index: `${BASE_PATH}/index.html`.replace('//', '/'), }, hot: true, open: [BASE_PATH], diff --git a/workspaces/frontend/package.json b/workspaces/frontend/package.json index 126afe29..c0a0afd1 100644 --- a/workspaces/frontend/package.json +++ b/workspaces/frontend/package.json @@ -21,6 +21,7 @@ "build:prod": "webpack --config ./config/webpack.prod.js", "generate:api": "./scripts/generate-api.sh && npm run prettier", "start:dev": "webpack serve --hot --color --config ./config/webpack.dev.js", + "start:tilt": "DEV_ENV=tilt npm run start:dev", "test": "run-s prettier:check test:lint test:type-check test:unit test:cypress-ci", "test:cypress-ci": "npx concurrently -P -k -s first \"CY_MOCK=1 npm run cypress:server:build && npm run cypress:server\" \"npx wait-on tcp:127.0.0.1:9001 && npm run cypress:run:mock -- {@}\" -- ", "test:jest": "jest --passWithNoTests",