Browse Source

Convert payments app to use Vite - Part 1

(Doesn't compile)
Manav Rathi 1 year ago
parent
commit
4255e48abb

+ 1 - 1
.github/workflows/web-deploy-payments.yml

@@ -39,5 +39,5 @@ jobs:
                   apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
                   projectName: ente
                   branch: deploy/payments
-                  directory: web/apps/payments/out
+                  directory: web/apps/payments/dist
                   wranglerVersion: "3"

+ 3 - 0
web/.gitignore

@@ -10,6 +10,9 @@ node_modules/
 # Local env files
 .env*.local
 
+# Vite
+dist
+
 # Next.js
 .next/
 out/

+ 1 - 1
web/apps/payments/.eslintrc.js

@@ -1,3 +1,3 @@
 module.exports = {
-    extends: ["@/build-config/eslintrc-next"],
+    extends: ["@/build-config/eslintrc-vite"],
 };

+ 2 - 2
web/apps/payments/README.md

@@ -42,8 +42,8 @@ use a set of (development) Stripe keys which can be found in
 Add the following to `web/apps/payments/.env.local`:
 
 ```env
-NEXT_PUBLIC_ENTE_ENDPOINT = http://localhost:8080
-NEXT_PUBLIC_STRIPE_US_PUBLISHABLE_KEY = stripe_publishable_key
+VITE_ENTE_ENDPOINT = http://localhost:8080
+VITE_STRIPE_US_PUBLISHABLE_KEY = stripe_publishable_key
 ```
 
 Then start it locally

+ 12 - 0
web/apps/payments/index.html

@@ -0,0 +1,12 @@
+<!doctype html>
+<html lang="en">
+    <head>
+        <meta charset="utf-8" />
+        <meta name="viewport" content="width=device-width" />
+        <title>Payments | ente.io</title>
+    </head>
+    <body>
+        <div id="root"></div>
+        <script type="module" src="/src/main.tsx"></script>
+    </body>
+</html>

+ 7 - 1
web/apps/payments/package.json

@@ -2,8 +2,14 @@
     "name": "payments",
     "version": "0.0.0",
     "private": true,
+    "type": "module",
+    "scripts": {
+        "build": "tsc && vite build",
+        "dev": "vite --port 3001",
+        "preview": "vite preview --port 3001"
+    },
     "dependencies": {
-        "@/next": "*",
+        "@/vite": "*",
         "@stripe/stripe-js": "^1.17.0"
     }
 }

+ 7 - 0
web/apps/payments/src/App.tsx

@@ -0,0 +1,7 @@
+import React from "react";
+
+const App: React.FC = () => {
+    return <h1>Hello</h1>;
+};
+
+export default App;

+ 10 - 0
web/apps/payments/src/main.tsx

@@ -0,0 +1,10 @@
+import React from "react";
+import ReactDOM from "react-dom/client";
+import App from "./App.js";
+import "./index.css";
+
+ReactDOM.createRoot(document.getElementById("root")!).render(
+    <React.StrictMode>
+        <App />
+    </React.StrictMode>,
+);

+ 9 - 10
web/apps/payments/src/services/billing-service.ts

@@ -46,26 +46,25 @@ export const parseAndHandleRequest = async () => {
     }
 };
 
-const apiOrigin =
-    process.env.NEXT_PUBLIC_ENTE_ENDPOINT ?? "https://api.ente.io";
+const apiOrigin = import.meta.env.VITE_ENTE_ENDPOINT ?? "https://api.ente.io";
 
-type StripeAccountCountry = "IN" | "US";
+type StripeAccountCountry = "US" | "IN";
 
 const isStripeAccountCountry = (c: unknown): c is StripeAccountCountry =>
