diff --git a/.env.example b/.env.example index 66df29b..930bffd 100644 --- a/.env.example +++ b/.env.example @@ -1,2 +1 @@ -NODE_ENV="development" SESSION_SECRET="super-duper-s3cret" diff --git a/.eslintrc.js b/.eslintrc.cjs similarity index 69% rename from .eslintrc.js rename to .eslintrc.cjs index 484b320..f6b3896 100644 --- a/.eslintrc.js +++ b/.eslintrc.cjs @@ -11,9 +11,9 @@ module.exports = { "cypress/globals": true, }, plugins: ["cypress"], - // we're using vitest which has a very similar API to jest - // (so the linting plugins work nicely), but it we have to explicitly - // set the jest version. + // We're using vitest which has a very similar API to jest + // (so the linting plugins work nicely), but it means we + // have to set the jest version explicitly. settings: { jest: { version: 28, diff --git a/.eslintrc.repo.js b/.eslintrc.repo.cjs similarity index 96% rename from .eslintrc.repo.js rename to .eslintrc.repo.cjs index 67f4896..a3796fa 100644 --- a/.eslintrc.repo.js +++ b/.eslintrc.repo.cjs @@ -6,7 +6,7 @@ const WARN = 1; /** @type {import('eslint').Linter.Config} */ module.exports = { extends: [ - "./.eslintrc.js", + "./.eslintrc.cjs", "@remix-run/eslint-config/internal", "plugin:markdown/recommended", ], diff --git a/.gitignore b/.gitignore index 44412e9..17f1c13 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,9 @@ pnpm-lock.yml node_modules /public/build +/server/index.mjs +/server/index.mjs.map +/server/metafile.* preferences.arc sam.json sam.yaml diff --git a/app.arc b/app.arc index bfdb720..57c421a 100644 --- a/app.arc +++ b/app.arc @@ -1,15 +1,23 @@ @app grunge-stack-template -# @aws -# region us-east-2 +@aws +runtime nodejs16.x +# concurrency 1 +# memory 1152 # profile default +# region us-west-1 +# timeout 30 @http /* method any src server +@plugins +plugin-remix + src plugin-remix.js + @static @tables diff --git a/app/root.tsx b/app/root.tsx index 94c4f8e..ac5c76c 100644 --- a/app/root.tsx +++ b/app/root.tsx @@ -16,8 +16,6 @@ import stylesheet from "~/tailwind.css"; export const links: LinksFunction = () => [ { rel: "stylesheet", href: stylesheet }, ...(cssBundleHref ? [{ rel: "stylesheet", href: cssBundleHref }] : []), - // NOTE: Architect deploys the public directory to /_static/ - { rel: "icon", href: "/_static/favicon.ico" }, ]; export const loader = async ({ request }: LoaderArgs) => { @@ -30,6 +28,7 @@ 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/mocks/index.js b/mocks/index.js index 20c384c..b7782ca 100644 --- a/mocks/index.js +++ b/mocks/index.js @@ -1,6 +1,14 @@ -const { setupServer } = require("msw/node"); +import { rest } from "msw"; +import { setupServer } from "msw/node"; -const server = setupServer(); +// put one-off handlers that don't really need an entire file to themselves here +const miscHandlers = [ + rest.post(`${process.env.REMIX_DEV_HTTP_ORIGIN}/ping`, (req) => + req.passthrough(), + ), +]; + +const server = setupServer(...miscHandlers); server.listen({ onUnhandledRequest: "bypass" }); diff --git a/package.json b/package.json index bca2ecb..d769968 100644 --- a/package.json +++ b/package.json @@ -2,13 +2,15 @@ "name": "grunge-stack-template", "private": true, "sideEffects": false, + "type": "module", "scripts": { "build": "remix build", "dev": "remix dev --manual -c \"arc sandbox -e testing\"", "format": "prettier --write .", "format:repo": "npm run format && npm run lint:repo -- --fix", "lint": "eslint --cache --cache-location ./node_modules/.cache/eslint .", - "lint:repo": "npm run lint -- --config ./.eslintrc.repo.js", + "lint:repo": "npm run lint -- --config ./.eslintrc.repo.cjs", + "start": "cross-env NODE_ENV=production arc sandbox", "test": "vitest", "test:e2e:dev": "start-server-and-test dev http://localhost:3000 \"npx cypress open\"", "test:e2e:run": "cross-env PORT=8811 start-server-and-test dev http://localhost:8811 \"npx cypress run\"", @@ -75,6 +77,6 @@ "vitest": "^0.34.2" }, "engines": { - "node": ">=14" + "node": ">=14.0.0" } } diff --git a/plugin-remix.js b/plugin-remix.js new file mode 100644 index 0000000..21947da --- /dev/null +++ b/plugin-remix.js @@ -0,0 +1,49 @@ +// This should eventually be a npm package, but for now it lives here. +// Its job is to notify the remix dev server of the version of the running +// app to trigger HMR / HDR. + +import * as fs from "node:fs"; +import * as path from "node:path"; + +import { logDevReady } from "@remix-run/node"; + +const buildPath = "server/index.mjs"; + +let lastTimeout; + +export default { + sandbox: { + async watcher() { + if (lastTimeout) { + clearTimeout(lastTimeout); + } + + lastTimeout = setTimeout(async () => { + const contents = fs.readFileSync( + path.resolve(process.cwd(), buildPath), + "utf8" + ); + const manifestMatches = contents.matchAll(/manifest-([A-f0-9]+)\.js/g); + const sent = new Set(); + for (const match of manifestMatches) { + const buildHash = match[1]; + if (!sent.has(buildHash)) { + sent.add(buildHash); + logDevReady({ assets: { version: buildHash } }); + } + } + }, 300); + }, + }, + set: { + env() { + // Pass matching env variables through to the application in dev mode. + const passthruKeys = /^NODE_ENV$|^REMIX_DEV_/; + return { + testing: Object.fromEntries( + Object.entries(process.env).filter(([key]) => passthruKeys.test(key)) + ), + }; + }, + }, +}; diff --git a/postcss.config.js b/postcss.config.cjs similarity index 100% rename from postcss.config.js rename to postcss.config.cjs diff --git a/remix.config.js b/remix.config.js index b2880e6..153f9cc 100644 --- a/remix.config.js +++ b/remix.config.js @@ -1,7 +1,7 @@ -const path = require("path"); +import path from "node:path"; /** @type {import('@remix-run/dev').AppConfig} */ -module.exports = { +export default { cacheDirectory: "./node_modules/.cache/remix", future: { v2_dev: true, @@ -14,22 +14,21 @@ module.exports = { ignoredRouteFiles: ["**/.*", "**/*.test.{js,jsx,ts,tsx}"], publicPath: "/_static/build/", postcss: true, - server: "./server.ts", - serverBuildPath: "server/index.js", - serverModuleFormat: "cjs", + server: "server.ts", + serverBuildPath: "server/index.mjs", + serverModuleFormat: "esm", tailwind: true, - routes(defineRoutes) { - return defineRoutes((route) => { + routes: (defineRoutes) => + defineRoutes((route) => { if (process.env.NODE_ENV === "production") return; console.log("⚠️ Test routes enabled."); - const appDir = path.join(__dirname, "app"); + const appDir = path.join(process.cwd(), "app"); route( "__tests/create-user", path.relative(appDir, "cypress/support/test-routes/create-user.ts"), ); - }); - }, + }), }; diff --git a/remix.init/gitignore b/remix.init/gitignore index cd3da90..be0c7d5 100644 --- a/remix.init/gitignore +++ b/remix.init/gitignore @@ -1,9 +1,9 @@ node_modules -/server/index.js -/server/index.js.map -/server/metafile.* /public/build +/server/index.mjs +/server/index.mjs.map +/server/metafile.* preferences.arc sam.json sam.yaml diff --git a/remix.init/index.js b/remix.init/index.js index 8009282..830f8e0 100644 --- a/remix.init/index.js +++ b/remix.init/index.js @@ -201,7 +201,7 @@ const main = async ({ isTypeScript, packageManager, rootDirectory }) => { fs.rm(path.join(rootDirectory, ".github", "workflows", "no-response.yml")), fs.rm(path.join(rootDirectory, ".github", "dependabot.yml")), fs.rm(path.join(rootDirectory, ".github", "PULL_REQUEST_TEMPLATE.md")), - fs.rm(path.join(rootDirectory, ".eslintrc.repo.js")), + fs.rm(path.join(rootDirectory, ".eslintrc.repo.cjs")), fs.rm(path.join(rootDirectory, "LICENSE.md")), ]; diff --git a/tsconfig.json b/tsconfig.json index 9bacef8..76e38a0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,7 +7,7 @@ "isolatedModules": true, "esModuleInterop": true, "jsx": "react-jsx", - "module": "CommonJS", + "module": "ES2020", "moduleResolution": "node", "resolveJsonModule": true, "target": "ES2019",