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

Modernize Deno template #9932

Open
wants to merge 40 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
5ca3397
Modernize deno template
redabacha Sep 2, 2024
a908ba6
Merge branch 'dev' into modernize-deno-template
redabacha Sep 2, 2024
454a13c
Install Deno for unit tests
redabacha Sep 2, 2024
1e48a52
Update deno scripts in package.json
redabacha Sep 2, 2024
b94e223
Don't pass --node-modules-dir flag to deno install
redabacha Sep 2, 2024
1228943
Add vite deno integration test
redabacha Sep 2, 2024
3daf1b6
Make vite deno integration test work
redabacha Sep 2, 2024
1f222bc
Install deno for integration tests
redabacha Sep 2, 2024
d58caab
Wait on 127.0.0.1 for only deno
redabacha Sep 2, 2024
9576356
Allow scripts when installing deps with deno
redabacha Sep 2, 2024
ead6719
Use viteConfig.basic for vite deno integration test
redabacha Sep 2, 2024
0b86c3d
ugly attempt to get windows msedge test passing
redabacha Sep 2, 2024
196db71
Cleanup solution for windows msedge test a bit
redabacha Sep 3, 2024
00ab18e
Add typegen instructions in deno template README.md
redabacha Sep 4, 2024
07a9fe7
Remove extraneous console.log
redabacha Sep 4, 2024
3d86009
Add vite deno build integration test
redabacha Sep 5, 2024
197fc8c
Update viteDevCmd to use nodeSync instead of node
redabacha Sep 5, 2024
21704c4
Update deploy instructions in deno template README.md
redabacha Sep 5, 2024
c83c7e4
Add changesets
redabacha Sep 5, 2024
619f6e8
Merge branch 'dev' into modernize-deno-template
redabacha Sep 9, 2024
155c20d
Merge branch 'dev' into modernize-deno-template
redabacha Sep 16, 2024
1fa4672
Merge branch 'dev' into modernize-deno-template
redabacha Sep 18, 2024
c5bc59b
Merge branch 'dev' into modernize-deno-template
redabacha Sep 19, 2024
24e3ee5
Merge branch 'dev' of https://github.com/redabacha/remix into moderni…
redabacha Oct 9, 2024
a3c1bcc
feat: only support deno 2
redabacha Oct 9, 2024
1954f5b
Merge branch 'dev' into modernize-deno-template
redabacha Oct 9, 2024
d4004f3
feat: update workflow install deno action
redabacha Oct 9, 2024
0795f97
Use new nodeModulesDir option
redabacha Oct 9, 2024
4f728c9
Update ignore rules for deno
redabacha Oct 9, 2024
65afd86
Use pnpm workspace for vite-deno-template integration test
redabacha Oct 9, 2024
60f9808
Remove package.json from deno gitignore
redabacha Oct 10, 2024
2095f21
Remove remix version pinning in deno template
redabacha Oct 10, 2024
7513f3b
Add --frozen-lockfile to 2nd pnpm install
redabacha Oct 10, 2024
b185f29
Only assert for react devtools message on non-webkit browsers
redabacha Oct 10, 2024
72e2a9f
Merge branch 'dev' of https://github.com/redabacha/remix into moderni…
redabacha Oct 11, 2024
343f23e
Update pnpm lockfile
redabacha Oct 11, 2024
62fe2d1
Merge branch 'dev' into modernize-deno-template
redabacha Oct 11, 2024
f4a1e48
Merge branch 'dev' into modernize-deno-template
redabacha Oct 11, 2024
0b65afb
Update templates.md
redabacha Oct 12, 2024
3907b73
Merge branch 'dev' of https://github.com/redabacha/remix into moderni…
redabacha Oct 19, 2024
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
5 changes: 5 additions & 0 deletions .github/workflows/shared-test-unit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ jobs:
- name: 📥 Install deps
run: pnpm install --frozen-lockfile

- name: 🦕 Install Deno
uses: denoland/setup-deno@v1
with:
deno-version: vx.x.x