-    c == "IN" || c == "US";
+    c == "US" || c == "IN";
 
 const stripePublishableKey = (accountCountry: StripeAccountCountry) => {
     switch (accountCountry) {
-        case "IN":
-            return (
-                process.env.NEXT_PUBLIC_STRIPE_IN_PUBLISHABLE_KEY ??
-                "pk_live_51HAhqDK59oeucIMOiTI6MDDM2UWUbCAJXJCGsvjJhiO8nYJz38rQq5T4iyQLDMKxqEDUfU5Hopuj4U5U4dff23oT00fHvZeodC"
-            );
         case "US":
             return (
-                process.env.NEXT_PUBLIC_STRIPE_US_PUBLISHABLE_KEY ??
+                import.meta.env.VITE_STRIPE_US_PUBLISHABLE_KEY ??
                 "pk_live_51LZ9P4G1ITnQlpAnrP6pcS7NiuJo3SnJ7gibjJlMRatkrd2EY1zlMVTVQG5RkSpLPbsHQzFfnEtgHnk1PiylIFkk00tC0LWXwi"
             );
+        case "IN":
+            return (
+                import.meta.env.VITE_STRIPE_IN_PUBLISHABLE_KEY ??
+                "pk_live_51HAhqDK59oeucIMOiTI6MDDM2UWUbCAJXJCGsvjJhiO8nYJz38rQq5T4iyQLDMKxqEDUfU5Hopuj4U5U4dff23oT00fHvZeodC"
+            );
     }
 };
 

+ 1 - 2
web/apps/payments/src/utils/strings.ts

@@ -1,12 +1,11 @@
 /**
- * User facing strings in the app
+ * User facing strings in the app.
  *
  * By keeping them separate, we make our lives easier if/when we need to
  * localize the corresponding pages. Right now, these are just the values in the
  * default language, English.
  */
 const S = {
-    title: "Payments | ente.io",
     error_generic: "Oops, something went wrong.",
     error_404: "404 | This page could not be found.",
 };

+ 28 - 0
web/apps/payments/src/vite-env.d.ts

@@ -0,0 +1,28 @@
+/// <reference types="vite/client" />
+
+interface ImportMetaEnv {
+    /**
+     * Override the origin (scheme://host:port) of Ente's API to connect to.
+     *
+     * This is useful when testing or connecting to alternative installations.
+     */
+    readonly VITE_ENTE_ENDPOINT: string | undefined;
+    /**
+     * Override the publishable Stripe key to use when the user's account
+     * country is "US".
+     *
+     * This is useful when testing.
+     */
+    readonly VITE_STRIPE_US_PUBLISHABLE_KEY: string | undefined;
+    /**
+     * Override the publishable Stripe key to use when the user's account
+     * country is "IN".
+     *
+     * This is useful when testing.
+     */
+    readonly VITE_STRIPE_IN_PUBLISHABLE_KEY: string | undefined;
+}
+
+interface ImportMeta {
+    env: ImportMetaEnv;
+}

+ 3 - 19
web/apps/payments/tsconfig.json

@@ -1,21 +1,5 @@
 {
-    "compilerOptions": {
-        "target": "es5",
-        "lib": ["dom", "dom.iterable", "esnext"],
-        "skipLibCheck": true,
-        "strict": true,
-        "forceConsistentCasingInFileNames": true,
-        "noEmit": true,
-        "esModuleInterop": true,
-        "module": "esnext",
-        "moduleResolution": "node",
-        "resolveJsonModule": true,
-        "isolatedModules": true,
-        "jsx": "preserve",
-        "baseUrl": "./src",
-        "incremental": true,
-        "allowJs": true
-    },
-    "include": ["next-env.d.ts", "src/**/*.ts", "src/**/*.tsx"],
-    "exclude": ["node_modules", "next.config.js"]
+    "extends": "@/build-config/tsconfig-vite.json",
+    "include": ["src"],
+    "references": [{ "path": "./tsconfig.node.json" }]
 }

+ 4 - 0
web/apps/payments/tsconfig.node.json

@@ -0,0 +1,4 @@
+{
+    "extends": "@/build-config/tsconfig-vite.node.json",
+    "include": ["vite.config.ts"]
+}

+ 3 - 0
web/apps/payments/vite.config.ts

@@ -0,0 +1,3 @@
+import defineConfig from "@/vite/vite.config.ts";
+
+export default defineConfig;

+ 21 - 0
web/apps/payments/xtsconfig.json

