From 27ad1e96dddb9a7148c43ec7d2ba20cc00b179b2 Mon Sep 17 00:00:00 2001 From: vchikalkin Date: Sun, 15 Oct 2023 15:22:58 +0300 Subject: [PATCH] apps/web: check and pass env variables convert next.config to mjs --- apps/web/.eslintrc.js | 1 + apps/web/Dockerfile | 19 +++----- apps/web/components/Form.jsx | 16 +++---- apps/web/components/Login.jsx | 2 +- apps/web/config/runtime.ts | 14 ++++++ apps/web/config/schema/env.js | 9 ++++ apps/web/next.config.js | 25 ---------- apps/web/next.config.mjs | 26 ++++++++++ apps/web/package.json | 4 +- apps/web/pages/_document.tsx | 19 ++++---- apps/web/pages/index.jsx | 10 ++-- apps/web/tsconfig.json | 29 ++++------- apps/web/types/env.ts | 0 package.json | 14 +++--- turbo.json | 10 ++-- yarn.lock | 90 +++++++++++++++++++++-------------- 16 files changed, 162 insertions(+), 126 deletions(-) create mode 100644 apps/web/config/runtime.ts create mode 100644 apps/web/config/schema/env.js delete mode 100644 apps/web/next.config.js create mode 100644 apps/web/next.config.mjs create mode 100644 apps/web/types/env.ts diff --git a/apps/web/.eslintrc.js b/apps/web/.eslintrc.js index e59076c..7542a8d 100644 --- a/apps/web/.eslintrc.js +++ b/apps/web/.eslintrc.js @@ -7,4 +7,5 @@ module.exports = { project: './tsconfig.json', tsconfigRootDir: __dirname, }, + root: true, }; diff --git a/apps/web/Dockerfile b/apps/web/Dockerfile index 9ca47c7..aabe6b5 100644 --- a/apps/web/Dockerfile +++ b/apps/web/Dockerfile @@ -1,18 +1,19 @@ # This Dockerfile is copy-pasted into our main docs at /docs/handbook/deploying-with-docker. # Make sure you update both files! -FROM node:16-alpine AS builder +FROM node:alpine AS builder # Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. RUN apk add --no-cache libc6-compat RUN apk update # Set working directory WORKDIR /app RUN yarn global add turbo +RUN yarn global add dotenv-cli COPY . . RUN turbo prune --scope=web --docker # Add lockfile and package.json's of isolated subworkspace -FROM node:16-alpine AS installer +FROM node:alpine AS installer RUN apk add --no-cache libc6-compat RUN apk update WORKDIR /app @@ -28,18 +29,10 @@ RUN yarn install # Build the project COPY --from=builder /app/out/full/ . COPY turbo.json turbo.json +COPY .env .env +RUN yarn dotenv -e .env turbo run build --filter=web... -# Pass variables from .env -ARG BASE_PATH -ARG APP_TITLE -ARG APP_DESCRIPTION -ENV BASE_PATH=${BASE_PATH} -ENV APP_TITLE=${APP_TITLE} -ENV APP_DESCRIPTION=${APP_DESCRIPTION} - -RUN yarn turbo run build --filter=web... - -FROM node:16-alpine AS runner +FROM node:alpine AS runner WORKDIR /app ENV NEXT_TELEMETRY_DISABLED 1 diff --git a/apps/web/components/Form.jsx b/apps/web/components/Form.jsx index fa5c969..4a85d60 100644 --- a/apps/web/components/Form.jsx +++ b/apps/web/components/Form.jsx @@ -1,13 +1,13 @@ import styles from './Form.module.scss'; +import { publicRuntimeConfig } from '@/config/runtime'; +import Button from '@/elements/Button'; +import Error from '@/elements/Error'; +import { H3 } from '@/elements/H'; +import Input from '@/elements/Input'; import axios from 'axios'; -import Button from 'elements/Button'; -import Error from 'elements/Error'; -import { H3 } from 'elements/H'; -import Input from 'elements/Input'; -import getConfig from 'next/config'; import { useState } from 'react'; -const { publicRuntimeConfig: config } = getConfig(); +const { BASE_PATH, APP_TITLE } = publicRuntimeConfig; export default function Form() { const [hasError, setHasError] = useState(false); @@ -27,7 +27,7 @@ export default function Form() { .post('/signin', data) .then(() => { const url = - (window.location.pathname.replace(config.basePath, '') || '/') + + (window.location.pathname.replace(BASE_PATH, '') || '/') + (window.location.search || ''); window.location.replace(url); @@ -37,7 +37,7 @@ export default function Form() { }); }} > -

