From 084cf01fcd876542c493fa4bb0163ff0b77412d8 Mon Sep 17 00:00:00 2001 From: Louis Lam Date: Mon, 17 Jul 2023 14:54:40 +0800 Subject: [PATCH] Add support for Codespaces (#3432) * Create devcontainer.json * WIP * WIP * WIP * Create README.md * Try to fix cypress issue * Add extensions * WIP * Minor --- .devcontainer/README.md | 26 ++++++++++++++++++++++++++ .devcontainer/devcontainer.json | 23 +++++++++++++++++++++++ config/vite.config.js | 1 + package.json | 1 + src/mixins/public.js | 5 ++++- src/mixins/socket.js | 5 ++++- src/util-frontend.js | 14 +++++++++++++- 7 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 .devcontainer/README.md create mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/README.md b/.devcontainer/README.md new file mode 100644 index 000000000..da9fcb818 --- /dev/null +++ b/.devcontainer/README.md @@ -0,0 +1,26 @@ +# Codespaces + +Now you can modifiy Uptime Kuma on your browser without setting up a local development. + +![image](https://github.com/louislam/uptime-kuma/assets/1336778/31d9f06d-dd0b-4405-8e0d-a96586ee4595) + +1. Click `Code` -> `Create codespace on master` +2. Wait a few minutes until you see there are two exposed ports +3. Go to the `3000` url, see if it is working + +![image](https://github.com/louislam/uptime-kuma/assets/1336778/909b2eb4-4c5e-44e4-ac26-6d20ed856e7f) + +## Frontend + +Since it is using Vite.js, all frontend changes will be hot-reloaded. You don't need to restart the frontend, unless you try to add a new frontend dependency. + +## Restart Backend + +Sometimes you need to restart the backend after changed something. + +1. Click `Terminal` +1. Click `Codespaces: server-dev` in the right panel +1. Press `Ctrl + C` to stop the server +2. Press `Up` to run `npm run start-server-dev` + +![image](https://github.com/louislam/uptime-kuma/assets/1336778/e0c0a350-fe46-4588-9f37-e053c85834d1) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..a63e2537d --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,23 @@ +{ + "image": "mcr.microsoft.com/devcontainers/javascript-node:dev-20-bookworm", + "features": { + "ghcr.io/devcontainers/features/github-cli:1": {} + }, + "updateContentCommand": "npm ci", + "postCreateCommand": "", + "postAttachCommand": { + "frontend-dev": "npm run start-frontend-devcontainer", + "server-dev": "npm run start-server-dev", + "open-port": "gh codespace ports visibility 3001:public -c $CODESPACE_NAME" + }, + "customizations": { + "vscode": { + "extensions": [ + "streetsidesoftware.code-spell-checker", + "dbaeumer.vscode-eslint", + "GitHub.copilot" + ] + } + }, + "forwardPorts": [3000, 3001] +} diff --git a/config/vite.config.js b/config/vite.config.js index f9ca0651e..5e2c6b225 100644 --- a/config/vite.config.js +++ b/config/vite.config.js @@ -17,6 +17,7 @@ export default defineConfig({ }, define: { "FRONTEND_VERSION": JSON.stringify(process.env.npm_package_version), + "DEVCONTAINER": process.env.DEVCONTAINER, }, plugins: [ commonjs(), diff --git a/package.json b/package.json index 1526fbd3e..9f3737704 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "lint": "npm run lint:js && npm run lint:style", "dev": "concurrently -k -r \"wait-on tcp:3000 && npm run start-server-dev \" \"npm run start-frontend-dev\"", "start-frontend-dev": "cross-env NODE_ENV=development vite --host --config ./config/vite.config.js", + "start-frontend-devcontainer": "cross-env NODE_ENV=development DEVCONTAINER=1 vite --host --config ./config/vite.config.js", "start": "npm run start-server", "start-server": "node server/server.js", "start-server-dev": "cross-env NODE_ENV=development node server/server.js", diff --git a/src/mixins/public.js b/src/mixins/public.js index a3e12f460..c87bfb358 100644 --- a/src/mixins/public.js +++ b/src/mixins/public.js @@ -1,9 +1,12 @@ import axios from "axios"; +import { getDevContainerServerHostname, isDevContainer } from "../util-frontend"; const env = process.env.NODE_ENV || "production"; // change the axios base url for development -if (env === "development" || localStorage.dev === "dev") { +if (env === "development" && isDevContainer()) { + axios.defaults.baseURL = location.protocol + "//" + getDevContainerServerHostname(); +} else if (env === "development" || localStorage.dev === "dev") { axios.defaults.baseURL = location.protocol + "//" + location.hostname + ":3001"; } diff --git a/src/mixins/socket.js b/src/mixins/socket.js index 8e078b100..2d27d109a 100644 --- a/src/mixins/socket.js +++ b/src/mixins/socket.js @@ -4,6 +4,7 @@ import jwtDecode from "jwt-decode"; import Favico from "favico.js"; import dayjs from "dayjs"; import { DOWN, MAINTENANCE, PENDING, UP } from "../util.ts"; +import { getDevContainerServerHostname, isDevContainer } from "../util-frontend.js"; const toast = useToast(); let socket; @@ -93,7 +94,9 @@ export default { let wsHost; const env = process.env.NODE_ENV || "production"; - if (env === "development" || localStorage.dev === "dev") { + if (env === "development" && isDevContainer()) { + wsHost = protocol + getDevContainerServerHostname(); + } else if (env === "development" || localStorage.dev === "dev") { wsHost = protocol + location.hostname + ":3001"; } else { wsHost = protocol + location.host; diff --git a/src/util-frontend.js b/src/util-frontend.js index 3a59dac5e..9b3c1cd12 100644 --- a/src/util-frontend.js +++ b/src/util-frontend.js @@ -72,13 +72,25 @@ export function setPageLocale() { */ export function getResBaseURL() { const env = process.env.NODE_ENV; - if (env === "development" || localStorage.dev === "dev") { + if (env === "development" && isDevContainer()) { + return location.protocol + "//" + getDevContainerServerHostname(); + } else if (env === "development" || localStorage.dev === "dev") { return location.protocol + "//" + location.hostname + ":3001"; } else { return ""; } } +export function isDevContainer() { + // eslint-disable-next-line no-undef + return (typeof DEVCONTAINER === "number" && DEVCONTAINER === 1); +} + +export function getDevContainerServerHostname() { + // replace -3000 with -3001 + return location.hostname.replace(/-3000\.preview\.app\.github\.dev/, "-3001.preview.app.github.dev"); +} + /** * * @param {} mqtt wheather or not the regex should take into account the fact that it is an mqtt uri