@@ -0,0 +1,21 @@
+{
+    "compilerOptions": {
+        "target": "es5",
+        "lib": ["dom", "dom.iterable", "esnext"],
+        "skipLibCheck": true,
+        "strict": true,
+        "forceConsistentCasingInFileNames": true,
+        "noEmit": true,
+        "esModuleInterop": true,
+        "module": "esnext",
+        "moduleResolution": "node",
+        "resolveJsonModule": true,
+        "isolatedModules": true,
+        "jsx": "preserve",
+        "baseUrl": "./src",
+        "incremental": true,
+        "allowJs": true
+    },
+    "include": ["next-env.d.ts", "src/**/*.ts", "src/**/*.tsx"],
+    "exclude": ["node_modules", "next.config.js"]
+}

+ 4 - 3
web/package.json

@@ -11,7 +11,7 @@
         "build:accounts": "yarn workspace accounts next build",
         "build:auth": "yarn workspace auth next build",
         "build:cast": "yarn workspace cast next build",
-        "build:payments": "yarn workspace payments next build",
+        "build:payments": "yarn workspace payments build",
         "build:photos": "yarn workspace photos next build",
         "deploy:accounts": "open 'https://github.com/ente-io/ente/compare/deploy/accounts...main?quick_pull=1&title=[web]+Deploy+accounts&body=Deploy+accounts.ente.io'",
         "deploy:auth": "open 'https://github.com/ente-io/ente/compare/deploy/auth...main?quick_pull=1&title=[web]+Deploy+auth&body=Deploy+auth.ente.io'",
@@ -23,14 +23,15 @@
         "dev:albums": "yarn workspace photos next dev -p 3002",
         "dev:auth": "yarn workspace auth next dev",
         "dev:cast": "yarn workspace cast next dev -p 3001",
-        "dev:payments": "yarn workspace payments next dev -p 3001",
+        "dev:payments": "yarn workspace payments dev",
         "dev:photos": "yarn workspace photos next dev",
-        "lint": "yarn prettier --check . && yarn workspaces run eslint .",
+        "lint": "yarn prettier --check . && yarn workspaces run eslint --report-unused-disable-directives",
         "lint-fix": "yarn prettier --write . && yarn workspaces run eslint --fix .",
         "preview": "yarn preview:photos",
         "preview:accounts": "yarn build:accounts && python3 -m http.server -d apps/accounts/out 3001",
         "preview:auth": "yarn build:auth && python3 -m http.server -d apps/auth/out 3000",
         "preview:cast": "yarn build:cast && python3 -m http.server -d apps/accounts/out 3001",
+        "preview:payments": "yarn workspace payments preview",
         "preview:photos": "yarn build:photos && python3 -m http.server -d apps/photos/out 3000"
     },
     "resolutions": {

+ 5 - 0
web/packages/build-config/eslintrc-vite.js

@@ -0,0 +1,5 @@
+/* eslint-env node */
+module.exports = {
+    extends: ["./eslintrc-react.js"],
+    ignorePatterns: [".eslintrc.js", "dist"],
+};

+ 4 - 4
web/packages/build-config/tsconfig.transpile.json → web/packages/build-config/tsconfig-typecheck.json

@@ -14,14 +14,14 @@
          * transpiler (Next.js) will ensure that these things hold.
          *
          * Unlike the other individual library components (say how "esnext"
-         * implies "esnext.*"), "dom.iterable" (the ability to iterate over DOM
-         * elements) is not a subset of "dom" and needs to be listed out
+         * implies "ESNext.*"), "DOM.Iterable" (the ability to iterate over DOM
+         * elements) is not a subset of "DOM" and needs to be listed out
          * explicitly.
          *
          * Note that we don't need to specify the `target` compilerOption, since
          * tsc isn't actually generating (emitting) the JavaScript.
          */
-        "lib": ["esnext", "dom", "dom.iterable"],
+        "lib": ["ESnext", "DOM", "DOM.Iterable"],
 
         /*
          * The module system to assume the generated JavaScript will use.
@@ -29,7 +29,7 @@
          * Since we're using a bundler, we should set this to "esnext"
          * https://www.typescriptlang.org/docs/handbook/modules/guides/choosing-compiler-options.html
          */
