Skip to content

Commit

Permalink
feat: upgrade to Remix v2
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelDeBoey committed Sep 6, 2023
1 parent 20dacf5 commit e3ec03f
Show file tree
Hide file tree
Showing 9 changed files with 38 additions and 132 deletions.
4 changes: 2 additions & 2 deletions app/routes/_index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { V2_MetaFunction } from "@remix-run/node";
import type { MetaFunction } from "@remix-run/node";
import { Link } from "@remix-run/react";

import { useOptionalUser } from "~/utils";

export const meta: V2_MetaFunction = () => [{ title: "Remix Notes" }];
export const meta: MetaFunction = () => [{ title: "Remix Notes" }];

export default function Index() {
const user = useOptionalUser();
Expand Down
4 changes: 2 additions & 2 deletions app/routes/join.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ActionArgs, LoaderArgs, V2_MetaFunction } from "@remix-run/node";
import type { ActionArgs, LoaderArgs, MetaFunction } from "@remix-run/node";

Check failure on line 1 in app/routes/join.tsx

View workflow job for this annotation

GitHub Actions / ʦ TypeScript

Module '"@remix-run/node"' has no exported member 'ActionArgs'.

Check failure on line 1 in app/routes/join.tsx

View workflow job for this annotation

GitHub Actions / ʦ TypeScript

Module '"@remix-run/node"' has no exported member 'LoaderArgs'.
import { json, redirect } from "@remix-run/node";
import { Form, Link, useActionData, useSearchParams } from "@remix-run/react";
import { useEffect, useRef } from "react";
Expand Down Expand Up @@ -63,7 +63,7 @@ export const action = async ({ request }: ActionArgs) => {
});
};

export const meta: V2_MetaFunction = () => [{ title: "Sign Up" }];
export const meta: MetaFunction = () => [{ title: "Sign Up" }];

export default function Join() {
const [searchParams] = useSearchParams();
Expand Down
4 changes: 2 additions & 2 deletions app/routes/login.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ActionArgs, LoaderArgs, V2_MetaFunction } from "@remix-run/node";
import type { ActionArgs, LoaderArgs, MetaFunction } from "@remix-run/node";

Check failure on line 1 in app/routes/login.tsx

View workflow job for this annotation

GitHub Actions / ʦ TypeScript

Module '"@remix-run/node"' has no exported member 'ActionArgs'.

Check failure on line 1 in app/routes/login.tsx

View workflow job for this annotation

GitHub Actions / ʦ TypeScript

Module '"@remix-run/node"' has no exported member 'LoaderArgs'.
import { json, redirect } from "@remix-run/node";
import { Form, Link, useActionData, useSearchParams } from "@remix-run/react";
import { useEffect, useRef } from "react";
Expand Down Expand Up @@ -58,7 +58,7 @@ export const action = async ({ request }: ActionArgs) => {
});
};

export const meta: V2_MetaFunction = () => [{ title: "Login" }];
export const meta: MetaFunction = () => [{ title: "Login" }];

