From 2b71a95f72b0a89dac5f679bd5ba76b7aa9e2f98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emil=20Holm=20Gj=C3=B8rup?= Date: Mon, 4 Nov 2024 16:07:24 +0100 Subject: [PATCH] Avoid building frontend for each environment and configure using env --- frontend/.env.mainnet | 10 ++ frontend/.env.stagenet | 10 ++ frontend/.env.testnet | 10 ++ frontend/CHANGELOG.md | 1 + frontend/Dockerfile | 13 +- frontend/Jenkinsfile | 2 - frontend/README.md | 31 ++-- frontend/nuxt.config.ts | 95 ++++++------ frontend/package.json | 6 +- .../components/molecules/GraphQLClient.vue | 14 +- .../components/molecules/NetworkSelect.vue | 78 ++++------ frontend/src/layouts/default.vue | 4 +- frontend/src/utils/composeBackendUrls.spec.ts | 49 ------- frontend/src/utils/composeBackendUrls.ts | 18 --- frontend/yarn.lock | 136 +++++++++++------- 15 files changed, 220 insertions(+), 257 deletions(-) create mode 100644 frontend/.env.mainnet create mode 100644 frontend/.env.stagenet create mode 100644 frontend/.env.testnet delete mode 100644 frontend/src/utils/composeBackendUrls.spec.ts delete mode 100644 frontend/src/utils/composeBackendUrls.ts diff --git a/frontend/.env.mainnet b/frontend/.env.mainnet new file mode 100644 index 000000000..0ca7f1e94 --- /dev/null +++ b/frontend/.env.mainnet @@ -0,0 +1,10 @@ +# Runtime configuration see comments in `nuxt.config.ts` for documentation. + +NUXT_PUBLIC_API_URL=https://api-ccdscan.mainnet.concordium.software/graphql +NUXT_PUBLIC_WS_URL=wss://api-ccdscan.mainnet.concordium.software/graphql +NUXT_PUBLIC_EXPLORER_NAME=Mainnet +NUXT_PUBLIC_EXPLORER_EXTERNAL=Testnet@https://testnet.ccdscan.io + +# Dev features, always disable in production. +NUXT_PUBLIC_ENABLE_URQL_DEVTOOLS=true +NUXT_PUBLIC_ENABLE_BREAKPOINT_HINT=true diff --git a/frontend/.env.stagenet b/frontend/.env.stagenet new file mode 100644 index 000000000..413f0a487 --- /dev/null +++ b/frontend/.env.stagenet @@ -0,0 +1,10 @@ +# Runtime configuration see comments in `nuxt.config.ts` for documentation. + +NUXT_PUBLIC_API_URL=https://api-ccdscan.stagenet.concordium.com/graphql +NUXT_PUBLIC_WS_URL=wss://api-ccdscan.stagenet.concordium.com/graphql +NUXT_PUBLIC_EXPLORER_NAME=Stagenet +NUXT_PUBLIC_EXPLORER_EXTERNAL=Mainnet@https://ccdscan.io;Testnet@https://testnet.ccdscan.io + +# Dev features, always disable in production. +NUXT_PUBLIC_ENABLE_URQL_DEVTOOLS=true +NUXT_PUBLIC_ENABLE_BREAKPOINT_HINT=true diff --git a/frontend/.env.testnet b/frontend/.env.testnet new file mode 100644 index 000000000..1ea3a0125 --- /dev/null +++ b/frontend/.env.testnet @@ -0,0 +1,10 @@ +# Runtime configuration see comments in `nuxt.config.ts` for documentation. + +NUXT_PUBLIC_API_URL=https://api-ccdscan.testnet.concordium.com/graphql +NUXT_PUBLIC_WS_URL=wss://api-ccdscan.testnet.concordium.com/graphql +NUXT_PUBLIC_EXPLORER_NAME=Testnet +NUXT_PUBLIC_EXPLORER_EXTERNAL=Mainnet@https://ccdscan.io + +# Dev features, always disable in production. +NUXT_PUBLIC_ENABLE_URQL_DEVTOOLS=true +NUXT_PUBLIC_ENABLE_BREAKPOINT_HINT=true diff --git a/frontend/CHANGELOG.md b/frontend/CHANGELOG.md index b8b6fee10..a91feb423 100644 --- a/frontend/CHANGELOG.md +++ b/frontend/CHANGELOG.md @@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file. - Migrate project to Nuxt `3.13`. - Update NodeJS runtime version to `18.12.1`. +- Frontend image is now independent on the network being used, and can be configured at runtime. ### Removed diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 709c18689..0813c344d 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -1,26 +1,15 @@ -ARG NODE_VERSION=18.12.1 +ARG NODE_VERSION=18.18.2 FROM node:${NODE_VERSION} as build - -ARG ENVIRONMENT - -ENV ENVIRONMENT=$ENVIRONMENT - WORKDIR /app - COPY package.json yarn.lock ./ RUN yarn - COPY . . RUN yarn build FROM node:${NODE_VERSION}-slim - ENV PORT=3000 ENV HOST=0.0.0.0 - EXPOSE 3000 - COPY --from=build /app/.output . - CMD ["node", "server/index.mjs"] diff --git a/frontend/Jenkinsfile b/frontend/Jenkinsfile index bfe7d4cec..f129d9022 100644 --- a/frontend/Jenkinsfile +++ b/frontend/Jenkinsfile @@ -1,7 +1,6 @@ // Params in JobDSL file // 'https://github.com/Concordium/concordium-infra-jenkins-jobs/blob/master/ccdscan_frontend.groovy': // - VERSION -// - TARGET_NET pipeline { agent any environment { @@ -21,7 +20,6 @@ pipeline { steps { sh '''\ docker build \ - --build-arg ENVIRONMENT=${TARGET_NET} \ -f "frontend/Dockerfile" \ -t "${image_name}" \ ./frontend diff --git a/frontend/README.md b/frontend/README.md index 228b104b6..66f1bdb95 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -4,11 +4,11 @@ The frontend of CCDScan is a server-side rendered single page app, which consume The frontend is built on some fundamental technologies: -- **[Vue](https://vuejs.org/)** +- **[Vue](https://vuejs.org/)** JavaScript framework for building user interfaces for the web. It is reactive, declarative and very approachable to build and extend. -- **[Nuxt 3](https://v3.nuxtjs.org/)** +- **[Nuxt 3](https://v3.nuxtjs.org/)** Application framework built on top of Vue. Out of the box it gives us some things that Vue itself lacks, such as routing, and it comes with a build system supporting code splitting and ohter optimisations. -- **[TypeScript](https://www.typescriptlang.org/)** +- **[TypeScript](https://www.typescriptlang.org/)** A typed programming language, which compiles to JavaScript. This acts as an accelerator during development, and prevents most type errors at write-time and compile-time. [More on this in a later section](#typescript). ## Setup @@ -23,25 +23,38 @@ yarn ### Run Development server +To run the development server a configuration can be provided using `.env` file, without it will assume the backend API is running locally. + ```sh yarn dev ``` -Go to [http://localhost:3000](http://localhost:3000) +Go to [http://localhost:3000](http://localhost:3000). + +To develop against our backend APIs already in production, specify the appropriate file with environment variables. Below is an example of using testnet backend API: + +```sh +yarn dev --dotenv .env.testnet +``` + ### Build and serve locally You can build and run the production image locally. -To build the image run +To build the image run: + ```sh -docker build -t IMAGE_NAME:VERSION --build-arg ENVIRONMENT= . +docker build -t IMAGE_NAME:VERSION . ``` -where `IMAGE_NAME` and `VERSION` are some container name and version of your choice and `CHAIN_ENVIRONMENT` is which environment to run agains (`stagenet`, `testnet` or `mainnet`). -To run the image run +where `IMAGE_NAME` and `VERSION` are some container name. + + +The image can be run against Testnet by providing the `.env.testnet` configuration. + ```sh -docker run -p 3000:3000 IMAGE_NAME:VERSION +docker run --public 3000:3000 --env-file .env.testnet IMAGE_NAME:VERSION ``` The application is now available at `http://localhost:3000/`. diff --git a/frontend/nuxt.config.ts b/frontend/nuxt.config.ts index 89017309d..e2471607c 100644 --- a/frontend/nuxt.config.ts +++ b/frontend/nuxt.config.ts @@ -1,41 +1,43 @@ import { defineNuxtConfig } from 'nuxt/config' -type Environment = 'dev' | 'stagenet' | 'testnet' | 'mainnet' -type Config = { - apiUrl: string - wsUrl: string -} - -const ENVIRONMENT = (process.env.ENVIRONMENT as Environment) || 'dev' - -const VARS: Record = { - dev: { - apiUrl: 'http://localhost:5090/graphql', - wsUrl: 'ws://localhost:5090/graphql', - }, - stagenet: { - apiUrl: 'https://api-ccdscan.stagenet.concordium.com/graphql', - wsUrl: 'wss://api-ccdscan.stagenet.concordium.com/graphql', - }, - testnet: { - apiUrl: 'https://api-ccdscan.testnet.concordium.com/graphql', - wsUrl: 'wss://api-ccdscan.testnet.concordium.com/graphql', - }, - mainnet: { - apiUrl: 'https://api-ccdscan.mainnet.concordium.software/graphql', - wsUrl: 'wss://api-ccdscan.mainnet.concordium.software/graphql', - }, -} - -const getConfig = (env: Environment): Config => { - return { - apiUrl: process.env.BACKEND_API_URL || VARS[env].apiUrl || '', - wsUrl: process.env.BACKEND_WS_URL || VARS[env].wsUrl || '', - } -} - export default defineNuxtConfig({ + // Configuration available to the application at runtime, note the `public` object will be + // expose directly in the client-side code and therefore should not contain secrets. + // Below values are default and can be overwritten by environment variables at runtime. + runtimeConfig: { + public: { + version: process.env.npm_package_version, + // URL to use when sending GraphQL queries to the CCDscan API. + // (env NUXT_PUBLIC_API_URL) + apiUrl: 'http://localhost:5090/graphql', + // URL to use when using websockets in GraphQL CCDscan API. + // (env NUXT_PUBLIC_WS_URL) + wsUrl: 'ws://localhost:5090/graphql', + // Settings for how to display the explorer. + explorer: { + // The name to display for the explorer. + // (env NUXT_PUBLIC_EXPLORER_NAME) + name: 'Local', + // The list of external explorers to link in the explorer selector. + // Should be provided as `@` separated by `;`. + // Ex.: 'Mainnet@https://ccdscan.io;Testnet@https://testnet.ccdscan.io' + // (env NUXT_PUBLIC_EXPLORER_EXTERNAL). + external: + 'Mainnet@https://ccdscan.io;Testnet@https://testnet.ccdscan.io;Stagenet@https://stagenet.ccdscan.io', + }, + // When enabled a hint for the current breakpoint (related to screen size) + // is displayed in the bottom left corner. Enable only for development. + // (env NUXT_PUBLIC_ENABLE_BREAKPOINT_HINT) + enableBreakpointHint: false, + // Enabled the urql-devtools for debugging GraphQL (require browser extension). + // Enable only for development. + // (env NUXT_PUBLIC_ENABLE_URQL_DEVTOOLS) + enableUrqlDevtools: false, + }, + }, + // Directory for finding the source files. srcDir: 'src/', + // Directories to search for components. components: [ '~/components', '~/components/atoms', @@ -45,27 +47,22 @@ export default defineNuxtConfig({ '~/components/Drawer', '~/components/BlockDetails', ], - - runtimeConfig: { - public: { - ...getConfig(ENVIRONMENT), - version: process.env.npm_package_version, - environment: ENVIRONMENT, - includeDevTools: - ENVIRONMENT === 'dev' || - ENVIRONMENT === 'stagenet' || - ENVIRONMENT === 'testnet', - }, - }, - + // Global CSS files css: ['~/assets/css/styles.css'], - + // Enable postCSS postcss: { plugins: { tailwindcss: {}, autoprefixer: {}, }, }, - + // Lock default values for Nuxt to what they were at this date. compatibilityDate: '2024-11-01', + // TypeScript configurations. + // typescript: { + // // Enable strict checks. + // strict: true, + // // Enable type-checking at build time. + // typeCheck: true, + // }, }) diff --git a/frontend/package.json b/frontend/package.json index c48a6601a..3cc50f252 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -65,10 +65,10 @@ "prettier": "^2.6.2", "ts-jest": "^28", "ts-node": "^10.8.0", - "typescript": "^4.7.2", - "vue-tsc": "^0.35.2" + "typescript": "^5.6.3", + "vue-tsc": "^2.1.10" }, "volta": { - "node": "18.12.1" + "node": "18.18.2" } } diff --git a/frontend/src/components/molecules/GraphQLClient.vue b/frontend/src/components/molecules/GraphQLClient.vue index d424e87bd..29e741713 100644 --- a/frontend/src/components/molecules/GraphQLClient.vue +++ b/frontend/src/components/molecules/GraphQLClient.vue @@ -12,18 +12,12 @@ import { provideClient, } from '@urql/vue' import { SubscriptionClient } from 'subscriptions-transport-ws' -import { composeBackendUrls } from '~/utils/composeBackendUrls' const { - public: { apiUrl, wsUrl, includeDevTools }, + public: { apiUrl, wsUrl, enableUrqlDevtools }, } = useRuntimeConfig() -const [composedApiUrl, composedWsUrl] = composeBackendUrls( - apiUrl, - wsUrl -)(location.host) - -const subscriptionClient = new SubscriptionClient(composedWsUrl, { +const subscriptionClient = new SubscriptionClient(wsUrl, { reconnect: true, }) @@ -34,13 +28,13 @@ let exchanges = [ }), ] -if (includeDevTools) { +if (enableUrqlDevtools) { const dtools = await import('@urql/devtools') exchanges = [dtools.devtoolsExchange, ...exchanges] } const client = createClient({ - url: composedApiUrl, + url: apiUrl, exchanges, }) diff --git a/frontend/src/components/molecules/NetworkSelect.vue b/frontend/src/components/molecules/NetworkSelect.vue index 8789d89c4..79c944fcc 100644 --- a/frontend/src/components/molecules/NetworkSelect.vue +++ b/frontend/src/components/molecules/NetworkSelect.vue @@ -1,27 +1,20 @@