# It's faster to use the built `cli.js` in tests if its available and up-to-date
- name: 🏗 Build
run: pnpm build
Expand Down
6 changes: 0 additions & 6 deletions .vscode/deno_resolve_npm_imports.json

This file was deleted.

5 changes: 3 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"typescript.tsdk": "node_modules/typescript/lib",
"deno.enablePaths": ["./packages/remix-deno/"],
"deno.importMap": "./.vscode/deno_resolve_npm_imports.json"
"deno.config": "./templates/deno/deno.jsonc",
"deno.enablePaths": ["./packages/remix-deno/", "./templates/deno"],
"deno.disablePaths": ["./templates/deno/app"]
}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
"clean:build": "node ./scripts/clean-build.mjs",
"clean:integration": "node ./integration/helpers/cleanup.mjs",
"format": "prettier --cache --ignore-path .eslintignore --write ./ && npm run lint:fix",
"format:deno": "deno fmt integration/helpers/deno-template packages/remix-deno templates/deno --ignore=node_modules,build,public/build",
"format:deno": "deno fmt --config ./templates/deno/deno.jsonc integration/helpers/deno-template packages/remix-deno templates/deno",
"license": "node ./scripts/license.js",
"lint": "eslint .",
"lint:deno": "deno lint integration/helpers/deno-template packages/remix-deno templates/deno --ignore=node_modules,build,public/build",
"lint:deno": "deno lint --config ./templates/deno/deno.jsonc integration/helpers/deno-template packages/remix-deno templates/deno",
"lint:fix": "pnpm lint --fix",
"playground:new": "node ./scripts/playground/new.js",
"publish": "node ./scripts/publish.js",
Expand Down
67 changes: 67 additions & 0 deletions packages/create-remix/__tests__/create-remix-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,42 @@ describe("create-remix CLI", () => {
expect(fse.existsSync(path.join(projectDir, "remix.init"))).toBeTruthy();
});

it("runs remix.init script in a deno project", async () => {
let projectDir = getProjectDir("remix-init-deno");

let { status, stdout, stderr } = await execCreateRemix({
args: [
projectDir,
"--template",
path.join(__dirname, "fixtures", "successful-remix-init-deno"),
"--no-git-init",
"--package-manager",
"deno",
],
interactions: [
{
question: /install dependencies/i,
type: ["y", ENTER],
},
{
question: /init script/i,
type: ["y", ENTER],
},
],
});

expect(stderr.trim()).toBeFalsy();
expect(stdout).toContain(`Template's remix.init script complete`);
expect(stdout).toContain("`package.json` file not found.");
expect(status).toBe(0);
expect(fse.existsSync(path.join(projectDir, "deno.json"))).toBeTruthy();
expect(fse.existsSync(path.join(projectDir, "test.txt"))).toBeTruthy();
expect(fse.readFileSync(path.join(projectDir, "test.txt"), "utf8")).toBe(
"added via remix.init, isOdd(1): true"
);
expect(fse.existsSync(path.join(projectDir, "remix.init"))).toBeFalsy();
});

