Skip to content

Commit

Permalink
feat: remove all TypeScript references when isTypeScript is passed …
Browse files Browse the repository at this point in the history
…as `false` to `remix.init`
  • Loading branch information
MichaelDeBoey committed May 27, 2022
1 parent 643aa82 commit 5fab3b9
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 31 deletions.
5 changes: 3 additions & 2 deletions cypress/support/create-user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
// and it will log out the cookie value you can use to interact with the server
// as that new user.

import { parse } from "cookie";
import { installGlobals } from "@remix-run/node/globals";
import { createUserSession } from "~/session.server";
import { parse } from "cookie";

import { createUser } from "~/models/user.server";
import { createUserSession } from "~/session.server";

installGlobals();

Expand Down
1 change: 1 addition & 0 deletions cypress/support/delete-user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// and that user will get deleted

import { installGlobals } from "@remix-run/node/globals";

import { prisma } from "~/db.server";

installGlobals();
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
"tsconfig-paths": "^4.0.0",
"typescript": "^4.6.4",
"vite": "^2.9.9",
"vite-tsconfig-paths": "^3.4.1",
"vite-tsconfig-paths": "^3.5.0",
"vitest": "^0.12.8"
},
"engines": {
Expand Down
149 changes: 124 additions & 25 deletions remix.init/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,78 @@ const { execSync } = require("child_process");
const crypto = require("crypto");
const fs = require("fs/promises");
const path = require("path");
const inquirer = require("inquirer");

const toml = require("@iarna/toml");
const sort = require("sort-package-json");
const PackageJson = require("@npmcli/package-json");
const inquirer = require("inquirer");

const cleanupCypressFiles = (filesEntries) =>
filesEntries.flatMap(([filePath, content]) => {
const newContent = content
.replace(
"npx ts-node --require tsconfig-paths/register ./cypress/support/create-user.ts",
"node --require tsconfig-paths/register ./cypress/support/create-user.js"
)
.replace(
"npx ts-node --require tsconfig-paths/register ./cypress/support/delete-user.ts",
"node --require tsconfig-paths/register ./cypress/support/delete-user.js"
);

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

const cleanupJSConfig = (jsConfig, jsConfigPath) => {
const newJSConfig = jsConfig.replace(
'"include": ["remix.env.d.ts", "**/*.ts", "**/*.tsx"]',
'"include": ["**/*.js", "**/*.jsx"]'
);

return [fs.writeFile(jsConfigPath, newJSConfig)];
};

function escapeRegExp(string) {
const escapeRegExp = (string) =>
// $& means the whole matched string
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");

function getRandomString(length) {
return crypto.randomBytes(length).toString("hex");
}
const getRandomString = (length) => crypto.randomBytes(length).toString("hex");

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

async function main({ rootDirectory }) {
const replaceVitestConfig = (rootDirectory) => {
// We renamed this during `create-remix`.
// Instead of reading this file and changing it,
// we have a copy of it in this directory already set up for JavaScript
const VITEST_CONFIG_NAME = "vitest.config.js";

return [
fs.copyFile(
path.join(rootDirectory, "remix.init", VITEST_CONFIG_NAME),
path.join(rootDirectory, VITEST_CONFIG_NAME)
),
];
};

const main = async ({ isTypeScript, rootDirectory }) => {
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 PACKAGE_JSON_PATH = path.join(rootDirectory, "package.json");
const JSCONFIG_PATH = path.join(rootDirectory, "jsconfig.json"); // We renamed this during `create-remix`
const CYPRESS_SUPPORT_PATH = path.join(rootDirectory, "cypress", "support");
const CYPRESS_COMMANDS_PATH = path.join(CYPRESS_SUPPORT_PATH, "commands.js"); // We renamed this during `create-remix`
const CREATE_USER_COMMAND_PATH = path.join(
CYPRESS_SUPPORT_PATH,
"create-user.js"
); // We renamed this during `create-remix`
const DELETE_USER_COMMAND_PATH = path.join(
CYPRESS_SUPPORT_PATH,
"delete-user.js"
); // We renamed this during `create-remix`

const REPLACER = "indie-stack-template";

Expand All @@ -32,11 +84,30 @@ async function main({ rootDirectory }) {
// get rid of anything that's not allowed in an app name
.replace(/[^a-zA-Z0-9-_]/g, "-");

const [prodContent, readme, env, packageJson] = await Promise.all([
const [
prodContent,
readme,
env,
jsConfig,
cypressCommands,
createUserCommand,
deleteUserCommand,
packageJson,
] = await Promise.all([
fs.readFile(FLY_TOML_PATH, "utf-8"),
fs.readFile(README_PATH, "utf-8"),
fs.readFile(EXAMPLE_ENV_PATH, "utf-8"),
fs.readFile(PACKAGE_JSON_PATH, "utf-8"),
isTypeScript ? Promise.resolve() : fs.readFile(JSCONFIG_PATH, "utf-8"),
isTypeScript
? Promise.resolve()
: fs.readFile(CYPRESS_COMMANDS_PATH, "utf-8"),
isTypeScript
? Promise.resolve()
: fs.readFile(CREATE_USER_COMMAND_PATH, "utf-8"),
isTypeScript
? Promise.resolve()
: fs.readFile(DELETE_USER_COMMAND_PATH, "utf-8"),
PackageJson.load(rootDirectory),
]);

const newEnv = env.replace(
Expand All @@ -52,27 +123,55 @@ async function main({ rootDirectory }) {
APP_NAME
);

const newPackageJson =
JSON.stringify(
sort({ ...JSON.parse(packageJson), name: APP_NAME }),
null,
2
) + "\n";

await Promise.all([
const {
devDependencies,
prisma,
scripts: { typecheck, validate, ...scripts },
} = packageJson.content;
packageJson.update({
name: APP_NAME,
devDependencies: isTypeScript
? devDependencies
: removeUnusedDependencies(devDependencies, [
"ts-node",
"vite-tsconfig-paths",
]),
prisma: isTypeScript ? prisma : { seed: "node prisma/seed.js" },
scripts: isTypeScript
? { ...scripts, typecheck, validate }
: { ...scripts, validate: 'run-p "test -- --run" lint test:e2e:run' },
});

const fileOperationPromises = [
fs.writeFile(FLY_TOML_PATH, toml.stringify(prodToml)),
fs.writeFile(README_PATH, newReadme),
fs.writeFile(ENV_PATH, newEnv),
fs.writeFile(PACKAGE_JSON_PATH, newPackageJson),
packageJson.save(),
fs.copyFile(
path.join(rootDirectory, "remix.init", "gitignore"),
path.join(rootDirectory, ".gitignore")
),
fs.rm(path.join(rootDirectory, ".github/ISSUE_TEMPLATE"), {
fs.rm(path.join(rootDirectory, ".github", "ISSUE_TEMPLATE"), {
recursive: true,
}),
fs.rm(path.join(rootDirectory, ".github/PULL_REQUEST_TEMPLATE.md")),
]);
fs.rm(path.join(rootDirectory, ".github", "PULL_REQUEST_TEMPLATE.md")),
];

if (!isTypeScript) {
fileOperationPromises.push(
...cleanupCypressFiles([
[CYPRESS_COMMANDS_PATH, cypressCommands],
[CREATE_USER_COMMAND_PATH, createUserCommand],
[DELETE_USER_COMMAND_PATH, deleteUserCommand],
])
);

fileOperationPromises.push(...cleanupJSConfig(jsConfig, JSCONFIG_PATH));

fileOperationPromises.push(...replaceVitestConfig(rootDirectory));
}

await Promise.all(fileOperationPromises);

execSync(`npm run setup`, { stdio: "inherit", cwd: rootDirectory });

Expand All @@ -93,7 +192,7 @@ async function main({ rootDirectory }) {
Start development with \`npm run dev\`
`.trim()
);
}
};

async function askSetupQuestions({ rootDirectory }) {
const answers = await inquirer.prompt([
Expand Down
4 changes: 2 additions & 2 deletions remix.init/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"license": "MIT",
"dependencies": {
"@iarna/toml": "^2.2.5",
"inquirer": "^8.2.4",
"sort-package-json": "^1.57.0"
"@npmcli/package-json": "^2.0.0",
"inquirer": "^8.2.4"
}
}
12 changes: 12 additions & 0 deletions remix.init/vitest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const react = require("@vitejs/plugin-react");
const { defineConfig } = require("vite");
const tsconfigPaths = require("vite-tsconfig-paths");

export default defineConfig({
plugins: [react(), tsconfigPaths()],
test: {
globals: true,
environment: "happy-dom",
setupFiles: ["./test/setup-test-env.js"],
},
});
2 changes: 1 addition & 1 deletion vitest.config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/// <reference types="vitest" />
/// <reference types="vite/client" />

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";

export default defineConfig({
Expand Down

0 comments on commit 5fab3b9

Please sign in to comment.