export default function LoginPage() {
const [searchParams] = useSearchParams();
Expand Down
4 changes: 2 additions & 2 deletions cypress/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
"types": ["node", "cypress", "@testing-library/cypress"],
"esModuleInterop": true,
"jsx": "react-jsx",
"moduleResolution": "node",
"target": "es2019",
"moduleResolution": "Bundler",
"target": "ES2020",
"strict": true,
"skipLibCheck": true,
"resolveJsonModule": true,
Expand Down
14 changes: 7 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@
"dependencies": {
"@isaacs/express-prometheus-middleware": "^1.2.1",
"@prisma/client": "^4.16.2",
"@remix-run/css-bundle": "*",
"@remix-run/express": "*",
"@remix-run/node": "*",
"@remix-run/react": "*",
"@remix-run/css-bundle": "^2.0.0-pre.8",
"@remix-run/express": "^2.0.0-pre.8",
"@remix-run/node": "^2.0.0-pre.8",
"@remix-run/react": "^2.0.0-pre.8",
"bcryptjs": "^2.4.3",
"chokidar": "^3.5.3",
"compression": "^1.7.4",
Expand All @@ -54,8 +54,8 @@
},
"devDependencies": {
"@faker-js/faker": "^8.0.2",
"@remix-run/dev": "*",
"@remix-run/eslint-config": "*",
"@remix-run/dev": "^2.0.0-pre.8",
"@remix-run/eslint-config": "^2.0.0-pre.8",
"@testing-library/cypress": "^9.0.0",
"@testing-library/jest-dom": "^5.17.0",
"@types/bcryptjs": "^2.4.2",
Expand Down Expand Up @@ -96,7 +96,7 @@
"vitest": "^0.34.2"
},
"engines": {
"node": ">=14.0.0"
"node": ">=18.0.0"
},
"prisma": {
"seed": "ts-node --esm --require tsconfig-paths/register prisma/seed.ts"
Expand Down
13 changes: 1 addition & 12 deletions remix.config.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,5 @@
/** @type {import('@remix-run/dev').AppConfig} */
export default {
cacheDirectory: "./node_modules/.cache/remix",
future: {
v2_dev: true,
v2_errorBoundary: true,
v2_headers: true,
v2_meta: true,
v2_normalizeFormMethod: true,
v2_routeConvention: true,
},
ignoredRouteFiles: ["**/.*", "**/*.test.{js,jsx,ts,tsx}"],
postcss: true,
serverModuleFormat: "esm",
tailwind: true,
ignoredRouteFiles: ["**/.*", "**/*.test.{ts,tsx}"],
};
116 changes: 17 additions & 99 deletions remix.init/index.js
Original file line number Diff line number Diff line change
@@ -1,47 +1,22 @@
const { execSync } = require("child_process");
const crypto = require("crypto");
const fs = require("fs/promises");
const path = require("path");
const { execSync } = require("node:child_process");
const crypto = require("node:crypto");
const fs = require("node:fs/promises");
const path = require("node:path");

const toml = require("@iarna/toml");
const PackageJson = require("@npmcli/package-json");
const semver = require("semver");
const YAML = require("yaml");

const cleanupCypressFiles = ({ fileEntries, isTypeScript, packageManager }) =>
const cleanupCypressFiles = ({ fileEntries, packageManager }) =>
fileEntries.flatMap(([filePath, content]) => {
let newContent = content.replace(
const newContent = content.replace(
new RegExp("npx ts-node", "g"),
isTypeScript ? `${packageManager.exec} ts-node` : "node",
`${packageManager.exec} ts-node`,
);

if (!isTypeScript) {
newContent = newContent
.replace(new RegExp("create-user.ts", "g"), "create-user.js")
.replace(new RegExp("delete-user.ts", "g"), "delete-user.js");
}

return [fs.writeFile(filePath, newContent)];
});

const cleanupDeployWorkflow = (deployWorkflow, deployWorkflowPath) => {
delete deployWorkflow.jobs.typecheck;
deployWorkflow.jobs.deploy.needs = deployWorkflow.jobs.deploy.needs.filter(
(need) => need !== "typecheck",
);

return [fs.writeFile(deployWorkflowPath, YAML.stringify(deployWorkflow))];
};

const cleanupVitestConfig = (vitestConfig, vitestConfigPath) => {
const newVitestConfig = vitestConfig.replace(
"setup-test-env.ts",
"setup-test-env.js",
);

return [fs.writeFile(vitestConfigPath, newVitestConfig)];
};

const escapeRegExp = (string) =>
// $& means the whole matched string
string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
Expand Down Expand Up @@ -81,31 +56,19 @@ const getPackageManagerVersion = (packageManager) =>

const getRandomString = (length) => crypto.randomBytes(length).toString("hex");

const readFileIfNotTypeScript = (
isTypeScript,
filePath,
parseFunction = (result) => result,
) =>
isTypeScript
? Promise.resolve()
: fs.readFile(filePath, "utf-8").then(parseFunction);

const removeUnusedDependencies = (dependencies, unusedDependencies) =>
Object.fromEntries(
Object.entries(dependencies).filter(
([key]) => !unusedDependencies.includes(key),
),
);

const updatePackageJson = ({ APP_NAME, isTypeScript, packageJson }) => {
const updatePackageJson = ({ APP_NAME, packageJson }) => {
const {
devDependencies,
prisma: { seed: prismaSeed, ...prisma },
scripts: {
"format:repo": _repoFormatScript,
"lint:repo": _repoLintScript,
typecheck,
validate,
...scripts
},
} = packageJson.content;
Expand All @@ -115,55 +78,29 @@ const updatePackageJson = ({ APP_NAME, isTypeScript, packageJson }) => {
devDependencies: removeUnusedDependencies(
devDependencies,
// packages that are only used for linting the repo
["eslint-plugin-markdown", "eslint-plugin-prefer-let"].concat(
isTypeScript ? [] : ["ts-node"],
),
["eslint-plugin-markdown", "eslint-plugin-prefer-let"],
),
prisma: isTypeScript
? { ...prisma, seed: prismaSeed }
: {
...prisma,
seed: prismaSeed
.replace("ts-node", "node")
.replace("seed.ts", "seed.js"),
},
scripts: isTypeScript
? { ...scripts, typecheck, validate }
: { ...scripts, validate: validate.replace(" typecheck", "") },
scripts,
});
};

const main = async ({ isTypeScript, packageManager, rootDirectory }) => {
const main = async ({ packageManager, rootDirectory }) => {
const pm = getPackageManagerCommand(packageManager);
const FILE_EXTENSION = isTypeScript ? "ts" : "js";

const README_PATH = path.join(rootDirectory, "README.md");
const FLY_TOML_PATH = path.join(rootDirectory, "fly.toml");
const EXAMPLE_ENV_PATH = path.join(rootDirectory, ".env.example");
const ENV_PATH = path.join(rootDirectory, ".env");
const DEPLOY_WORKFLOW_PATH = path.join(
rootDirectory,
".github",
"workflows",
"deploy.yml",
);
const DOCKERFILE_PATH = path.join(rootDirectory, "Dockerfile");
const CYPRESS_SUPPORT_PATH = path.join(rootDirectory, "cypress", "support");
const CYPRESS_COMMANDS_PATH = path.join(
CYPRESS_SUPPORT_PATH,
`commands.${FILE_EXTENSION}`,
);
const CYPRESS_COMMANDS_PATH = path.join(CYPRESS_SUPPORT_PATH, "commands.ts");
const CREATE_USER_COMMAND_PATH = path.join(
CYPRESS_SUPPORT_PATH,
`create-user.${FILE_EXTENSION}`,
"create-user.ts",
);
const DELETE_USER_COMMAND_PATH = path.join(
CYPRESS_SUPPORT_PATH,
`delete-user.${FILE_EXTENSION}`,
);
const VITEST_CONFIG_PATH = path.join(
rootDirectory,
`vitest.config.${FILE_EXTENSION}`,
"delete-user.ts",
);

const REPLACER = "blues-stack-template";
Expand All @@ -183,8 +120,6 @@ const main = async ({ isTypeScript, packageManager, rootDirectory }) => {
cypressCommands,
createUserCommand,
deleteUserCommand,
deployWorkflow,
vitestConfig,
packageJson,
] = await Promise.all([
fs.readFile(FLY_TOML_PATH, "utf-8"),
Expand All @@ -194,10 +129,6 @@ const main = async ({ isTypeScript, packageManager, rootDirectory }) => {
fs.readFile(CYPRESS_COMMANDS_PATH, "utf-8"),
fs.readFile(CREATE_USER_COMMAND_PATH, "utf-8"),
fs.readFile(DELETE_USER_COMMAND_PATH, "utf-8"),
readFileIfNotTypeScript(isTypeScript, DEPLOY_WORKFLOW_PATH, (s) =>
YAML.parse(s),
),
readFileIfNotTypeScript(isTypeScript, VITEST_CONFIG_PATH),
PackageJson.load(rootDirectory),
]);

Expand Down Expand Up @@ -231,9 +162,9 @@ const main = async ({ isTypeScript, packageManager, rootDirectory }) => {
)
: dockerfile;

updatePackageJson({ APP_NAME, isTypeScript, packageJson });
updatePackageJson({ APP_NAME, packageJson });

const fileOperationPromises = [
await Promise.all([
fs.writeFile(FLY_TOML_PATH, toml.stringify(prodToml)),
fs.writeFile(README_PATH, newReadme),
fs.writeFile(ENV_PATH, newEnv),
Expand All @@ -244,7 +175,6 @@ const main = async ({ isTypeScript, packageManager, rootDirectory }) => {
[CREATE_USER_COMMAND_PATH, createUserCommand],
[DELETE_USER_COMMAND_PATH, deleteUserCommand],
],
isTypeScript,
packageManager: pm,
}),
packageJson.save(),
Expand All @@ -262,19 +192,7 @@ const main = async ({ isTypeScript, packageManager, rootDirectory }) => {
fs.rm(path.join(rootDirectory, ".github", "PULL_REQUEST_TEMPLATE.md")),
fs.rm(path.join(rootDirectory, ".eslintrc.repo.cjs")),
fs.rm(path.join(rootDirectory, "LICENSE.md")),
];

if (!isTypeScript) {
fileOperationPromises.push(
...cleanupDeployWorkflow(deployWorkflow, DEPLOY_WORKFLOW_PATH),
);

fileOperationPromises.push(
...cleanupVitestConfig(vitestConfig, VITEST_CONFIG_PATH),
);
}

await Promise.all(fileOperationPromises);
]);

execSync(pm.run("format", "--loglevel warn"), {
cwd: rootDirectory,
Expand Down
5 changes: 2 additions & 3 deletions remix.init/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
"license": "MIT",
"dependencies": {
"@iarna/toml": "^2.2.5",
"@npmcli/package-json": "^2.0.0",
"semver": "^7.5.4",
"yaml": "^2.3.1"
"@npmcli/package-json": "^5.0.0",
"semver": "^7.5.4"
}
}
6 changes: 3 additions & 3 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
"exclude": ["./cypress", "./cypress.config.ts"],
"include": ["remix.env.d.ts", "**/*.ts", "**/*.tsx"],
"compilerOptions": {
"lib": ["DOM", "DOM.Iterable", "ES2019"],
"lib": ["DOM", "DOM.Iterable", "ES2020"],
"types": ["vitest/globals"],
"isolatedModules": true,
"esModuleInterop": true,
"jsx": "react-jsx",
"module": "ES2020",
"moduleResolution": "node",
"moduleResolution": "Bundler",
"resolveJsonModule": true,
"target": "ES2019",
"target": "ES2020",
"strict": true,
"allowJs": true,
"forceConsistentCasingInFileNames": true,
Expand Down

0 comments on commit e3ec03f

Please sign in to comment.