From d49714839109d50ea7ebe0f398f9be54f160d705 Mon Sep 17 00:00:00 2001 From: Stephen Wade Date: Sun, 31 Mar 2024 23:03:55 -0400 Subject: [PATCH] Switch to Vite and ESM (#1405) * Switch to Vite * Use standard Vite CSS import * Switch to ESM --- .eslintrc.js => .eslintrc.cjs | 2 +- Dockerfile | 1 - app/components/ShowEnded/ShowEnded.tsx | 9 +--- app/components/ShowIntro/ShowIntro.tsx | 9 +--- app/components/ShowPlaying/ShowPlaying.tsx | 19 ++----- app/components/Spinner/Spinner.tsx | 9 +--- .../ToastContainer/ToastContainer.tsx | 12 ++--- app/components/VolumeFab/VolumeFab.tsx | 8 +-- app/components/admin/AudioFileUpload.tsx | 2 +- app/forms/show/forms.tsx | 4 +- app/forms/show/index.ts | 2 - app/forms/show/validator.server.ts | 23 +++++++++ .../show/{validators.ts => validator.ts} | 19 ------- app/root.tsx | 2 - app/routes/$show.tsx | 25 +++------- app/routes/admin.audio-upload.events.ts | 23 ++------- app/routes/admin.audio-upload.new.ts | 2 +- app/routes/admin.shows.$show_.edit.tsx | 3 +- app/routes/admin.shows.new.tsx | 3 +- app/routes/admin.tsx | 10 ++-- .../admin-events.ts} | 0 app/sse.server/audio-file-events.ts | 16 ++++++ env.d.ts | 1 + package-lock.json | 49 ++++++++++++++++++- package.json | 11 +++-- playwright-ct.config.ts | 2 +- playwright.config.ts | 4 +- remix.config.js | 11 ----- remix.env.d.ts | 2 - stylelint.config.js | 2 +- tsconfig.json | 11 ++--- vite.config.ts | 13 +++++ 32 files changed, 154 insertions(+), 155 deletions(-) rename .eslintrc.js => .eslintrc.cjs (96%) delete mode 100644 app/forms/show/index.ts create mode 100644 app/forms/show/validator.server.ts rename app/forms/show/{validators.ts => validator.ts} (65%) rename app/{sse/admin-events.server.ts => sse.server/admin-events.ts} (100%) create mode 100644 app/sse.server/audio-file-events.ts create mode 100644 env.d.ts delete mode 100644 remix.config.js delete mode 100644 remix.env.d.ts create mode 100644 vite.config.ts diff --git a/.eslintrc.js b/.eslintrc.cjs similarity index 96% rename from .eslintrc.js rename to .eslintrc.cjs index c2e1ef93..e585244f 100644 --- a/.eslintrc.js +++ b/.eslintrc.cjs @@ -78,7 +78,7 @@ module.exports = { overrides: [ { - files: ['.eslintrc.js', 'remix.config.js', 'stylelint.config.js'], + files: ['.eslintrc.cjs', 'stylelint.config.js'], env: { node: true, diff --git a/Dockerfile b/Dockerfile index 43067ff8..6bff3fb4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -57,7 +57,6 @@ COPY --from=production-deps /app/node_modules /app/node_modules COPY --from=build /app/node_modules/.prisma /app/node_modules/.prisma COPY --from=build /app/build /app/build -COPY --from=build /app/public /app/public COPY --from=build /app/package.json /app/package.json COPY --from=build /app/start.sh /app/start.sh COPY --from=build /app/prisma /app/prisma diff --git a/app/components/ShowEnded/ShowEnded.tsx b/app/components/ShowEnded/ShowEnded.tsx index 5ff71cdb..2f64a8f7 100644 --- a/app/components/ShowEnded/ShowEnded.tsx +++ b/app/components/ShowEnded/ShowEnded.tsx @@ -1,14 +1,9 @@ -import type { LinksFunction } from '@remix-run/node'; +import '~/styles/show-ended.css'; + import type { FC } from 'react'; import { useEffect } from 'react'; import { toast } from 'react-toastify'; -import stylesUrl from '~/styles/show-ended.css'; - -export const links: LinksFunction = () => [ - { rel: 'stylesheet', href: stylesUrl }, -]; - interface ShowEndedProps { logoUrl: string; } diff --git a/app/components/ShowIntro/ShowIntro.tsx b/app/components/ShowIntro/ShowIntro.tsx index a8b7ccda..cad91451 100644 --- a/app/components/ShowIntro/ShowIntro.tsx +++ b/app/components/ShowIntro/ShowIntro.tsx @@ -1,11 +1,6 @@ -import type { LinksFunction } from '@remix-run/node'; -import type { FC } from 'react'; - -import stylesUrl from '~/styles/show-intro.css'; +import '~/styles/show-intro.css'; -export const links: LinksFunction = () => [ - { rel: 'stylesheet', href: stylesUrl }, -]; +import type { FC } from 'react'; interface ShowIntroProps { logoUrl: string; diff --git a/app/components/ShowPlaying/ShowPlaying.tsx b/app/components/ShowPlaying/ShowPlaying.tsx index 5a61d950..9e4e17ff 100644 --- a/app/components/ShowPlaying/ShowPlaying.tsx +++ b/app/components/ShowPlaying/ShowPlaying.tsx @@ -1,28 +1,17 @@ -import type { LinksFunction } from '@remix-run/node'; +import '~/styles/show-playing.css'; + import type { FC } from 'react'; import { useEffect } from 'react'; import { toast } from 'react-toastify'; -import { links as spinnerLinks } from '~/components/Spinner'; -import { - links as toastLinks, - ToastContainer, -} from '~/components/ToastContainer'; -import { links as volumeLinks, VolumeFab } from '~/components/VolumeFab'; -import stylesUrl from '~/styles/show-playing.css'; +import { ToastContainer } from '~/components/ToastContainer'; +import { VolumeFab } from '~/components/VolumeFab'; import type { AudioStatus } from '~/types/AudioStatus'; import type { ShowInfo } from '~/types/ShowInfo'; import { AudioCanvas } from './AudioCanvas'; import { CurrentTime } from './CurrentTime'; -export const links: LinksFunction = () => [ - ...spinnerLinks(), - ...volumeLinks(), - ...toastLinks(), - { rel: 'stylesheet', href: stylesUrl }, -]; - export interface ShowPlayingProps { volume: number; audioStatus: AudioStatus; diff --git a/app/components/Spinner/Spinner.tsx b/app/components/Spinner/Spinner.tsx index 8114d1b9..f24b09e2 100644 --- a/app/components/Spinner/Spinner.tsx +++ b/app/components/Spinner/Spinner.tsx @@ -1,11 +1,6 @@ -import type { LinksFunction } from '@remix-run/node'; -import type { FC } from 'react'; - -import stylesUrl from './spinner.css'; +import './spinner.css'; -export const links: LinksFunction = () => [ - { rel: 'stylesheet', href: stylesUrl }, -]; +import type { FC } from 'react'; export const Spinner: FC = () => (
diff --git a/app/components/ToastContainer/ToastContainer.tsx b/app/components/ToastContainer/ToastContainer.tsx index 1c5c2d7c..f6654f94 100644 --- a/app/components/ToastContainer/ToastContainer.tsx +++ b/app/components/ToastContainer/ToastContainer.tsx @@ -1,15 +1,9 @@ -import type { LinksFunction } from '@remix-run/node'; +import 'react-toastify/dist/ReactToastify.min.css'; +import './toast.css'; + import type { CloseButtonProps } from 'node_modules/react-toastify/dist/components'; import type { FC } from 'react'; import { cssTransition, ToastContainer as Container } from 'react-toastify'; -import toastStylesUrl from 'react-toastify/dist/ReactToastify.min.css'; - -import stylesUrl from './toast.css'; - -export const links: LinksFunction = () => [ - { rel: 'stylesheet', href: toastStylesUrl }, - { rel: 'stylesheet', href: stylesUrl }, -]; const ToastClose: FC = ({ type, closeToast }) => { return ( diff --git a/app/components/VolumeFab/VolumeFab.tsx b/app/components/VolumeFab/VolumeFab.tsx index 9b116d6d..6ec3a218 100644 --- a/app/components/VolumeFab/VolumeFab.tsx +++ b/app/components/VolumeFab/VolumeFab.tsx @@ -1,19 +1,15 @@ -import type { LinksFunction } from '@remix-run/node'; +import './volume-fab.css'; + import type { FC, KeyboardEventHandler } from 'react'; import { memo, useCallback, useRef, useState } from 'react'; import { useOnClickOutside } from 'usehooks-ts'; import { VolumeDownIcon, VolumeMuteIcon, VolumeUpIcon } from './icons'; -import stylesUrl from './volume-fab.css'; const INPUT_MIN = 0; const INPUT_MAX = 100; const INPUT_STEP = 5; -export const links: LinksFunction = () => [ - { rel: 'stylesheet', href: stylesUrl }, -]; - export interface VolumeFabProps { volume: number; onVolumeInput: (volume: number) => void; diff --git a/app/components/admin/AudioFileUpload.tsx b/app/components/admin/AudioFileUpload.tsx index b0efd154..bdfde0de 100644 --- a/app/components/admin/AudioFileUpload.tsx +++ b/app/components/admin/AudioFileUpload.tsx @@ -7,8 +7,8 @@ import { useControlField, useField } from 'remix-validated-form'; import { UPLOAD_AUDIO_FORM_KEY } from '~/forms/upload-audio'; import { useSse } from '~/hooks/useSse'; import type { loader as audioUploadLoader } from '~/routes/admin.audio-upload.$id'; -import type { AudioFileUploadEvent } from '~/routes/admin.audio-upload.events'; import type { action as newAudioUploadAction } from '~/routes/admin.audio-upload.new'; +import type { AudioFileUploadEvent } from '~/sse.server/audio-file-events'; type PutFormResponse = SerializeFrom; diff --git a/app/forms/show/forms.tsx b/app/forms/show/forms.tsx index 4fa8af6e..bedf008c 100644 --- a/app/forms/show/forms.tsx +++ b/app/forms/show/forms.tsx @@ -18,8 +18,8 @@ import { InputDateTime } from '~/components/admin/InputDateTime'; import { SaveButton } from '~/components/admin/SaveButton'; import { useOrigin } from '~/hooks/useOrigin'; -import type { schema, setSchema } from './validators'; -import { clientValidator } from './validators'; +import type { schema, setSchema } from './validator'; +import { clientValidator } from './validator'; const SHOW_FORM_ID = 'show-form'; diff --git a/app/forms/show/index.ts b/app/forms/show/index.ts deleted file mode 100644 index 16b4d22a..00000000 --- a/app/forms/show/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './forms'; -export * from './validators'; diff --git a/app/forms/show/validator.server.ts b/app/forms/show/validator.server.ts new file mode 100644 index 00000000..4c6fb68d --- /dev/null +++ b/app/forms/show/validator.server.ts @@ -0,0 +1,23 @@ +import { withZod } from '@remix-validated-form/with-zod'; + +import { db } from '~/db/db.server'; + +import { schema } from './validator'; + +export function makeServerValidator({ + previousId, +}: { previousId?: string } = {}) { + return withZod( + schema.refine( + async ({ id }) => { + if (id === previousId) return true; + const existingShow = await db.show.findUnique({ where: { id } }); + return !existingShow; + }, + { + path: ['id'], + message: 'A show already exists with that URL.', + }, + ), + ); +} diff --git a/app/forms/show/validators.ts b/app/forms/show/validator.ts similarity index 65% rename from app/forms/show/validators.ts rename to app/forms/show/validator.ts index 662f1461..4171e18f 100644 --- a/app/forms/show/validators.ts +++ b/app/forms/show/validator.ts @@ -2,8 +2,6 @@ import { withZod } from '@remix-validated-form/with-zod'; import { z } from 'zod'; import { zfd } from 'zod-form-data'; -import { db } from '~/db/db.server'; - export const setSchema = z.object({ id: zfd.text(), artist: zfd.text(), @@ -30,20 +28,3 @@ export const schema = zfd.formData({ }); export const clientValidator = withZod(schema); - -export const makeServerValidator = ({ - previousId, -}: { previousId?: string } = {}) => - withZod( - schema.refine( - async ({ id }) => { - if (id === previousId) return true; - const existingShow = await db.show.findUnique({ where: { id } }); - return !existingShow; - }, - { - path: ['id'], - message: 'A show already exists with that URL.', - }, - ), - ); diff --git a/app/root.tsx b/app/root.tsx index 7b940c2a..1663db33 100644 --- a/app/root.tsx +++ b/app/root.tsx @@ -3,7 +3,6 @@ import { rootAuthLoader } from '@clerk/remix/ssr.server'; import type { LoaderFunction, MetaFunction } from '@remix-run/node'; import { Links, - LiveReload, Meta, Outlet, redirect, @@ -51,7 +50,6 @@ function App() { - ); diff --git a/app/routes/$show.tsx b/app/routes/$show.tsx index 0874395c..2c1a57f9 100644 --- a/app/routes/$show.tsx +++ b/app/routes/$show.tsx @@ -1,8 +1,7 @@ -import type { - LinksFunction, - LoaderFunction, - MetaFunction, -} from '@remix-run/node'; +import '~/styles/elevation.css'; +import '~/styles/show.css'; + +import type { LoaderFunction, MetaFunction } from '@remix-run/node'; import { json, redirect } from '@remix-run/node'; import { useLoaderData } from '@remix-run/react'; import { addSeconds, formatISO } from 'date-fns'; @@ -10,13 +9,11 @@ import type { FC } from 'react'; import useLocalStorageState from 'use-local-storage-state'; import { AudioController } from '~/components/AudioController'; -import { links as endedLinks, ShowEnded } from '~/components/ShowEnded'; -import { links as introLinks, ShowIntro } from '~/components/ShowIntro'; -import { links as playingLinks, ShowPlaying } from '~/components/ShowPlaying'; +import { ShowEnded } from '~/components/ShowEnded'; +import { ShowIntro } from '~/components/ShowIntro'; +import { ShowPlaying } from '~/components/ShowPlaying'; import { db } from '~/db/db.server'; import { useShowInfo } from '~/hooks/useShowInfo'; -import elevationStylesUrl from '~/styles/elevation.css'; -import showStylesUrl from '~/styles/show.css'; import type { ShowData } from '~/types/ShowData'; export const meta: MetaFunction = ({ data, params }) => { @@ -29,14 +26,6 @@ export const meta: MetaFunction = ({ data, params }) => { ]; }; -export const links: LinksFunction = () => [ - { rel: 'stylesheet', href: elevationStylesUrl }, - { rel: 'stylesheet', href: showStylesUrl }, - ...introLinks(), - ...playingLinks(), - ...endedLinks(), -]; - export const loader = (async ({ params }) => { const id = params.show!; diff --git a/app/routes/admin.audio-upload.events.ts b/app/routes/admin.audio-upload.events.ts index 1c65e11a..1f7f866a 100644 --- a/app/routes/admin.audio-upload.events.ts +++ b/app/routes/admin.audio-upload.events.ts @@ -1,26 +1,11 @@ -import type { Prisma } from '@prisma/client'; -import type { LoaderFunction, SerializeFrom } from '@remix-run/node'; +import type { LoaderFunction } from '@remix-run/node'; import { redirectToLogin } from '~/auth/redirect-to-login.server'; -import { - adminEventStream, - dispatchAdminEvent, -} from '~/sse/admin-events.server'; - -export type AudioFileUploadEvent = SerializeFrom< - Prisma.AudioFileUploadGetPayload<{ - include: { audioFile: true }; - }> ->; - -const EVENT_TYPE = 'audio file processing'; - -export function emitAudioFileProcessingEvent(data: AudioFileUploadEvent) { - dispatchAdminEvent(EVENT_TYPE, data); -} +import { adminEventStream } from '~/sse.server/admin-events'; +import { AUDIO_FILE_EVENT_TYPE } from '~/sse.server/audio-file-events'; export const loader = (async (args) => { await redirectToLogin(args); - return adminEventStream(args.request, EVENT_TYPE); + return adminEventStream(args.request, AUDIO_FILE_EVENT_TYPE); }) satisfies LoaderFunction; diff --git a/app/routes/admin.audio-upload.new.ts b/app/routes/admin.audio-upload.new.ts index 7d31a03b..01ba7e7a 100644 --- a/app/routes/admin.audio-upload.new.ts +++ b/app/routes/admin.audio-upload.new.ts @@ -15,7 +15,7 @@ import { ffmpeg } from '~/ffmpeg/ffmpeg.server'; import type { FFprobeOutput } from '~/ffmpeg/ffprobe.server'; import { ffprobe } from '~/ffmpeg/ffprobe.server'; import { UPLOAD_AUDIO_FORM_KEY } from '~/forms/upload-audio'; -import { emitAudioFileProcessingEvent } from '~/routes/admin.audio-upload.events'; +import { emitAudioFileProcessingEvent } from '~/sse.server/audio-file-events'; const GIGABYTE = 1_000_000_000; const MICROSECONDS = 1 / 1_000_000; diff --git a/app/routes/admin.shows.$show_.edit.tsx b/app/routes/admin.shows.$show_.edit.tsx index 4c85632b..a763c817 100644 --- a/app/routes/admin.shows.$show_.edit.tsx +++ b/app/routes/admin.shows.$show_.edit.tsx @@ -10,7 +10,8 @@ import { validationError } from 'remix-validated-form'; import { redirectToLogin } from '~/auth/redirect-to-login.server'; import { db } from '~/db/db.server'; -import { EditShowForm, makeServerValidator } from '~/forms/show'; +import { EditShowForm } from '~/forms/show/forms'; +import { makeServerValidator } from '~/forms/show/validator.server'; import { replaceNullsWithUndefined } from '~/forms/utils/replaceNullsWithUndefined'; import { replaceUndefinedsWithNull } from '~/forms/utils/replaceUndefinedsWithNull'; diff --git a/app/routes/admin.shows.new.tsx b/app/routes/admin.shows.new.tsx index 4eb8011d..b33d99b2 100644 --- a/app/routes/admin.shows.new.tsx +++ b/app/routes/admin.shows.new.tsx @@ -9,7 +9,8 @@ import { validationError } from 'remix-validated-form'; import { redirectToLogin } from '~/auth/redirect-to-login.server'; import { db } from '~/db/db.server'; -import { makeServerValidator, NewShowForm } from '~/forms/show'; +import { NewShowForm } from '~/forms/show/forms'; +import { makeServerValidator } from '~/forms/show/validator.server'; export const meta: MetaFunction = () => [ { title: 'New show | Festival admin' }, diff --git a/app/routes/admin.tsx b/app/routes/admin.tsx index 84ac23f9..b1bc5060 100644 --- a/app/routes/admin.tsx +++ b/app/routes/admin.tsx @@ -1,16 +1,12 @@ +import '~/styles/admin.css'; + import { UserButton } from '@clerk/remix'; -import type { LinksFunction, MetaFunction } from '@remix-run/node'; +import type { MetaFunction } from '@remix-run/node'; import { Outlet } from '@remix-run/react'; import type { FC } from 'react'; -import adminStylesUrl from '~/styles/admin.css'; - export const meta: MetaFunction = () => [{ title: 'Festival admin' }]; -export const links: LinksFunction = () => [ - { rel: 'stylesheet', href: adminStylesUrl }, -]; - const Admin: FC = () => { return ( <> diff --git a/app/sse/admin-events.server.ts b/app/sse.server/admin-events.ts similarity index 100% rename from app/sse/admin-events.server.ts rename to app/sse.server/admin-events.ts diff --git a/app/sse.server/audio-file-events.ts b/app/sse.server/audio-file-events.ts new file mode 100644 index 00000000..b6a48ed9 --- /dev/null +++ b/app/sse.server/audio-file-events.ts @@ -0,0 +1,16 @@ +import type { Prisma } from '@prisma/client'; +import type { SerializeFrom } from '@remix-run/node'; + +import { dispatchAdminEvent } from './admin-events'; + +export type AudioFileUploadEvent = SerializeFrom< + Prisma.AudioFileUploadGetPayload<{ + include: { audioFile: true }; + }> +>; + +export const AUDIO_FILE_EVENT_TYPE = 'audio file processing'; + +export function emitAudioFileProcessingEvent(data: AudioFileUploadEvent) { + dispatchAdminEvent(AUDIO_FILE_EVENT_TYPE, data); +} diff --git a/env.d.ts b/env.d.ts new file mode 100644 index 00000000..11f02fe2 --- /dev/null +++ b/env.d.ts @@ -0,0 +1 @@ +/// diff --git a/package-lock.json b/package-lock.json index d979f06f..a63c5a20 100644 --- a/package-lock.json +++ b/package-lock.json @@ -56,7 +56,9 @@ "stylelint-config-standard": "36.0.0", "stylelint-order": "6.0.4", "typescript": "5.4.3", - "use-deep-compare": "1.2.1" + "use-deep-compare": "1.2.1", + "vite": "5.2.7", + "vite-tsconfig-paths": "4.3.2" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -6801,6 +6803,12 @@ "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", "dev": true }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -12862,6 +12870,26 @@ "typescript": ">=4.2.0" } }, + "node_modules/tsconfck": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.0.3.tgz", + "integrity": "sha512-4t0noZX9t6GcPTfBAbIbbIU4pfpCwh0ueq3S4O/5qXI1VwK1outmxhe9dOiEWqMz3MW2LKgDTpqWV+37IWuVbA==", + "dev": true, + "bin": { + "tsconfck": "bin/tsconfck.js" + }, + "engines": { + "node": "^18 || >=20" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/tsconfig-paths": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", @@ -13488,6 +13516,25 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/vite-tsconfig-paths": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-4.3.2.tgz", + "integrity": "sha512-0Vd/a6po6Q+86rPlntHye7F31zA2URZMbH8M3saAZ/xR9QoGN/L21bxEGfXdWmFdNkqPpRdxFT7nmNe12e9/uA==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "globrex": "^0.1.2", + "tsconfck": "^3.0.3" + }, + "peerDependencies": { + "vite": "*" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, "node_modules/vite/node_modules/@esbuild/android-arm": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", diff --git a/package.json b/package.json index c2bb38b3..52289c5c 100644 --- a/package.json +++ b/package.json @@ -7,11 +7,12 @@ "type": "git", "url": "git+https://github.com/stephenwade/festival.git" }, + "type": "module", "scripts": { "prepare": "husky; prisma generate", - "build": "remix build", - "dev": "remix dev", - "start": "remix-serve ./build/index.js", + "dev": "remix vite:dev", + "build": "remix vite:build", + "start": "remix-serve ./build/server/index.js", "lint:eslint": "eslint . --ignore-path .gitignore --max-warnings 0", "lint:stylelint": "stylelint \"**/*.css\" --ignore-path .gitignore --max-warnings 0", "lint:prettier": "prettier . --check --ignore-path .gitignore --log-level warn", @@ -73,7 +74,9 @@ "stylelint-config-standard": "36.0.0", "stylelint-order": "6.0.4", "typescript": "5.4.3", - "use-deep-compare": "1.2.1" + "use-deep-compare": "1.2.1", + "vite": "5.2.7", + "vite-tsconfig-paths": "4.3.2" }, "lint-staged": { "*.css": "stylelint --fix", diff --git a/playwright-ct.config.ts b/playwright-ct.config.ts index e769dc3c..a17d60be 100644 --- a/playwright-ct.config.ts +++ b/playwright-ct.config.ts @@ -21,7 +21,7 @@ export default defineConfig({ resolve: { // Match "paths" in tsconfig.json alias: { - '~': resolve(__dirname, 'app'), + '~': resolve(import.meta.dirname, 'app'), }, }, }, diff --git a/playwright.config.ts b/playwright.config.ts index b87961f8..2a14885a 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -24,7 +24,9 @@ export default defineConfig({ }, webServer: { - command: ['npx prisma migrate dev', 'npx remix dev'].join(' && '), + command: ['npx prisma migrate dev', 'npm run build', 'npm run start'].join( + ' && ', + ), url: `${baseURL}/admin`, reuseExistingServer: !process.env.CI, env: { diff --git a/remix.config.js b/remix.config.js deleted file mode 100644 index d3fdad61..00000000 --- a/remix.config.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * @type {import('@remix-run/dev').AppConfig} - */ -module.exports = { - ignoredRouteFiles: ['**/.*'], - serverDependenciesToBundle: [ - 'remix-utils/sse/server', - 'use-local-storage-state', - ], - serverModuleFormat: 'cjs', -}; diff --git a/remix.env.d.ts b/remix.env.d.ts deleted file mode 100644 index dcf8c45e..00000000 --- a/remix.env.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -/// -/// diff --git a/stylelint.config.js b/stylelint.config.js index 19995885..c92451d7 100644 --- a/stylelint.config.js +++ b/stylelint.config.js @@ -1,4 +1,4 @@ -module.exports = { +export default { extends: ['stylelint-config-standard', 'stylelint-config-hudochenkov/order'], rules: { 'declaration-property-value-no-unknown': true, diff --git a/tsconfig.json b/tsconfig.json index 0f77a1a2..c193305c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,17 +1,12 @@ { - "include": [ - "remix.env.d.ts", - ".eslintrc.js", - "**/*.js", - "**/*.ts", - "**/*.tsx" - ], - "exclude": ["build", "public/build"], + "include": ["env.d.ts", ".eslintrc.cjs", "**/*.js", "**/*.ts", "**/*.tsx"], + "exclude": ["build"], "compilerOptions": { "lib": ["DOM", "DOM.Iterable", "ES2020"], "isolatedModules": true, "esModuleInterop": true, "jsx": "react-jsx", + "module": "esnext", "moduleResolution": "bundler", "resolveJsonModule": true, "target": "ES2020", diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 00000000..9bded3f1 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,13 @@ +import { vitePlugin as remix } from '@remix-run/dev'; +import dotenv from 'dotenv'; +import { defineConfig } from 'vite'; +import tsconfigPaths from 'vite-tsconfig-paths'; + +dotenv.config(); + +export default defineConfig({ + plugins: [tsconfigPaths(), remix()], + server: { + port: Number(process.env.PORT), + }, +});