Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add nx to the repo #65

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@ node_modules
/postgres-data

/app/styles/tailwind.css

/.idea
Comment on lines +19 to +20
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

31 changes: 31 additions & 0 deletions nx.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"extends": "nx/presets/core.json",
"npmScope": "remix",
"tasksRunnerOptions": {
"default": {
"runner": "nx/tasks-runners/default",
"options": {
"cacheableOperations": [
"build-all",
"validate-all",
"build:css",
"build:remix",
"build:server",
"typecheck",
"test:run",
"lint",
"test:e2e:run"
]
}
}
},
"cli": {
"defaultProjectName": "blues-stack-template"
},
"pluginsConfig": {
"@nrwl/js": {
"analyzeSourceFiles": false,
"analyzePackageJson": false
}
}
}
44 changes: 39 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@
"license": "",
"sideEffects": false,
"scripts": {
"build": "run-s build:*",
"build:css": "npm run generate:css -- --minify",
"build:remix": "remix build",
"build:server": "esbuild --platform=node --format=cjs ./server.ts --outdir=build",
"dev": "run-p dev:*",
"dev:server": "cross-env NODE_ENV=development node --inspect --require ./node_modules/dotenv/config --require ./mocks ./build/server.js",
"dev:build": "cross-env NODE_ENV=development npm run build:server -- --watch",
"dev:remix": "cross-env NODE_ENV=development remix watch",
Expand All @@ -22,11 +20,13 @@
"start": "cross-env NODE_ENV=production node ./build/server.js",
"start:mocks": "cross-env NODE_ENV=production node --require ./mocks --require dotenv/config ./build/server.js",
"test": "vitest",
"test:run": "vitest --run",
"test:e2e:dev": "start-server-and-test dev http://localhost:3000 \"cypress open\"",
"pretest:e2e:run": "npm run build",
"test:e2e:run": "cross-env PORT=8811 start-server-and-test start:mocks http://localhost:8811 \"cypress run\"",
"typecheck": "tsc -b && tsc -b cypress",
"validate": "run-p \"test -- --run\" lint typecheck test:e2e:run"
"build": "nx build-all --output-style=compact",
"dev": "nx build-all --output-style=compact && nx dev-all",
"validate": "nx validate-all --output-style=compact"
},
"prettier": {},
"eslintIgnore": [
Expand Down Expand Up @@ -76,7 +76,7 @@
"eslint-config-prettier": "^8.5.0",
"happy-dom": "^2.55.0",
"msw": "^0.39.2",
"npm-run-all": "^4.1.5",
"nx": "14.1.4",
"postcss": "^8.4.12",
"prettier": "^2.6.1",
"prettier-plugin-tailwindcss": "^0.1.8",
Expand All @@ -95,5 +95,39 @@
},
"prisma": {
"seed": "ts-node --require tsconfig-paths/register prisma/seed.ts"
},
"nx": {
"targets": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vsavkin If I'm correct, this can be in the nx.json/project.json file as well?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. If we're going to have the other config files then let's keep all config in those files.

"build:remix": {
"outputs": [
"/build/index.js",
"/public/build"
]
},
"build:server": {
"outputs": [
"/build/server.js"
]
},
"build:css": {
"outputs": [
"/app/styles/tailwind.css"
]
},
"test:e2e:run": {
"outputs": [
"/cypress/screenshots",
"/cypress/videos"
],
"dependsOn": [
"build-all"
]
},
"test:e2e:dev": {
"dependsOn": [
"build-all"
]
}
}
}
}
40 changes: 40 additions & 0 deletions project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "blues-stack-template",
"targets": {
"dev-all": {
"executor": "nx:run-commands",
"options": {
"commands": [
{
"command": "nx dev:server blues-stack-template",
"prefix": "[SERVER]",
"color": "blue"
},
{
"command": "nx dev:build blues-stack-template",
"prefix": "[BUILD-]",
"color": "green"
},
{
"command": "nx dev:remix blues-stack-template",
"prefix": "[REMIX-]",
"color": "yellow"
},
{
"command": "nx dev:css blues-stack-template",
"prefix": "[CSS---]",
"color": "cyan"
}
]
}
},
"validate-all": {
"executor": "nx:noop",
"dependsOn": ["test:run", "lint", "typecheck", "test:e2e:run"]
},
"build-all": {
"executor": "nx:noop",
"dependsOn": ["build:css", "build:remix", "build:server"]
}
}
}
95 changes: 39 additions & 56 deletions remix.init/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,75 +2,58 @@ const crypto = require("crypto");
const fs = require("fs/promises");
const path = require("path");

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

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

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

async function main({ 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 REPLACER = "blues-stack-template";

const DIR_NAME = path.basename(rootDirectory);
const SUFFIX = getRandomString(2);

const APP_NAME = (DIR_NAME + "-" + SUFFIX)
const APP_NAME = path.basename(rootDirectory);
const APP_ID = (APP_NAME + "-" + getRandomString(2))
// 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([
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"),
]);
// copy files
const filesToCopy = [["remix.init/gitignore", ".gitignore"]];
for (const [from, to] of filesToCopy) {
await fs.copyFile(
path.join(rootDirectory, from),
path.join(rootDirectory, to)
);
}

// update env to have SESSION_SECRET
const EXAMPLE_ENV_PATH = path.join(rootDirectory, ".env.example");
const ENV_PATH = path.join(rootDirectory, ".env");
const env = await fs.readFile(EXAMPLE_ENV_PATH, "utf-8");
const newEnv = env.replace(
/^SESSION_SECRET=.*$/m,
`SESSION_SECRET="${getRandomString(16)}"`
);

const prodToml = toml.parse(prodContent);
prodToml.app = prodToml.app.replace(REPLACER, APP_NAME);

const newReadme = readme.replace(
new RegExp(escapeRegExp(REPLACER), "g"),
APP_NAME
);

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

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

// delete files only needed for the template
const filesToDelete = [
".github/ISSUE_TEMPLATE",
".github/PULL_REQUEST_TEMPLATE.md",
];
for (const file of filesToDelete) {
await fs.rm(path.join(rootDirectory, file), { recursive: true });
}

// replace "blues-stack-template" in all files with the app name
const filesToReplaceIn = [
"README.md",
"package.json",
"fly.toml",
"project.json",
"nx.json",
];
for (const file of filesToReplaceIn) {
const filePath = path.join(rootDirectory, file);
const contents = await fs.readFile(filePath, "utf-8");
const newContents = contents.replace(/blues-stack-template/g, APP_ID);
await fs.writeFile(filePath, newContents);
}

console.log(
`
Expand Down
5 changes: 1 addition & 4 deletions remix.init/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,5 @@
"private": true,
"main": "index.js",
"license": "MIT",
"dependencies": {
"@iarna/toml": "^2.2.5",
"sort-package-json": "^1.55.0"
}
"dependencies": {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file can be removed completely I think, since we don't have any dependencies anymore?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, we can probably remove this 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, we can't remove until remix-run/remix#3146 is merged/released

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Released in 1.5.0

}