{config.appTitle}

+

{APP_TITLE}

{error} diff --git a/apps/web/components/Login.jsx b/apps/web/components/Login.jsx index bc4830f..e968933 100644 --- a/apps/web/components/Login.jsx +++ b/apps/web/components/Login.jsx @@ -1,6 +1,6 @@ import Form from './Form'; import styles from './Login.module.scss'; -import Logo from 'elements/Logo'; +import Logo from '@/elements/Logo'; export default function Login() { return ( diff --git a/apps/web/config/runtime.ts b/apps/web/config/runtime.ts new file mode 100644 index 0000000..e8b619a --- /dev/null +++ b/apps/web/config/runtime.ts @@ -0,0 +1,14 @@ +import type envSchema from './schema/env'; +import getConfig from 'next/config'; +import type { z } from 'zod'; + +type Config = z.infer; + +type RunTimeConfig = { + publicRuntimeConfig: Config; + serverRuntimeConfig: Config; +}; + +const { publicRuntimeConfig, serverRuntimeConfig } = getConfig() as RunTimeConfig; + +export { publicRuntimeConfig, serverRuntimeConfig }; diff --git a/apps/web/config/schema/env.js b/apps/web/config/schema/env.js new file mode 100644 index 0000000..254362a --- /dev/null +++ b/apps/web/config/schema/env.js @@ -0,0 +1,9 @@ +import { z } from 'zod'; + +const envSchema = z.object({ + APP_DESCRIPTION: z.string(), + APP_TITLE: z.string(), + BASE_PATH: z.string().optional().default(''), +}); + +export default envSchema; diff --git a/apps/web/next.config.js b/apps/web/next.config.js deleted file mode 100644 index f5f8a9c..0000000 --- a/apps/web/next.config.js +++ /dev/null @@ -1,25 +0,0 @@ -const path = require('path'); - -const runtimeConfig = { - appTitle: process.env.APP_TITLE, - description: process.env.APP_DESCRIPTION, - basePath: process.env.BASE_PATH, -}; - -/** @type {import('next').NextConfig} */ -const nextConfig = { - basePath: process.env.BASE_PATH, - output: 'standalone', - reactStrictMode: true, - swcMinify: true, - eslint: { - ignoreDuringBuilds: true, - }, - serverRuntimeConfig: runtimeConfig, - publicRuntimeConfig: runtimeConfig, - experimental: { - outputFileTracingRoot: path.join(__dirname, '../../'), - }, -}; - -module.exports = nextConfig; diff --git a/apps/web/next.config.mjs b/apps/web/next.config.mjs new file mode 100644 index 0000000..299a633 --- /dev/null +++ b/apps/web/next.config.mjs @@ -0,0 +1,26 @@ +import envSchema from './config/schema/env.js'; +import { dirname, join } from 'path'; +import { fileURLToPath } from 'url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +const runtimeConfig = envSchema.parse(process.env); + +/** @type {import('next').NextConfig} */ +const nextConfig = { + basePath: process.env.BASE_PATH, + eslint: { + ignoreDuringBuilds: true, + }, + experimental: { + outputFileTracingRoot: join(__dirname, '../../'), + }, + output: 'standalone', + publicRuntimeConfig: runtimeConfig, + reactStrictMode: true, + serverRuntimeConfig: runtimeConfig, + swcMinify: true, +}; + +export default nextConfig; diff --git a/apps/web/package.json b/apps/web/package.json index 9e9942a..6ce58c8 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -2,6 +2,7 @@ "name": "web", "version": "0.1.0", "private": true, + "type": "module", "scripts": { "dev": "next dev", "build": "next build", @@ -20,7 +21,8 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "sass": "^1.69.3", - "typescript": "5.2.2" + "typescript": "4.9.5", + "zod": "^3.22.4" }, "devDependencies": { "@vchikalkin/eslint-config-awesome": "^1.1.2", diff --git a/apps/web/pages/_document.tsx b/apps/web/pages/_document.tsx index 8636be7..f6d17d3 100644 --- a/apps/web/pages/_document.tsx +++ b/apps/web/pages/_document.tsx @@ -1,8 +1,8 @@ -import getConfig from 'next/config'; +/* eslint-disable @typescript-eslint/explicit-member-accessibility */ +import { serverRuntimeConfig } from '@/config/runtime'; import Document, { Head, Html, Main, NextScript } from 'next/document'; -const { serverRuntimeConfig: config } = getConfig(); -const { basePath = '', description } = config; +const { BASE_PATH, APP_DESCRIPTION } = serverRuntimeConfig; export default class MyDocument extends Document { render() { @@ -10,13 +10,12 @@ export default class MyDocument extends Document { - - - - - - - + + + + + + diff --git a/apps/web/pages/index.jsx b/apps/web/pages/index.jsx index 67b98aa..fa994ff 100644 --- a/apps/web/pages/index.jsx +++ b/apps/web/pages/index.jsx @@ -1,13 +1,13 @@ -import Login from 'components/Login'; -import getConfig from 'next/config'; +import Login from '@/components/Login'; +import { publicRuntimeConfig } from '@/config/runtime'; import Head from 'next/head'; -const { publicRuntimeConfig: config } = getConfig(); +const { APP_DESCRIPTION } = publicRuntimeConfig; function PageHead() { return ( - {`Вход - ${config.description}`} + {`Вход - ${APP_DESCRIPTION}`} ); } @@ -15,7 +15,7 @@ function PageHead() { export default function Home() { return ( <> - + ); diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json index 2891df2..a1ced37 100644 --- a/apps/web/tsconfig.json +++ b/apps/web/tsconfig.json @@ -1,12 +1,8 @@ { + "$schema": "https://json.schemastore.org/tsconfig", + "display": "Next.js", "compilerOptions": { - "baseUrl": ".", - "target": "es5", - "lib": [ - "dom", - "dom.iterable", - "esnext" - ], + "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, "strict": true, @@ -23,17 +19,12 @@ { "name": "next" } - ] + ], + "baseUrl": ".", + "paths": { + "@/*": ["*"] + } }, - "include": [ - "next-env.d.ts", - "**/*.ts", - "**/*.tsx", - "**/*.js", - "**/*.jsx", - ".next/types/**/*.ts" - ], - "exclude": [ - "node_modules" - ] + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx"], + "exclude": ["node_modules"] } diff --git a/apps/web/types/env.ts b/apps/web/types/env.ts new file mode 100644 index 0000000..e69de29 diff --git a/package.json b/package.json index dd77be9..b8eb32a 100644 --- a/package.json +++ b/package.json @@ -1,19 +1,21 @@ { - "name": "Evo.Auth", + "name": "evo-auth", "version": "0.0.0", "private": true, "workspaces": [ "apps/*" ], "scripts": { - "build": "turbo run build", - "dev": "turbo run dev --parallel", - "lint": "turbo run lint", - "lint:fix": "turbo run lint:fix", + "build": "dotenv -e .env turbo run build", + "dev": "dotenv -e .env.local turbo run dev", + "lint": "dotenv -e .env.local turbo run lint", + "lint:fix": "dotenv -e .env.local turbo run lint:fix", "clean": "turbo run clean", - "format": "prettier --write \"**/*.{ts,tsx,md}\"" + "format": "prettier --write \"**/*.{js,jsx,ts,tsx}\"", + "test": "dotenv -e .env.local turbo run test" }, "devDependencies": { + "dotenv-cli": "^7.3.0", "prettier": "latest", "turbo": "latest" }, diff --git a/turbo.json b/turbo.json index 6c04f24..b863a02 100644 --- a/turbo.json +++ b/turbo.json @@ -1,10 +1,15 @@ { "$schema": "https://turbo.build/schema.json", + "globalDependencies": [".env.*"], "pipeline": { "build": { "outputs": ["dist/**", ".next/**", "public/dist/**"], "dependsOn": ["^build"] }, + "dev": { + "cache": false, + "persistent": true + }, "lint": { "dependsOn": ["^build"], "cache": false, @@ -14,9 +19,8 @@ "dependsOn": ["^build"], "outputs": [] }, - "dev": { - "cache": false, - "persistent": true + "test": { + "cache": false }, "clean": { "cache": false diff --git a/yarn.lock b/yarn.lock index 30cade7..9fe4f8e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3265,12 +3265,22 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -dotenv-expand@10.0.0: +dotenv-cli@^7.3.0: + version "7.3.0" + resolved "https://registry.yarnpkg.com/dotenv-cli/-/dotenv-cli-7.3.0.tgz#21e33e7944713001677658d68856063968edfbd2" + integrity sha512-314CA4TyK34YEJ6ntBf80eUY+t1XaFLyem1k9P0sX1gn30qThZ5qZr/ZwE318gEnzyYP9yj9HJk6SqwE0upkfw== + dependencies: + cross-spawn "^7.0.3" + dotenv "^16.3.0" + dotenv-expand "^10.0.0" + minimist "^1.2.6" + +dotenv-expand@10.0.0, dotenv-expand@^10.0.0: version "10.0.0" resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-10.0.0.tgz#12605d00fb0af6d0a592e6558585784032e4ef37" integrity sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A== -dotenv@16.3.1: +dotenv@16.3.1, dotenv@^16.3.0: version "16.3.1" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== @@ -8015,47 +8025,47 @@ tsutils@^3.21.0: dependencies: tslib "^1.8.1" -turbo-darwin-64@1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/turbo-darwin-64/-/turbo-darwin-64-1.6.3.tgz#fad7e078784b0fafc0b1f75ce9378828918595f5" - integrity sha512-QmDIX0Yh1wYQl0bUS0gGWwNxpJwrzZU2GIAYt3aOKoirWA2ecnyb3R6ludcS1znfNV2MfunP+l8E3ncxUHwtjA== +turbo-darwin-64@1.10.15: + version "1.10.15" + resolved "https://registry.yarnpkg.com/turbo-darwin-64/-/turbo-darwin-64-1.10.15.tgz#8f1d80ca91e46909a2c80e416e475bc44c91ef9f" + integrity sha512-Sik5uogjkRTe1XVP9TC2GryEMOJCaKE2pM/O9uLn4koQDnWKGcLQv+mDU+H+9DXvKLnJnKCD18OVRkwK5tdpoA== -turbo-darwin-arm64@1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/turbo-darwin-arm64/-/turbo-darwin-arm64-1.6.3.tgz#f0a32cae39e3fcd3da5e3129a94c18bb2e3ed6aa" - integrity sha512-75DXhFpwE7CinBbtxTxH08EcWrxYSPFow3NaeFwsG8aymkWXF+U2aukYHJA6I12n9/dGqf7yRXzkF0S/9UtdyQ== +turbo-darwin-arm64@1.10.15: + version "1.10.15" + resolved "https://registry.yarnpkg.com/turbo-darwin-arm64/-/turbo-darwin-arm64-1.10.15.tgz#4b6b29c9d10c8e286b27d372936c09a98f34449a" + integrity sha512-xwqyFDYUcl2xwXyGPmHkmgnNm4Cy0oNzMpMOBGRr5x64SErS7QQLR4VHb0ubiR+VAb8M+ECPklU6vD1Gm+wekg== -turbo-linux-64@1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/turbo-linux-64/-/turbo-linux-64-1.6.3.tgz#8ddc6ac55ef84641182fe5ff50647f1b355826b0" - integrity sha512-O9uc6J0yoRPWdPg9THRQi69K6E2iZ98cRHNvus05lZbcPzZTxJYkYGb5iagCmCW/pq6fL4T4oLWAd6evg2LGQA== +turbo-linux-64@1.10.15: + version "1.10.15" + resolved "https://registry.yarnpkg.com/turbo-linux-64/-/turbo-linux-64-1.10.15.tgz#a892aae53946c68f311b2e71504af5b9768dd2c1" + integrity sha512-dM07SiO3RMAJ09Z+uB2LNUSkPp3I1IMF8goH5eLj+d8Kkwoxd/+qbUZOj9RvInyxU/IhlnO9w3PGd3Hp14m/nA== -turbo-linux-arm64@1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/turbo-linux-arm64/-/turbo-linux-arm64-1.6.3.tgz#846c1dc84d8dc741651906613c16acccba30428c" - integrity sha512-dCy667qqEtZIhulsRTe8hhWQNCJO0i20uHXv7KjLHuFZGCeMbWxB8rsneRoY+blf8+QNqGuXQJxak7ayjHLxiA== +turbo-linux-arm64@1.10.15: + version "1.10.15" + resolved "https://registry.yarnpkg.com/turbo-linux-arm64/-/turbo-linux-arm64-1.10.15.tgz#9d241414e75c7457ea8371c36c4b9700ec7ca553" + integrity sha512-MkzKLkKYKyrz4lwfjNXH8aTny5+Hmiu4SFBZbx+5C0vOlyp6fV5jZANDBvLXWiDDL4DSEAuCEK/2cmN6FVH1ow== -turbo-windows-64@1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/turbo-windows-64/-/turbo-windows-64-1.6.3.tgz#89ac819fa76ad31d12fbfdeb3045bcebd0d308eb" - integrity sha512-lKRqwL3mrVF09b9KySSaOwetehmGknV9EcQTF7d2dxngGYYX1WXoQLjFP9YYH8ZV07oPm+RUOAKSCQuDuMNhiA== +turbo-windows-64@1.10.15: + version "1.10.15" + resolved "https://registry.yarnpkg.com/turbo-windows-64/-/turbo-windows-64-1.10.15.tgz#7d19853634482f01b7c4ae8d5e255321a2f7582c" + integrity sha512-3TdVU+WEH9ThvQGwV3ieX/XHebtYNHv9HARHauPwmVj3kakoALkpGxLclkHFBLdLKkqDvmHmXtcsfs6cXXRHJg== -turbo-windows-arm64@1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/turbo-windows-arm64/-/turbo-windows-arm64-1.6.3.tgz#977607c9a51f0b76076c8b158bafce06ce813070" - integrity sha512-BXY1sDPEA1DgPwuENvDCD8B7Hb0toscjus941WpL8CVd10hg9pk/MWn9CNgwDO5Q9ks0mw+liDv2EMnleEjeNA== +turbo-windows-arm64@1.10.15: + version "1.10.15" + resolved "https://registry.yarnpkg.com/turbo-windows-arm64/-/turbo-windows-arm64-1.10.15.tgz#c7b0cf8732b02914b415577593afeda4155219fb" + integrity sha512-l+7UOBCbfadvPMYsX08hyLD+UIoAkg6ojfH+E8aud3gcA1padpjCJTh9gMpm3QdMbKwZteT5uUM+wyi6Rbbyww== turbo@latest: - version "1.6.3" - resolved "https://registry.yarnpkg.com/turbo/-/turbo-1.6.3.tgz#ec26cc8907c38a9fd6eb072fb10dad254733543e" - integrity sha512-FtfhJLmEEtHveGxW4Ye/QuY85AnZ2ZNVgkTBswoap7UMHB1+oI4diHPNyqrQLG4K1UFtCkjOlVoLsllUh/9QRw== + version "1.10.15" + resolved "https://registry.yarnpkg.com/turbo/-/turbo-1.10.15.tgz#356731acb46991b4e337cce2f7ccd3279bc1f1a6" + integrity sha512-mKKkqsuDAQy1wCCIjCdG+jOCwUflhckDMSRoeBPcIL/CnCl7c5yRDFe7SyaXloUUkt4tUR0rvNIhVCcT7YeQpg== optionalDependencies: - turbo-darwin-64 "1.6.3" - turbo-darwin-arm64 "1.6.3" - turbo-linux-64 "1.6.3" - turbo-linux-arm64 "1.6.3" - turbo-windows-64 "1.6.3" - turbo-windows-arm64 "1.6.3" + turbo-darwin-64 "1.10.15" + turbo-darwin-arm64 "1.10.15" + turbo-linux-64 "1.10.15" + turbo-linux-arm64 "1.10.15" + turbo-windows-64 "1.10.15" + turbo-windows-arm64 "1.10.15" type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" @@ -8141,6 +8151,11 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== +typescript@4.9.5: + version "4.9.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" + integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== + typescript@5.2.2, typescript@^5.2.2: version "5.2.2" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78" @@ -8541,3 +8556,8 @@ yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +zod@^3.22.4: + version "3.22.4" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.4.tgz#f31c3a9386f61b1f228af56faa9255e845cf3fff" + integrity sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==