it("runs npm install by default", async () => {
let originalUserAgent = process.env.npm_config_user_agent;
process.env.npm_config_user_agent = undefined;
Expand Down Expand Up @@ -865,6 +901,37 @@ describe("create-remix CLI", () => {
process.env.npm_config_user_agent = originalUserAgent;
});

it("recognizes when Deno was used to run the command", async () => {
process.versions.deno = "1.46.2";

let projectDir = getProjectDir("deno-create-from-process-versions");

let execa = require("execa");
execa.mockImplementation(async () => {});

// Suppress terminal output
let stdoutMock = jest
.spyOn(process.stdout, "write")
.mockImplementation(() => true);

await createRemix([
projectDir,
"--template",
path.join(__dirname, "fixtures", "blank"),
"--no-git-init",
"--yes",
]);

stdoutMock.mockReset();

expect(execa).toHaveBeenCalledWith(
"deno",
expect.arrayContaining(["install", "--no-lock"]),
expect.objectContaining({ env: { DENO_FUTURE: "1" } })
);
delete process.versions.deno;
});

it("supports specifying the package manager, regardless of user agent", async () => {
let originalUserAgent = process.env.npm_config_user_agent;
process.env.npm_config_user_agent =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"nodeModulesDir": true,
"imports": {
"is-odd": "npm:is-odd@3.0.1"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const fs = require("node:fs");
const path = require("node:path");
const isOdd = require("is-odd");

module.exports = ({ rootDirectory }) => {
fs.writeFileSync(
path.join(rootDirectory, "test.txt"),
`added via remix.init, isOdd(1): ${isOdd(1)}`
);
};
51 changes: 30 additions & 21 deletions packages/create-remix/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,11 @@ async function getContext(argv: string[]): Promise<Context> {
noMotion,
pkgManager: validatePackageManager(
pkgManager ??
// npm, pnpm, Yarn, and Bun set the user agent environment variable that can be used
// to determine which package manager ran the command.
(process.env.npm_config_user_agent ?? "npm").split("/")[0]
(process.versions.deno
? "deno"
: // npm, pnpm, Yarn, and Bun set the user agent environment variable that can be used
// to determine which package manager ran the command.
(process.env.npm_config_user_agent ?? "npm").split("/")[0])
Comment on lines +163 to +167
Copy link
Contributor Author

Choose a reason for hiding this comment

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

),
projectName,
prompt,
Expand Down Expand Up @@ -525,7 +527,8 @@ async function runInitScriptStep(ctx: Context) {
return;
}

let initCommand = `${packageManagerExecScript[ctx.pkgManager]} remix init`;
let packageManager = ctx.pkgManager;
let initCommand = `${packageManagerExecScript[packageManager]} init`;

if (!ctx.install || !ctx.initScript) {
await sleep(100);
Expand All @@ -544,16 +547,15 @@ async function runInitScriptStep(ctx: Context) {

let initScriptDir = path.dirname(ctx.initScriptPath);
let initPackageJson = path.resolve(initScriptDir, "package.json");
let packageManager = ctx.pkgManager;

try {
if (await fileExists(initPackageJson)) {
await loadingIndicator({
start: `Dependencies for remix.init script installing with ${ctx.pkgManager}...`,
start: `Dependencies for remix.init script installing with ${packageManager}...`,
end: "Dependencies for remix.init script installed",
while: () =>
installDependencies({
pkgManager: ctx.pkgManager,
pkgManager: packageManager,
cwd: initScriptDir,
showInstallOutput: ctx.showInstallOutput,
}),
Expand Down Expand Up @@ -642,13 +644,14 @@ async function doneStep(ctx: Context) {
await sleep(200);
}

type PackageManager = "npm" | "yarn" | "pnpm" | "bun";
type PackageManager = "npm" | "yarn" | "pnpm" | "bun" | "deno";

const packageManagerExecScript: Record<PackageManager, string> = {
npm: "npx",
yarn: "yarn",
pnpm: "pnpm exec",
bun: "bunx",
npm: "npx remix",
yarn: "yarn remix",
pnpm: "pnpm exec remix",
bun: "bunx remix",
deno: "deno run --no-lock -A npm:@remix-run/dev",
};

function validatePackageManager(pkgManager: string): PackageManager {
Expand All @@ -667,10 +670,15 @@ async function installDependencies({
showInstallOutput: boolean;
}) {
try {
await execa(pkgManager, ["install"], {
cwd,
stdio: showInstallOutput ? "inherit" : "ignore",
});
await execa(
pkgManager,
["install", ...(pkgManager === "deno" ? ["--no-lock"] : [])],
redabacha marked this conversation as resolved.
Show resolved Hide resolved
{
cwd,
env: pkgManager === "deno" ? { DENO_FUTURE: "1" } : undefined,
stdio: showInstallOutput ? "inherit" : "ignore",
}
);
} catch (err) {
error("Oh no!", "Failed to install dependencies.");
throw err;
Expand All @@ -681,12 +689,13 @@ async function updatePackageJSON(ctx: Context) {
let packageJSONPath = path.join(ctx.cwd, "package.json");
if (!fs.existsSync(packageJSONPath)) {
let relativePath = path.relative(process.cwd(), ctx.cwd);
error(
"Oh no!",
"The provided template must be a Remix project with a `package.json` " +
`file, but that file does not exist in ${color.bold(relativePath)}.`
info(
"`package.json` file not found.",
"The provided template did not provide a `package.json` file in " +
color.bold(relativePath) +
". This is expected for Deno templates."
);
throw new Error(`package.json does not exist in ${ctx.cwd}`);
return;
}

let contents = await fs.promises.readFile(packageJSONPath, "utf-8");
Expand Down
30 changes: 0 additions & 30 deletions packages/remix-dev/__tests__/fixtures/deno/package.json

This file was deleted.

20 changes: 12 additions & 8 deletions packages/remix-dev/__tests__/readConfig-test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
import path from "node:path";

import type { RemixConfig } from "../config";
import { readConfig } from "../config";

const remixRoot = path.join(__dirname, "fixtures", "stack");

describe("readConfig", () => {
let config: RemixConfig;
beforeEach(async () => {
config = await readConfig(remixRoot);
});

it("generates a config", async () => {
let remixRoot = path.join(__dirname, "fixtures", "stack");
let config = await readConfig(remixRoot);
expect(config).toMatchInlineSnapshot(
{
rootDirectory: expect.any(String),
Expand Down Expand Up @@ -76,4 +70,14 @@ describe("readConfig", () => {
`
);
});

it("generates a config for deno project", async () => {
let remixRoot = path.join(__dirname, "fixtures", "deno");
let config = await readConfig(remixRoot);
expect(config).toEqual(
expect.objectContaining({
entryServerFile: "entry.server.deno.tsx",
})
);
});
});
33 changes: 2 additions & 31 deletions packages/remix-dev/cli/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { execSync } from "node:child_process";
import fse from "fs-extra";
import getPort, { makeRange } from "get-port";
import prettyMs from "pretty-ms";
import PackageJson from "@npmcli/package-json";
import pc from "picocolors";
import exitHook from "exit-hook";

Expand All @@ -23,6 +22,7 @@ import type { Options } from "../compiler/options";
import { createFileWatchCache } from "../compiler/fileWatchCache";
import { logger } from "../tux";
import * as profiler from "../vite/profiler";
import { detectServerRuntime } from "./detectServerRuntime";

type InitFlags = {
deleteScript?: boolean;
Expand Down Expand Up @@ -230,11 +230,6 @@ let conjunctionListFormat = new Intl.ListFormat("en", {
type: "conjunction",
});

let disjunctionListFormat = new Intl.ListFormat("en", {
style: "long",
type: "disjunction",
});

export async function generateEntry(
entry: string,
remixRoot: string,
Expand Down Expand Up @@ -273,31 +268,7 @@ export async function generateEntry(
return;
}

let pkgJson = await PackageJson.load(rootDirectory);
let deps = pkgJson.content.dependencies ?? {};

let serverRuntime = deps["@remix-run/deno"]
? "deno"
: deps["@remix-run/cloudflare"]
? "cloudflare"
: deps["@remix-run/node"]
? "node"
: undefined;

if (!serverRuntime) {
let serverRuntimes = [
"@remix-run/deno",
"@remix-run/cloudflare",
"@remix-run/node",
];
let formattedList = disjunctionListFormat.format(serverRuntimes);
console.error(
colors.error(
`Could not determine server runtime. Please install one of the following: ${formattedList}`
)
);
return;
}
let serverRuntime = await detectServerRuntime(rootDirectory);

let defaultsDirectory = path.resolve(__dirname, "..", "config", "defaults");
let defaultEntryClient = path.resolve(defaultsDirectory, "entry.client.tsx");
Expand Down
Loading