-        "module": "esnext",
+        "module": "ESNext",
 
         /*
          * Tell TypeScript how to lookup the file for a given import

+ 45 - 0
web/packages/build-config/tsconfig-vite.json

@@ -0,0 +1,45 @@
+{
+    /* TSConfig file used for typechecking the files in src/
+     *
+     * The base configuration was generated using `yarn create vite`. This was
+     * already almost the same as the `tsconfig-typecheck.json` we use
+     * elsewhere, with one or two differences.
+     */
+    "compilerOptions": {
+        "target": "ES2020",
+        "useDefineForClassFields": true,
+        "lib": ["ES2020", "DOM", "DOM.Iterable"],
+        "module": "esnext",
+        "skipLibCheck": true,
+
+        /* Bundler mode */
+        "moduleResolution": "bundler",
+        "allowImportingTsExtensions": true,
+        "resolveJsonModule": true,
+        "isolatedModules": true,
+        "noEmit": true,
+        "jsx": "react-jsx",
+
+        /* Linting */
+        "strict": true,
+        "noUnusedLocals": true,
+        "noUnusedParameters": true,
+        "noFallthroughCasesInSwitch": true,
+
+        /*
+         * On top of the generated configuration, we've mostly added additional
+         * strictness checks.
+         */
+
+        /* Require the `type` modifier when importing types */
+        "verbatimModuleSyntax": true,
+
+        /* Stricter than strict */
+        "noImplicitReturns": true,
+        /* e.g. makes array indexing returns undefined */
+        "noUncheckedIndexedAccess": true,
+        "exactOptionalPropertyTypes": true
+    },
+    "include": ["src"],
+    "references": [{ "path": "./tsconfig.node.json" }]
+}

+ 15 - 0
web/packages/build-config/tsconfig-vite.node.json

@@ -0,0 +1,15 @@
+{
+    /* TSConfig file used for typechecking vite's config file itself
+     *
+     * These are vite defaults, generated using `yarn create vite`.
+     */
+    "compilerOptions": {
+        "composite": true,
+        "skipLibCheck": true,
+        "module": "ESNext",
+        "moduleResolution": "bundler",
+        "allowSyntheticDefaultImports": true,
+        "strict": true
+    },
+    "include": ["vite.config.ts"]
+}

+ 1 - 1
web/packages/next/tsconfig.json

@@ -1,5 +1,5 @@
 {
-    "extends": "@/build-config/tsconfig.transpile.json",
+    "extends": "@/build-config/tsconfig-typecheck.json",
     /* Typecheck all files with the given extensions (here or in subfolders) */
     "include": ["**/*.ts", "**/*.tsx"]
 }

+ 1 - 1
web/packages/utils/tsconfig.json

@@ -1,5 +1,5 @@
 {
-    "extends": "@/build-config/tsconfig.transpile.json",
+    "extends": "@/build-config/tsconfig-typecheck.json",
     /* Typecheck all files with the given extensions (here or in subfolders) */
     "include": ["**/*.ts"]
 }

+ 8 - 0
web/packages/vite/README.md

@@ -0,0 +1,8 @@
+## @/vite
+
+A base package for sharing configuration between our Vite + React + TS apps.
+
+It is not meant to share code, but provide the base versions in package.json and
+. As
+such, this is similar to the [build-config](../build-config/README.md) package,
+except this is for our projects that use Vite.

+ 17 - 0
web/packages/vite/package.json

@@ -0,0 +1,17 @@
+{
+    "name": "@/vite",
+    "version": "0.0.0",
+    "private": true,
+    "type": "module",
+    "dependencies": {
+        "react": "^18",
+        "react-dom": "^18"
+    },
+    "devDependencies": {
+        "@/build-config": "*",
+        "@types/react": "^18",
+        "@types/react-dom": "^18",
+        "@vitejs/plugin-react": "^4.2",
+        "vite": "^5.2"
+    }
+}

+ 4 - 0
web/packages/vite/tsconfig.node.json

@@ -0,0 +1,4 @@
+{
+    "extends": "@/build-config/tsconfig-vite.node.json",
+    "include": ["vite.config.ts"]
+}

+ 7 - 0
web/packages/vite/vite.config.ts

@@ -0,0 +1,7 @@
+import { defineConfig } from 'vite'
+import react from '@vitejs/plugin-react'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+  plugins: [react()],
+})