diff --git a/.eslintrc.js b/.eslintrc.cjs similarity index 98% rename from .eslintrc.js rename to .eslintrc.cjs index 9381f335..75cecae9 100644 --- a/.eslintrc.js +++ b/.eslintrc.cjs @@ -127,7 +127,7 @@ module.exports = { // Node { - files: [".eslintrc.js", "mocks/**/*.js"], + files: [".eslintrc.cjs", "mocks/**/*.js"], env: { node: true, }, diff --git a/Dockerfile b/Dockerfile index 093ace78..74929254 100644 --- a/Dockerfile +++ b/Dockerfile @@ -52,8 +52,8 @@ WORKDIR /myapp COPY --from=production-deps /myapp/node_modules /myapp/node_modules COPY --from=build /myapp/node_modules/.prisma /myapp/node_modules/.prisma -COPY --from=build /myapp/build /myapp/build -COPY --from=build /myapp/public /myapp/public +COPY --from=build /myapp/build/server /myapp/build/server +COPY --from=build /myapp/build/client /myapp/build/client COPY --from=build /myapp/package.json /myapp/package.json COPY --from=build /myapp/start.sh /myapp/start.sh COPY --from=build /myapp/prisma /myapp/prisma diff --git a/README.md b/README.md index d9895663..d274954c 100644 --- a/README.md +++ b/README.md @@ -176,7 +176,7 @@ This project uses TypeScript. It's recommended to get TypeScript set up for your ### Linting -This project uses ESLint for linting. That is configured in `.eslintrc.js`. +This project uses ESLint for linting. That is configured in `.eslintrc.cjs`. ### Formatting diff --git a/app/root.tsx b/app/root.tsx index 426fac35..88409941 100644 --- a/app/root.tsx +++ b/app/root.tsx @@ -1,9 +1,7 @@ -import { cssBundleHref } from "@remix-run/css-bundle"; -import type { LinksFunction, LoaderFunctionArgs } from "@remix-run/node"; +import type { LoaderFunctionArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Links, - LiveReload, Meta, Outlet, Scripts, @@ -11,12 +9,7 @@ import { } from "@remix-run/react"; import { getUser } from "~/session.server"; -import stylesheet from "~/tailwind.css"; - -export const links: LinksFunction = () => [ - { rel: "stylesheet", href: stylesheet }, - ...(cssBundleHref ? [{ rel: "stylesheet", href: cssBundleHref }] : []), -]; +import "~/tailwind.css"; export const loader = async ({ request }: LoaderFunctionArgs) => { return json({ user: await getUser(request) }); @@ -35,7 +28,6 @@ export default function App() { - ); diff --git a/cypress/.eslintrc.js b/cypress/.eslintrc.cjs similarity index 100% rename from cypress/.eslintrc.js rename to cypress/.eslintrc.cjs diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index 23815c92..a12fc624 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -50,7 +50,7 @@ function login({ } = {}) { cy.then(() => ({ email })).as("user"); cy.exec( - `npx ts-node -r tsconfig-paths/register ./cypress/support/create-user.ts "${email}"`, + `npx vite-node ./cypress/support/create-user.ts "${email}"`, ).then(({ stdout }) => { const cookieValue = stdout .replace(/.*(?.*)<\/cookie>.*/s, "$") @@ -76,7 +76,7 @@ function cleanupUser({ email }: { email?: string } = {}) { function deleteUserByEmail(email: string) { cy.exec( - `npx ts-node -r tsconfig-paths/register ./cypress/support/delete-user.ts "${email}"`, + `npx vite-node ./cypress/support/delete-user.ts "${email}"`, ); cy.clearCookie("__session"); } diff --git a/cypress/support/create-user.ts b/cypress/support/create-user.ts index fa33b948..52b08dbd 100644 --- a/cypress/support/create-user.ts +++ b/cypress/support/create-user.ts @@ -1,6 +1,6 @@ // Use this to create a new user and login with that user // Simply call this with: -// npx ts-node -r tsconfig-paths/register ./cypress/support/create-user.ts username@example.com, +// npx vite-node ./cypress/support/create-user.ts username@example.com, // and it will log out the cookie value you can use to interact with the server // as that new user. diff --git a/cypress/support/delete-user.ts b/cypress/support/delete-user.ts index 13500190..159a01fd 100644 --- a/cypress/support/delete-user.ts +++ b/cypress/support/delete-user.ts @@ -1,6 +1,6 @@ // Use this to delete a user by their email // Simply call this with: -// npx ts-node -r tsconfig-paths/register ./cypress/support/delete-user.ts username@example.com, +// npx vite-node ./cypress/support/delete-user.ts username@example.com, // and that user will get deleted import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library"; diff --git a/remix.env.d.ts b/env.d.ts similarity index 50% rename from remix.env.d.ts rename to env.d.ts index dcf8c45e..8d2f9518 100644 --- a/remix.env.d.ts +++ b/env.d.ts @@ -1,2 +1,2 @@ -/// +/// /// diff --git a/mocks/index.js b/mocks/index.js index ca2210ce..2cbbbe76 100644 --- a/mocks/index.js +++ b/mocks/index.js @@ -1,5 +1,5 @@ -const { http, passthrough } = require("msw"); -const { setupServer } = require("msw/node"); +import { http, passthrough } from "msw"; +import { setupServer } from "msw/node"; // put one-off handlers that don't really need an entire file to themselves here const miscHandlers = [ diff --git a/package.json b/package.json index 5ccca2ec..2cfdf8ac 100644 --- a/package.json +++ b/package.json @@ -2,16 +2,16 @@ "name": "indie-stack-template", "private": true, "sideEffects": false, + "type": "module", "scripts": { - "build": "remix build", - "dev": "remix dev -c \"npm run dev:serve\"", - "dev:serve": "binode --require ./mocks -- @remix-run/serve:remix-serve ./build/index.js", + "build": "remix vite:build", + "dev": "binode --import ./mocks/index.js -- vite:vite dev", "format": "prettier --write .", "format:repo": "npm run format && npm run lint -- --fix", "lint": "eslint --cache --cache-location ./node_modules/.cache/eslint .", "setup": "prisma generate && prisma migrate deploy && prisma db seed", - "start": "remix-serve ./build/index.js", - "start:mocks": "binode --require ./mocks -- @remix-run/serve:remix-serve ./build/index.js", + "start": "dotenv -e .env remix-serve ./build/server/index.js", + "start:mocks": "binode --import ./mocks/index.js -- @remix-run/serve:remix-serve ./build/server/index.js", "test": "vitest", "test:e2e:dev": "start-server-and-test dev http://localhost:3000 \"npx cypress open\"", "pretest:e2e:run": "npm run build", @@ -32,6 +32,7 @@ "@remix-run/react": "*", "@remix-run/serve": "*", "bcryptjs": "^2.4.3", + "dotenv-cli": "^7.3.0", "isbot": "^4.4.0", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -79,10 +80,10 @@ "prisma": "^5.14.0", "start-server-and-test": "^2.0.3", "tailwindcss": "^3.4.3", - "ts-node": "^10.9.2", "tsconfig-paths": "^4.2.0", "typescript": "^5.4.5", "vite": "^5.2.12", + "vite-node": "^1.6.0", "vite-tsconfig-paths": "^4.3.2", "vitest": "^1.6.0" }, @@ -90,6 +91,6 @@ "node": ">=18.0.0" }, "prisma": { - "seed": "ts-node -r tsconfig-paths/register prisma/seed.ts" + "seed": "vite-node prisma/seed.ts" } } diff --git a/postcss.config.js b/postcss.config.js index 12a703d9..2aa7205d 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,4 +1,4 @@ -module.exports = { +export default { plugins: { tailwindcss: {}, autoprefixer: {}, diff --git a/remix.config.js b/remix.config.js deleted file mode 100644 index 29582b29..00000000 --- a/remix.config.js +++ /dev/null @@ -1,6 +0,0 @@ -/** @type {import('@remix-run/dev').AppConfig} */ -module.exports = { - cacheDirectory: "./node_modules/.cache/remix", - ignoredRouteFiles: ["**/.*", "**/*.test.{ts,tsx}"], - serverModuleFormat: "cjs", -}; diff --git a/remix.init/index.js b/remix.init/index.js index 94b1200e..9abac82b 100644 --- a/remix.init/index.js +++ b/remix.init/index.js @@ -10,8 +10,8 @@ const semver = require("semver"); const cleanupCypressFiles = ({ fileEntries, packageManager }) => fileEntries.flatMap(([filePath, content]) => { const newContent = content.replace( - new RegExp("npx ts-node", "g"), - packageManager.name === "bun" ? "bun" : `${packageManager.exec} ts-node`, + new RegExp("npx vite-node", "g"), + packageManager.name === "bun" ? "bun" : `${packageManager.exec} vite-node`, ); return [fs.writeFile(filePath, newContent)]; @@ -87,13 +87,13 @@ const updatePackageJson = ({ APP_NAME, packageJson, packageManager }) => { name: APP_NAME, devDependencies: packageManager.name === "bun" - ? removeUnusedDependencies(devDependencies, ["ts-node"]) + ? removeUnusedDependencies(devDependencies, ["vite-node"]) : devDependencies, prisma: { ...prisma, seed: packageManager.name === "bun" - ? prismaSeed.replace("ts-node", "bun") + ? prismaSeed.replace("vite-node", "bun") : prismaSeed, }, scripts, diff --git a/tsconfig.json b/tsconfig.json index c0a761dd..17738d90 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,16 +1,16 @@ { - "exclude": ["./cypress", "./cypress.config.ts"], - "include": ["remix.env.d.ts", "**/*.ts", "**/*.tsx"], + "exclude": ["./cypress", "cypress.config.ts"], + "include": ["env.d.ts", "**/*.ts", "**/*.tsx", "cypress.config.ts", "cypress/support/e2e.ts"], "compilerOptions": { - "lib": ["DOM", "DOM.Iterable", "ES2020"], + "lib": ["DOM", "DOM.Iterable", "ES2022"], "types": ["vitest/globals"], "isolatedModules": true, "esModuleInterop": true, "jsx": "react-jsx", - "module": "CommonJS", - "moduleResolution": "node", + "module": "ESNext", + "moduleResolution": "Bundler", "resolveJsonModule": true, - "target": "ES2020", + "target": "ES2022", "strict": true, "allowJs": true, "forceConsistentCasingInFileNames": true, diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 00000000..2553996d --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,20 @@ +/// +/// +import { vitePlugin as remix } from "@remix-run/dev"; +import { installGlobals } from "@remix-run/node"; +import { defineConfig } from "vite"; +import tsconfigPaths from "vite-tsconfig-paths"; + +installGlobals(); + +export default defineConfig({ + server: { + port: 3000, + }, + plugins: [ + remix({ + ignoredRouteFiles: ["**/.*", "**/*.test.{ts,tsx}"], + }), + tsconfigPaths(), + ], +});