Skip to content

Commit

Permalink
fix(remix-dev): support JSX in .js route files (remix-run#3059)
Browse files Browse the repository at this point in the history
  • Loading branch information
chaance authored and aaronpowell committed May 10, 2022
1 parent 9ad9ea7 commit 372ff69
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 7 deletions.
2 changes: 1 addition & 1 deletion docs/api/conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ There are a few conventions that Remix uses you should be aware of.

Setting up routes in Remix is as simple as creating files in your `app` directory. These are the conventions you should know to understand how routing in Remix works.

Please note that you can use either `.jsx` or `.tsx` file extensions depending on whether or not you use TypeScript. We'll stick with `.tsx` in the examples to avoid duplication (and because we ❤️ TypeScript).
Please note that you can use either `.js`, `.jsx` or `.tsx` file extensions depending on whether or not you use TypeScript. We'll stick with `.tsx` in the examples to avoid duplication (and because we ❤️ TypeScript).

#### Root Layout Route

Expand Down
4 changes: 1 addition & 3 deletions docs/guides/typescript.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ title: TypeScript

Remix seamlessly supports both JavaScript and TypeScript. If you name a file with a `.ts` or `.tsx` extension, it will treat it as TypeScript (`.tsx` is for TypeScript files [with JSX](https://www.typescriptlang.org/docs/handbook/jsx.html) in them). But it isn't required. You can write all your files as `.js` files if you don't want TypeScript.

<docs-warning>To use JSX without TypeScript, you need to use the `.jsx` extension.</docs-warning>

The remix compiler will not do any type checking (it simply removes the types). If you want to do type checking, you'll want to use TypeScript's `tsc` CLI yourself. A common solution is to add a `typecheck` script to your package.json:
The Remix compiler will not do any type checking (it simply removes the types). If you want to do type checking, you'll want to use TypeScript's `tsc` CLI yourself. A common solution is to add a `typecheck` script to your package.json:

```json filename=package.json lines=[11]
{
Expand Down
42 changes: 42 additions & 0 deletions integration/js-routes-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { test } from "@playwright/test";

import { createAppFixture, createFixture, js } from "./helpers/create-fixture";
import type { AppFixture } from "./helpers/create-fixture";
import { PlaywrightFixture } from "./helpers/playwright-fixture";

test.describe(".js route files", () => {
let appFixture: AppFixture;

test.beforeAll(async () => {
appFixture = await createAppFixture(
await createFixture({
files: {
"app/routes/js.js": js`
export default () => <div data-testid="route-js">Rendered with .js ext</div>;
`,
"app/routes/jsx.jsx": js`
export default () => <div data-testid="route-jsx">Rendered with .jsx ext</div>;
`,
},
})
);
});

test.afterAll(async () => {
await appFixture.close();
});

test("should render all .js routes", async ({ page }) => {
let app = new PlaywrightFixture(appFixture, page);
await app.goto("/js");
await page.waitForSelector("[data-testid='route-js']");
test.expect(await page.content()).toContain("Rendered with .js ext");
});

test("should render all .jsx routes", async ({ page }) => {
let app = new PlaywrightFixture(appFixture, page);
await app.goto("/jsx");
await page.waitForSelector("[data-testid='route-jsx']");
test.expect(await page.content()).toContain("Rendered with .jsx ext");
});
});
3 changes: 3 additions & 0 deletions packages/remix-dev/compiler/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ export async function getRouteModuleExports(
format: "esm",
metafile: true,
write: false,
loader: {
".js": "jsx",
},
logLevel: "silent",
plugins: [mdxPlugin(config)],
});
Expand Down
6 changes: 3 additions & 3 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -887,9 +887,9 @@ function copyToPlaygrounds() {
await fse.copy(writtenDir, destDir);

// tickle live reload by touching the server entry
let serverEntry = ["entry.server.tsx", "entry.server.jsx"].find(
(entryPath) =>
fse.existsSync(path.join(playgroundDir, "app", entryPath))
let serverEntry = ["tsx", "js", "jsx"].find(
(entryPathExtension) =>
fse.existsSync(path.join(playgroundDir, "app", `entry.server.${entryPathExtension}`))
);
let serverEntryPath = path.join(playgroundDir, "app", serverEntry);
let serverEntryContent = await fse.readFile(serverEntryPath);
Expand Down

0 comments on commit 372ff69

Please sign in to comment.