Repository: remix-run/remix
Pull request #3970 (2022-08-09 21:23:52)

fix(remix-dev): allow defining multiple routes for the same route module file
Closes: #1898

- [ ] Docs
- [x] Tests

Testing Strategy:

I copied a failing test to show that multiple routes pointing at a single route module get overwritten from here https://github.com/remix-run/remix/pull/3684 and works in some files to get this works for real.

Basically I've changed the `remix-dev/config/routes.ts` to allow receive some optional custom ID for routes because in a normal way two or more routes to the same route module will receive internally the same ID, so if somebody could pass a new unique ID we will resolve this this "route overwritten" situation.

Also to get the this idea completely working I've had too changed `remix-dev/compiler/assets.ts` to allow the compiler groups more then one route per route module file.

changeset-bot[bot]: ###  ⚠️  No Changeset found

Latest commit: f80267df6238c0dff84528f71363d76213914cd4

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. **If these changes should result in a version bump, you need to add a changeset.**

<details><summary>This PR includes no changesets</summary>

  When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

</details>

[Click here to learn what changesets are, and how to add one](https://github.com/changesets/changesets/blob/master/docs/adding-a-changeset.md).

[Click here if you're a maintainer who wants to add a changeset to this PR](https://github.com/lucasferreira/remix/new/dev?filename=.changeset/light-fireants-flow.md&value=---%0A%22remix%22%3A%20patch%0A%22%40remix-run%2Fdev%22%3A%20patch%0A---%0A%0AAllow%20multiple%20routes%20for%20same%20route%20module%0A)


lucasferreira: Hi @AndrewLeedham 

I made a small change in the last commit in variable `id` (to `fileId`) name to clarify more what kind of id the automated. And also made more one adjust in `id` option comment instruction/detail in the way u suggest.

What is the next step to me?
AndrewLeedham: > Hi @AndrewLeedham 
> 
> I made a small change in the last commit in variable `id` (to `fileId`) name to clarify more what kind of id the automated. And also made more one adjust in `id` option comment instruction/detail in the way u suggest.
> 
> What is the next step to me?

The changes looks good to me. Unfortunately I'm not a maintainer, just an interested party, so the PR getting the attention and subsequent review of a maintainer would be the next step I would have thought.
runmoore: Nice work! I think it would be good if the docs are also updated, but maybe this can come later once the idea has been given the OK
lucasferreira: > Nice work! I think it would be good if the docs are also updated, but maybe this can come later once the idea has been given the OK

I agree with the future docs update and if someone need some light code sample to test this PR:

```javascript
module.exports = {
  appDirectory: "app",
  assetsBuildDirectory: "public/build",
  devServerPort: 8002,
  publicPath: "/build/",
  serverBuildDirectory: "build",
  ignoredRouteFiles: [".*"],
  routes(defineRoutes) {
    return defineRoutes(route => {
      route("/user/:id", "routes/index.tsx", { id: "user-by-id" });
      route("/user", "routes/index.tsx");
    });
  }
};
```
runmoore: @lucasferreira what's the easiest way to test this logic in my own app?
lucasferreira: > @lucasferreira what's the easiest way to test this logic in my own app?

I know thats weird but when I started develop this changes I worked directly inside de `node_modules/@remix-run` of my current working project. If you need to test in a exists project you could do the same looking to my PR files:

https://github.com/remix-run/remix/pull/3970/files

Basically you need to change 2 files `node_modules/@remix-run/dev/dist/config/routes.js` and `node_modules/@remix-run/dev/dist/compiler/assets.js`

But if you need to test isolated some code and sample project you could checkout my modified branch (https://github.com/lucasferreira/remix/tree/dev) and create some playground app: https://github.com/remix-run/remix/blob/main/docs/pages/contributing.md#playground
AndrewLeedham: Just played around with this locally, and it works a treat! Would be great to get this merged in :)

@runmoore I got this working by making a [patch-package](https://www.npmjs.com/package/patch-package) patch, I'll include it below.

<details>
<summary><code>@remix-run+dev+1.7.0.patch</code></summary>

```
diff --git a/node_modules/@remix-run/dev/dist/build.js b/node_modules/@remix-run/dev/dist/build.js
index e633d32..2ac6024 100644
--- a/node_modules/@remix-run/dev/dist/build.js
+++ b/node_modules/@remix-run/dev/dist/build.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cache.js b/node_modules/@remix-run/dev/dist/cache.js
index a2bf15e..7ad0d81 100644
--- a/node_modules/@remix-run/dev/dist/cache.js
+++ b/node_modules/@remix-run/dev/dist/cache.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli.js b/node_modules/@remix-run/dev/dist/cli.js
old mode 100755
new mode 100644
index b610bda..598d7a0
--- a/node_modules/@remix-run/dev/dist/cli.js
+++ b/node_modules/@remix-run/dev/dist/cli.js
@@ -1,6 +1,6 @@
 #!/usr/bin/env node
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/checkGitStatus.js b/node_modules/@remix-run/dev/dist/cli/checkGitStatus.js
index 73aadc1..974a250 100644
--- a/node_modules/@remix-run/dev/dist/cli/checkGitStatus.js
+++ b/node_modules/@remix-run/dev/dist/cli/checkGitStatus.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
@@ -25,9 +25,7 @@ const checkGitStatus = (projectDir, {
     clean = isGitClean(projectDir);
     errorMessage = "Git directory is not clean";
   } catch (err) {
-    var _err$stderr;
-
-    if ((err === null || err === void 0 ? void 0 : (_err$stderr = err.stderr) === null || _err$stderr === void 0 ? void 0 : _err$stderr.indexOf("Not a git repository")) >= 0) {
+    if ((err === null || err === void 0 ? void 0 : err.stderr.indexOf("Not a git repository")) >= 0) {
       clean = true;
     }
   }
diff --git a/node_modules/@remix-run/dev/dist/cli/commands.js b/node_modules/@remix-run/dev/dist/cli/commands.js
index 31e6d43..93e642f 100644
--- a/node_modules/@remix-run/dev/dist/cli/commands.js
+++ b/node_modules/@remix-run/dev/dist/cli/commands.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/create.js b/node_modules/@remix-run/dev/dist/cli/create.js
index 2863b8e..395f1a8 100644
--- a/node_modules/@remix-run/dev/dist/cli/create.js
+++ b/node_modules/@remix-run/dev/dist/cli/create.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/getPreferredPackageManager.js b/node_modules/@remix-run/dev/dist/cli/getPreferredPackageManager.js
index 37645f6..fdc78bd 100644
--- a/node_modules/@remix-run/dev/dist/cli/getPreferredPackageManager.js
+++ b/node_modules/@remix-run/dev/dist/cli/getPreferredPackageManager.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/index.js b/node_modules/@remix-run/dev/dist/cli/index.js
index 3283c64..521d741 100644
--- a/node_modules/@remix-run/dev/dist/cli/index.js
+++ b/node_modules/@remix-run/dev/dist/cli/index.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/jscodeshift.js b/node_modules/@remix-run/dev/dist/cli/migrate/jscodeshift.js
index 14b2d7e..c63080c 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/jscodeshift.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/jscodeshift.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/cleanupPackageJson.js b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/cleanupPackageJson.js
index 83f1360..e7529bd 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/cleanupPackageJson.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/cleanupPackageJson.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/convertTSConfigs.js b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/convertTSConfigs.js
index 12a77dd..83bcb3e 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/convertTSConfigs.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/convertTSConfigs.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/convertTSFilesToJS/convertTSFileToJS.js b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/convertTSFilesToJS/convertTSFileToJS.js
index 9b67636..89ce36b 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/convertTSFilesToJS/convertTSFileToJS.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/convertTSFilesToJS/convertTSFileToJS.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/convertTSFilesToJS/index.js b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/convertTSFilesToJS/index.js
index 17755db..b3d0d78 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/convertTSFilesToJS/index.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/convertTSFilesToJS/index.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/index.js b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/index.js
index 4bb4d57..1d0da47 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/index.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/index.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/transform/checkNoDifferentImportTypesCombined.js b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/transform/checkNoDifferentImportTypesCombined.js
index b15839e..e5543d2 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/transform/checkNoDifferentImportTypesCombined.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/transform/checkNoDifferentImportTypesCombined.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/transform/createExpressionStatement.js b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/transform/createExpressionStatement.js
index c213e78..bcc262e 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/transform/createExpressionStatement.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/transform/createExpressionStatement.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/transform/createVariableDeclarationIdentifier.js b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/transform/createVariableDeclarationIdentifier.js
index 1f2897e..979f387 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/transform/createVariableDeclarationIdentifier.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/transform/createVariableDeclarationIdentifier.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/transform/createVariableDeclarationObjectPattern.js b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/transform/createVariableDeclarationObjectPattern.js
index bf4cfbc..b032157 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/transform/createVariableDeclarationObjectPattern.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/transform/createVariableDeclarationObjectPattern.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/transform/index.js b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/transform/index.js
index 81f188b..2f4429c 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/transform/index.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/convert-to-javascript/transform/index.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/index.js b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/index.js
index 8c17762..52cfa3d 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/index.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/index.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/dependency.js b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/dependency.js
index fa98724..e610274 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/dependency.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/dependency.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/index.js b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/index.js
index e4210bb..93308d7 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/index.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/index.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/messages.js b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/messages.js
index 7ffe47b..e68830c 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/messages.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/messages.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/remixSetup.js b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/remixSetup.js
index 7d4afb9..efbd58a 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/remixSetup.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/remixSetup.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/resolveTransformOptions.js b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/resolveTransformOptions.js
index 88cc39a..1f9920d 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/resolveTransformOptions.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/resolveTransformOptions.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/adapter.js b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/adapter.js
index c21d7be..d0336f1 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/adapter.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/adapter.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/getNewImportDeclarations.js b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/getNewImportDeclarations.js
index 63333ee..0a500a3 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/getNewImportDeclarations.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/getNewImportDeclarations.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/getRemixImports.js b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/getRemixImports.js
index 069d25f..7a1fec8 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/getRemixImports.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/getRemixImports.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/index.js b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/index.js
index 11d2715..a966870 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/index.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/index.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/mapNormalizedImports/index.js b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/mapNormalizedImports/index.js
index 7f6954d..c087697 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/mapNormalizedImports/index.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/mapNormalizedImports/index.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/mapNormalizedImports/packageExports.js b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/mapNormalizedImports/packageExports.js
index 1fb0077..4a332bf 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/mapNormalizedImports/packageExports.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/mapNormalizedImports/packageExports.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/normalizeImports.js b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/normalizeImports.js
index d1d6231..924f3eb 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/normalizeImports.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/normalizeImports.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/runtime.js b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/runtime.js
index 23b6d96..b7f317c 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/runtime.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/replace-remix-imports/transform/runtime.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/transforms.js b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/transforms.js
index cc1ddb7..02bcc10 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/migrations/transforms.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/migrations/transforms.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/resolveInput.js b/node_modules/@remix-run/dev/dist/cli/migrate/resolveInput.js
index 1972125..6aa340e 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/resolveInput.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/resolveInput.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/migrate/run.js b/node_modules/@remix-run/dev/dist/cli/migrate/run.js
index d8d202b..83f5fe1 100644
--- a/node_modules/@remix-run/dev/dist/cli/migrate/run.js
+++ b/node_modules/@remix-run/dev/dist/cli/migrate/run.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/cli/run.js b/node_modules/@remix-run/dev/dist/cli/run.js
index 9f6edb6..0bbc772 100644
--- a/node_modules/@remix-run/dev/dist/cli/run.js
+++ b/node_modules/@remix-run/dev/dist/cli/run.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
@@ -63,7 +63,6 @@ ${colors.logoBlue("R")} ${colors.logoGreen("E")} ${colors.logoYellow("M")} ${col
     $ remix build [${colors.arg("projectDir")}]
     $ remix dev [${colors.arg("projectDir")}]
     $ remix routes [${colors.arg("projectDir")}]
-    $ remix watch [${colors.arg("projectDir")}]
     $ remix setup [${colors.arg("remixPlatform")}]
     $ remix migrate [-m ${colors.arg("migration")}] [${colors.arg("projectDir")}]
 
@@ -139,14 +138,6 @@ ${colors.logoBlue("R")} ${colors.logoGreen("E")} ${colors.logoYellow("M")} ${col
     $ remix dev my-app
     $ remix dev --debug
 
-  ${colors.heading("Start your server separately and watch for changes")}:
-
-    # custom server start command, for example:
-    $ remix watch
-
-    # in a separate tab:
-    $ node --inspect --require ./node_modules/dotenv/config --require ./mocks ./build/server.js
-
   ${colors.heading("Show all routes in your app")}:
 
     $ remix routes
diff --git a/node_modules/@remix-run/dev/dist/cli/setup.js b/node_modules/@remix-run/dev/dist/cli/setup.js
index d0711e6..7da47fb 100644
--- a/node_modules/@remix-run/dev/dist/cli/setup.js
+++ b/node_modules/@remix-run/dev/dist/cli/setup.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/colors.js b/node_modules/@remix-run/dev/dist/colors.js
index 2b32f07..12845e4 100644
--- a/node_modules/@remix-run/dev/dist/colors.js
+++ b/node_modules/@remix-run/dev/dist/colors.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/compiler.js b/node_modules/@remix-run/dev/dist/compiler.js
index 9ce96d5..c37d916 100644
--- a/node_modules/@remix-run/dev/dist/compiler.js
+++ b/node_modules/@remix-run/dev/dist/compiler.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
@@ -62,6 +62,11 @@ var fse__namespace = /*#__PURE__*/_interopNamespace(fse);
 var debounce__default = /*#__PURE__*/_interopDefaultLegacy(debounce);
 var chokidar__default = /*#__PURE__*/_interopDefaultLegacy(chokidar);
 
+// directory in the same place relative to this file. It is eventually injected
+// as a source file when building the app.
+
+const reactShim = path__namespace.resolve(__dirname, "compiler/shims/react.ts");
+
 function defaultWarningHandler(message, key) {
   warnings.warnOnce(message, key);
 }
@@ -316,6 +321,7 @@ async function createBrowserBuild(config, options) {
     platform: "browser",
     format: "esm",
     external: externals,
+    inject: config.serverBuildTarget === "deno" ? [] : [reactShim],
     loader: loaders.loaders,
     bundle: true,
     logLevel: "silent",
@@ -334,8 +340,6 @@ async function createBrowserBuild(config, options) {
       "process.env.NODE_ENV": JSON.stringify(options.mode),
       "process.env.REMIX_DEV_SERVER_WS_PORT": JSON.stringify(config.devServerPort)
     },
-    jsx: "automatic",
-    jsxDev: options.mode !== build$1.BuildMode.Production,
     plugins
   });
 }
@@ -383,6 +387,7 @@ function createServerBuild(config, options, assetsManifestPromiseRef) {
     minify: options.mode === build$1.BuildMode.Production && isCloudflareRuntime,
     mainFields: isCloudflareRuntime ? ["browser", "module", "main"] : config.serverModuleFormat === "esm" ? ["module", "main"] : ["main", "module"],
     target: options.target,
+    inject: config.serverBuildTarget === "deno" ? [] : [reactShim],
     loader: loaders.loaders,
     bundle: true,
     logLevel: "silent",
@@ -397,8 +402,6 @@ function createServerBuild(config, options, assetsManifestPromiseRef) {
       "process.env.NODE_ENV": JSON.stringify(options.mode),
       "process.env.REMIX_DEV_SERVER_WS_PORT": JSON.stringify(config.devServerPort)
     },
-    jsx: "automatic",
-    jsxDev: options.mode !== build$1.BuildMode.Production,
     plugins
   }).then(async build => {
     await writeServerBuildResult(config, build.outputFiles);
diff --git a/node_modules/@remix-run/dev/dist/compiler/assets.js b/node_modules/@remix-run/dev/dist/compiler/assets.js
index 37c3817..cd062bd 100644
--- a/node_modules/@remix-run/dev/dist/compiler/assets.js
+++ b/node_modules/@remix-run/dev/dist/compiler/assets.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
@@ -50,7 +50,7 @@ async function createAssetsManifest(config, metafile) {
   let entryClientFile = path__namespace.resolve(config.appDirectory, config.entryClientFile);
   let routesByFile = Object.keys(config.routes).reduce((map, key) => {
     let route = config.routes[key];
-    map.set(route.file, route);
+    map.set(route.file, map.has(route.file) ? [...map.get(route.file), route] : [route]);
     return map;
   }, new Map());
   let entry;
@@ -69,22 +69,27 @@ async function createAssetsManifest(config, metafile) {
       }; // Only parse routes otherwise dynamic imports can fall into here and fail the build
     } else if (entryPointFile.startsWith("browser-route-module:")) {
       entryPointFile = entryPointFile.replace(/(^browser-route-module:|\?browser$)/g, "");
-      let route = routesByFile.get(entryPointFile);
-      invariant["default"](route, `Cannot get route for entry point ${output.entryPoint}`);
-      let sourceExports = await routes.getRouteModuleExportsCached(config, route.id);
-      routes$1[route.id] = {
-        id: route.id,
-        parentId: route.parentId,
-        path: route.path,
-        index: route.index,
-        caseSensitive: route.caseSensitive,
-        module: resolveUrl(key),
-        imports: resolveImports(output.imports),
-        hasAction: sourceExports.includes("action"),
-        hasLoader: sourceExports.includes("loader"),
-        hasCatchBoundary: sourceExports.includes("CatchBoundary"),
-        hasErrorBoundary: sourceExports.includes("ErrorBoundary")
-      };
+      let groupedRoute = routesByFile.get(entryPointFile);
+      invariant["default"](groupedRoute, `Cannot get route(s) for entry point ${output.entryPoint}`);
+
+      if (groupedRoute) {
+        for (let route of groupedRoute) {
+          let sourceExports = await routes.getRouteModuleExportsCached(config, route.id);
+          routes$1[route.id] = {
+            id: route.id,
+            parentId: route.parentId,
+            path: route.path,
+            index: route.index,
+            caseSensitive: route.caseSensitive,
+            module: resolveUrl(key),
+            imports: resolveImports(output.imports),
+            hasAction: sourceExports.includes("action"),
+            hasLoader: sourceExports.includes("loader"),
+            hasCatchBoundary: sourceExports.includes("CatchBoundary"),
+            hasErrorBoundary: sourceExports.includes("ErrorBoundary")
+          };
+        }
+      }
     }
   }
 
diff --git a/node_modules/@remix-run/dev/dist/compiler/dependencies.js b/node_modules/@remix-run/dev/dist/compiler/dependencies.js
index d9637fb..3a52f08 100644
--- a/node_modules/@remix-run/dev/dist/compiler/dependencies.js
+++ b/node_modules/@remix-run/dev/dist/compiler/dependencies.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/compiler/loaders.js b/node_modules/@remix-run/dev/dist/compiler/loaders.js
index 267db7e..c9f7861 100644
--- a/node_modules/@remix-run/dev/dist/compiler/loaders.js
+++ b/node_modules/@remix-run/dev/dist/compiler/loaders.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
@@ -36,13 +36,10 @@ var path__namespace = /*#__PURE__*/_interopNamespace(path);
 
 const loaders = {
   ".aac": "file",
-  ".avif": "file",
   ".css": "file",
   ".eot": "file",
   ".flac": "file",
   ".gif": "file",
-  ".gql": "text",
-  ".graphql": "text",
   ".ico": "file",
   ".jpeg": "file",
   ".jpg": "file",
@@ -68,8 +65,7 @@ const loaders = {
   ".webmanifest": "file",
   ".webp": "file",
   ".woff": "file",
-  ".woff2": "file",
-  ".zip": "file"
+  ".woff2": "file"
 };
 function getLoaderForFile(file) {
   let ext = path__namespace.extname(file);
diff --git a/node_modules/@remix-run/dev/dist/compiler/plugins/browserRouteModulesPlugin.js b/node_modules/@remix-run/dev/dist/compiler/plugins/browserRouteModulesPlugin.js
index e73e834..85a0cc3 100644
--- a/node_modules/@remix-run/dev/dist/compiler/plugins/browserRouteModulesPlugin.js
+++ b/node_modules/@remix-run/dev/dist/compiler/plugins/browserRouteModulesPlugin.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/compiler/plugins/emptyModulesPlugin.js b/node_modules/@remix-run/dev/dist/compiler/plugins/emptyModulesPlugin.js
index de2be25..24061de 100644
--- a/node_modules/@remix-run/dev/dist/compiler/plugins/emptyModulesPlugin.js
+++ b/node_modules/@remix-run/dev/dist/compiler/plugins/emptyModulesPlugin.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/compiler/plugins/mdx.js b/node_modules/@remix-run/dev/dist/compiler/plugins/mdx.js
index ed4befe..26fdbb7 100644
--- a/node_modules/@remix-run/dev/dist/compiler/plugins/mdx.js
+++ b/node_modules/@remix-run/dev/dist/compiler/plugins/mdx.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/compiler/plugins/serverAssetsManifestPlugin.js b/node_modules/@remix-run/dev/dist/compiler/plugins/serverAssetsManifestPlugin.js
index 5aa58bd..bfbacbb 100644
--- a/node_modules/@remix-run/dev/dist/compiler/plugins/serverAssetsManifestPlugin.js
+++ b/node_modules/@remix-run/dev/dist/compiler/plugins/serverAssetsManifestPlugin.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/compiler/plugins/serverBareModulesPlugin.js b/node_modules/@remix-run/dev/dist/compiler/plugins/serverBareModulesPlugin.js
index 07b03f2..e17905b 100644
--- a/node_modules/@remix-run/dev/dist/compiler/plugins/serverBareModulesPlugin.js
+++ b/node_modules/@remix-run/dev/dist/compiler/plugins/serverBareModulesPlugin.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/compiler/plugins/serverEntryModulePlugin.js b/node_modules/@remix-run/dev/dist/compiler/plugins/serverEntryModulePlugin.js
index 73194c8..b5fbd7d 100644
--- a/node_modules/@remix-run/dev/dist/compiler/plugins/serverEntryModulePlugin.js
+++ b/node_modules/@remix-run/dev/dist/compiler/plugins/serverEntryModulePlugin.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/compiler/plugins/serverRouteModulesPlugin.js b/node_modules/@remix-run/dev/dist/compiler/plugins/serverRouteModulesPlugin.js
index ecd2ad8..e2456b3 100644
--- a/node_modules/@remix-run/dev/dist/compiler/plugins/serverRouteModulesPlugin.js
+++ b/node_modules/@remix-run/dev/dist/compiler/plugins/serverRouteModulesPlugin.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/compiler/plugins/urlImportsPlugin.js b/node_modules/@remix-run/dev/dist/compiler/plugins/urlImportsPlugin.js
index bc13acf..431fab6 100644
--- a/node_modules/@remix-run/dev/dist/compiler/plugins/urlImportsPlugin.js
+++ b/node_modules/@remix-run/dev/dist/compiler/plugins/urlImportsPlugin.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/compiler/routes.js b/node_modules/@remix-run/dev/dist/compiler/routes.js
index f10aa30..0d3d4de 100644
--- a/node_modules/@remix-run/dev/dist/compiler/routes.js
+++ b/node_modules/@remix-run/dev/dist/compiler/routes.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/compiler/shims/react.ts b/node_modules/@remix-run/dev/dist/compiler/shims/react.ts
new file mode 100644
index 0000000..44af7fb
--- /dev/null
+++ b/node_modules/@remix-run/dev/dist/compiler/shims/react.ts
@@ -0,0 +1,3 @@
+// eslint-disable-next-line import/no-extraneous-dependencies
+import * as React from "react";
+export { React };
diff --git a/node_modules/@remix-run/dev/dist/compiler/utils/crypto.js b/node_modules/@remix-run/dev/dist/compiler/utils/crypto.js
index 3361cd9..8efc4ea 100644
--- a/node_modules/@remix-run/dev/dist/compiler/utils/crypto.js
+++ b/node_modules/@remix-run/dev/dist/compiler/utils/crypto.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/compiler/utils/fs.js b/node_modules/@remix-run/dev/dist/compiler/utils/fs.js
index 71bfc95..ddb3b51 100644
--- a/node_modules/@remix-run/dev/dist/compiler/utils/fs.js
+++ b/node_modules/@remix-run/dev/dist/compiler/utils/fs.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/compiler/utils/tsconfig/index.js b/node_modules/@remix-run/dev/dist/compiler/utils/tsconfig/index.js
index 3443787..8a4c2ca 100644
--- a/node_modules/@remix-run/dev/dist/compiler/utils/tsconfig/index.js
+++ b/node_modules/@remix-run/dev/dist/compiler/utils/tsconfig/index.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/compiler/utils/tsconfig/write-config-defaults.js b/node_modules/@remix-run/dev/dist/compiler/utils/tsconfig/write-config-defaults.js
index 74903dc..5f82e4b 100644
--- a/node_modules/@remix-run/dev/dist/compiler/utils/tsconfig/write-config-defaults.js
+++ b/node_modules/@remix-run/dev/dist/compiler/utils/tsconfig/write-config-defaults.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/compiler/utils/url.js b/node_modules/@remix-run/dev/dist/compiler/utils/url.js
index c2c6f97..270e588 100644
--- a/node_modules/@remix-run/dev/dist/compiler/utils/url.js
+++ b/node_modules/@remix-run/dev/dist/compiler/utils/url.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/compiler/virtualModules.js b/node_modules/@remix-run/dev/dist/compiler/virtualModules.js
index 73e3760..6ad2f54 100644
--- a/node_modules/@remix-run/dev/dist/compiler/virtualModules.js
+++ b/node_modules/@remix-run/dev/dist/compiler/virtualModules.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/compiler/warnings.js b/node_modules/@remix-run/dev/dist/compiler/warnings.js
index 050af27..c80ac49 100644
--- a/node_modules/@remix-run/dev/dist/compiler/warnings.js
+++ b/node_modules/@remix-run/dev/dist/compiler/warnings.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/config.js b/node_modules/@remix-run/dev/dist/config.js
index 4924d80..58392b5 100644
--- a/node_modules/@remix-run/dev/dist/config.js
+++ b/node_modules/@remix-run/dev/dist/config.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
@@ -13,7 +13,6 @@
 Object.defineProperty(exports, '__esModule', { value: true });
 
 var path = require('path');
-var url = require('url');
 var fse = require('fs-extra');
 var getPort = require('get-port');
 var routes = require('./config/routes.js');
@@ -63,23 +62,9 @@ async function readConfig(remixRoot, serverMode = serverModes.ServerMode.Product
   let appConfig = {};
 
   if (configFile) {
-    let appConfigModule;
-
     try {
-      var _appConfigModule;
-
-      // shout out to next
-      // https://github.com/vercel/next.js/blob/b15a976e11bf1dc867c241a4c1734757427d609c/packages/next/server/config.ts#L748-L765
-      if (process.env.NODE_ENV === "test") {
-        // dynamic import does not currently work inside of vm which
-        // jest relies on so we fall back to require for this case
-        // https://github.com/nodejs/node/issues/35889
-        appConfigModule = require(configFile);
-      } else {
-        appConfigModule = await import(url.pathToFileURL(configFile).href);
-      }
-
-      appConfig = ((_appConfigModule = appConfigModule) === null || _appConfigModule === void 0 ? void 0 : _appConfigModule.default) || appConfigModule;
+      let appConfigModule = await import(configFile);
+      appConfig = (appConfigModule === null || appConfigModule === void 0 ? void 0 : appConfigModule.default) || appConfig;
     } catch (error) {
       throw new Error(`Error loading Remix config at ${configFile}\n${String(error)}`);
     }
diff --git a/node_modules/@remix-run/dev/dist/config/format.js b/node_modules/@remix-run/dev/dist/config/format.js
index e1ebeeb..b0b3ccd 100644
--- a/node_modules/@remix-run/dev/dist/config/format.js
+++ b/node_modules/@remix-run/dev/dist/config/format.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/config/routes.d.ts b/node_modules/@remix-run/dev/dist/config/routes.d.ts
index f87306e..b375c5d 100644
--- a/node_modules/@remix-run/dev/dist/config/routes.d.ts
+++ b/node_modules/@remix-run/dev/dist/config/routes.d.ts
@@ -44,6 +44,12 @@ export interface DefineRouteOptions {
      * Should be `true` if this is an index route that does not allow child routes.
      */
     index?: boolean;
+    /**
+     * An optional unique id string for this route, that will be appended to the file
+     * name e.g: `<file-name>--<id>`. Use this if you need to aggregate two or more
+     * routes with the same route file.
+     */
+    id?: string;
 }
 interface DefineRouteChildren {
     (): void;
diff --git a/node_modules/@remix-run/dev/dist/config/routes.js b/node_modules/@remix-run/dev/dist/config/routes.js
index 5bf6165..6efd7e9 100644
--- a/node_modules/@remix-run/dev/dist/config/routes.js
+++ b/node_modules/@remix-run/dev/dist/config/routes.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
@@ -65,11 +65,12 @@ function defineRoutes(callback) {
       options = optionsOrChildren || {};
     }
 
+    let fileId = createRouteId(file);
     let route = {
       path: path ? path : undefined,
       index: options.index ? true : undefined,
       caseSensitive: options.caseSensitive ? true : undefined,
-      id: createRouteId(file),
+      id: options.id ? `${fileId}--${options.id}` : fileId,
       parentId: parentRoutes.length > 0 ? parentRoutes[parentRoutes.length - 1].id : undefined,
       file
     };
diff --git a/node_modules/@remix-run/dev/dist/config/routesConvention.js b/node_modules/@remix-run/dev/dist/config/routesConvention.js
index 53b70c2..9f72532 100644
--- a/node_modules/@remix-run/dev/dist/config/routesConvention.js
+++ b/node_modules/@remix-run/dev/dist/config/routesConvention.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/config/serverModes.js b/node_modules/@remix-run/dev/dist/config/serverModes.js
index 0148352..fc7fc5c 100644
--- a/node_modules/@remix-run/dev/dist/config/serverModes.js
+++ b/node_modules/@remix-run/dev/dist/config/serverModes.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/env.js b/node_modules/@remix-run/dev/dist/env.js
index 94604b6..28ddc5f 100644
--- a/node_modules/@remix-run/dev/dist/env.js
+++ b/node_modules/@remix-run/dev/dist/env.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/index.js b/node_modules/@remix-run/dev/dist/index.js
index ee5da6d..1417091 100644
--- a/node_modules/@remix-run/dev/dist/index.js
+++ b/node_modules/@remix-run/dev/dist/index.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/invariant.js b/node_modules/@remix-run/dev/dist/invariant.js
index edf22a0..03dd14b 100644
--- a/node_modules/@remix-run/dev/dist/invariant.js
+++ b/node_modules/@remix-run/dev/dist/invariant.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/logging.js b/node_modules/@remix-run/dev/dist/logging.js
index 74628e0..2261c3f 100644
--- a/node_modules/@remix-run/dev/dist/logging.js
+++ b/node_modules/@remix-run/dev/dist/logging.js
@@ -1,5 +1,5 @@
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *
diff --git a/node_modules/@remix-run/dev/dist/modules.d.ts b/node_modules/@remix-run/dev/dist/modules.d.ts
index 87516fe..4bc9a62 100644
--- a/node_modules/@remix-run/dev/dist/modules.d.ts
+++ b/node_modules/@remix-run/dev/dist/modules.d.ts
@@ -3,10 +3,6 @@ declare module "*.aac" {
     let asset: string;
     export default asset;
 }
-declare module "*.avif" {
-    let asset: string;
-    export default asset;
-}
 declare module "*.css" {
     let asset: string;
     export default asset;
@@ -23,14 +19,6 @@ declare module "*.gif" {
     let asset: string;
     export default asset;
 }
-declare module "*.gql" {
-    let asset: string;
-    export default asset;
-}
-declare module "*.graphql" {
-    let asset: string;
-    export default asset;
-}
 declare module "*.jpeg" {
     let asset: string;
     export default asset;
@@ -73,10 +61,6 @@ declare module "*.png" {
     let asset: string;
     export default asset;
 }
-declare module "*.sql" {
-    let asset: string;
-    export default asset;
-}
 declare module "*.svg" {
     let asset: string;
     export default asset;
@@ -109,7 +93,3 @@ declare module "*.webmanifest" {
     let asset: string;
     export default asset;
 }
-declare module "*.zip" {
-    let asset: string;
-    export default asset;
-}
diff --git a/node_modules/@remix-run/dev/dist/server-build.js b/node_modules/@remix-run/dev/dist/server-build.js
index 062a341..8c5c44d 100644
--- a/node_modules/@remix-run/dev/dist/server-build.js
+++ b/node_modules/@remix-run/dev/dist/server-build.js
@@ -1,6 +1,6 @@
 #!/usr/bin/env node
 /**
- * @remix-run/dev v1.7.0
+ * @remix-run/dev v1.6.7
  *
  * Copyright (c) Remix Software Inc.
  *

```

</details>



kiliman: @runmoore The third parameter to the `route` function is a callback where you can define your child routes. Looks like if you're using the `{ id }` options, then the callback is the fourth parameter.
```ts
routes(defineRoutes) {
    return defineRoutes((route) => {
      route('/vols', 'routes/flights.tsx', { id: 'flights-fr-fr' }, () => {... child routes }});
    });
  },
runmoore: @kiliman like this? I've tested it locally, and it works, but the nested routing is really confusing me.

```js
routes(defineRoutes) {
    return defineRoutes((route) => {
      route(
        '/vols', 'routes/flights.tsx', { id: 'flights-root-fr-fr' },
        () => {
          route('/vols', 'routes/flights/index.tsx', { id: 'flights-fr-fr' });
          route('/vols/a-propos', 'routes/flights/about/index.tsx', { id: 'flights-about-fr-fr' },
          );
        },
      );
    });
  },
  ```
 
runmoore: Thanks @kiliman, this is very useful, especially about the undocumented `index: true`. I have more questions, and to avoid derailling this PR, i've started a discussion on discord https://discord.com/channels/770287896669978684/1025080466488954914/1025080466488954914
lucasferreira: > Perhaps docs is the blocker here? Maybe a commented example as part of https://remix.run/docs/en/v1/api/conventions#routes would help?

Hi @AndrewLeedham I really don't know whey this new feature/fix didn't got the "appeal" that deserves (IMHO).

I was thinking to write some docs update, but I don't even know if "core teams" likes my changes and if they think that is the right way to apply multiple routes solution, so I will wait a little more before work on this again.
lucasferreira: > Hey folks - sorry we are busy with some other things at the moment, but I think we were waiting on the change to remove the `${fileId}--${options.id}` logic based on [this discussion](https://github.com/remix-run/remix/pull/3970#discussion_r977715196)? Can we get that updated to use the `id` verbatim, and then start throwing an error if a user manually specifies duplicate ids? And some tests to assert that behavior would be great too!

Hi @brophdawg11 🤘

Changing the `id` logic it's really easy to do here, but I was wait for you and @jacob-ebey to indicates me what's the better place to put this Error throwing/duplicate check, maybe in `packages/remix-dev/config/routes.ts` or in `packages/remix-dev/compiler/assets.ts`?

`throw new Error(...)` or `invariant` call when found some dupe? 
AndrewLeedham: > > Hey folks - sorry we are busy with some other things at the moment, but I think we were waiting on the change to remove the `${fileId}--${options.id}` logic based on [this discussion](https://github.com/remix-run/remix/pull/3970#discussion_r977715196)? Can we get that updated to use the `id` verbatim, and then start throwing an error if a user manually specifies duplicate ids? And some tests to assert that behavior would be great too!
> 
> Hi @brophdawg11 🤘
> 
> Changing the `id` logic it's really easy to do here, but I was wait for you and @jacob-ebey to indicates me what's the better place to put this Error throwing/duplicate check, maybe in `packages/remix-dev/config/routes.ts` or in `packages/remix-dev/compiler/assets.ts`?
> 
> `throw new Error(...)` or `invariant` call when found some dupe?

I would have thought something like:

```typescript
    if (options.id && options.id in routes) {
      throw new Error(
        `You tried to define a route with id "${options.id}" but one already exists. ` +
          "Custom route ids must be unique"
      );
    }
```
in `packages/remix-dev/config/routes.ts` would make sense, as from what I can tell that is run before assets, so would always throw at runtime.
brophdawg11: @lucasferreira I'd say error as early as possible, which should be in `defineRoutes`.  That's where we'd inadvertently overwrite previous routes via `routes[route.id] = route` 👍 

lucasferreira: > @lucasferreira I'd say error as early as possible, which should be in `defineRoutes`. That's where we'd inadvertently overwrite previous routes via `routes[route.id] = route` 👍

Hi @brophdawg11 and @AndrewLeedham ,

I followed the indicated instructions here in my last commit, now the custom ID it's 100% customizable and we are checking for dupes inside `routes.ts`. I have also written some tests to check this error catch in case that some duplicate route are set.

But now we have some conflict in `assets.ts` file, as I could see something changed in this file in the last commits, something about the `getRouteModuleExportsCached`, but I couldn't solve this conflict cause we don't have automatic merge available.

@brophdawg11 could you help us in that?
AndrewLeedham: > > @lucasferreira I'd say error as early as possible, which should be in `defineRoutes`. That's where we'd inadvertently overwrite previous routes via `routes[route.id] = route` 👍
> 
> Hi @brophdawg11 and @AndrewLeedham ,
> 
> I followed the indicated instructions here in my last commit, now the custom ID it's 100% customizable and we are checking for dupes inside `routes.ts`. I have also written some tests to check this error catch in case that some duplicate route are set.
> 
> But now we have some conflict in `assets.ts` file, as I could see something changed in this file in the last commits, something about the `getRouteModuleExportsCached`, but I couldn't solve this conflict cause we don't have automatic merge available.
> 
> @brophdawg11 could you help us in that?

Could you add remix as an upstream remote locally and do a git merge or rebase?
lucasferreira: > 
> Could you add remix as an upstream remote locally and do a git merge or rebase?

Hi @AndrewLeedham I really don't know how to do that 😫

I'm working only in my fork in dev branch, is it easy to find how to do this rebase thing? I'm not git expert =/

AndrewLeedham: > 

Hi @lucasferreira. I would usually do this from the command-line, if you are using a GUI tool there may be a way to do it there. The command-line way is as follows:

1. Add remix as a remote, you can call it what you want "upstream" is a convention:
    ```
    git remote add upstream https://github.com/remix-run/remix
    ```
2. Then pull the git information for the remote:
    ```
    git fetch upstream
    ```
3. Finally either merge or rebase the remote dev branch into your branch:
    - Merge 
        ```
        git merge upstream/dev
        ```
    - Rebase
        ```
        git rebase upstream/dev
        ```

Hope that helps :)
lucasferreira: That's was more easy than expected! Thank you very much @AndrewLeedham! 
lucasferreira: Hi @brophdawg11 anything left for me to do here and help this PR?
brophdawg11: @lucasferreira Do you mind adding a changeset?  There are instructions in https://github.com/remix-run/remix/pull/3970#issuecomment-1209910225 but the gist of it is run `yarn changeset`, choose your changed packages (`@remix-run/dev`), and then choose a `minor` bump since this is new functionality.  Then commit and push the added changeset file.  Thanks!

lucasferreira: > @lucasferreira Do you mind adding a changeset? There are instructions in [#3970 (comment)](https://github.com/remix-run/remix/pull/3970#issuecomment-1209910225) but the gist of it is run `yarn changeset`, choose your changed packages (`@remix-run/dev`), and then choose a `minor` bump since this is new functionality. Then commit and push the added changeset file. Thanks!

Done!
brophdawg11: Thanks @lucasferreira!

Patch:
diff --git a/.changeset/big-spoons-grab.md b/.changeset/big-spoons-grab.md
new file mode 100644
index 000000000..ab0ddcd25
--- /dev/null
+++ b/.changeset/big-spoons-grab.md
@@ -0,0 +1,5 @@
+---
+"@remix-run/dev": minor
+---
+
+allow defining multiple routes for the same route module file
diff --git a/contributors.yml b/contributors.yml
index 54b97030a..18c8c6b36 100644
--- a/contributors.yml
+++ b/contributors.yml
@@ -257,6 +257,7 @@
 - lpsinger
 - lswest
 - lucasdibz
+- lucasferreira
 - luispagarcia
 - luisrivas
 - luistak
diff --git a/packages/remix-dev/compiler/assets.ts b/packages/remix-dev/compiler/assets.ts
index af02d8323..60be5b6da 100644
--- a/packages/remix-dev/compiler/assets.ts
+++ b/packages/remix-dev/compiler/assets.ts
@@ -56,10 +56,13 @@ export async function createAssetsManifest(
     config.appDirectory,
     config.entryClientFile
   );
-  let routesByFile: Map<string, Route> = Object.keys(config.routes).reduce(
+  let routesByFile: Map<string, Route[]> = Object.keys(config.routes).reduce(
     (map, key) => {
       let route = config.routes[key];
-      map.set(route.file, route);
+      map.set(
+        route.file,
+        map.has(route.file) ? [...map.get(route.file), route] : [route]
+      );
       return map;
     },
     new Map()
@@ -83,22 +86,27 @@ export async function createAssetsManifest(
         /(^browser-route-module:|\?browser$)/g,
         ""
       );
-      let route = routesByFile.get(entryPointFile);
-      invariant(route, `Cannot get route for entry point ${output.entryPoint}`);
-      let sourceExports = await getRouteModuleExports(config, route.id);
-      routes[route.id] = {
-        id: route.id,
-        parentId: route.parentId,
-        path: route.path,
-        index: route.index,
-        caseSensitive: route.caseSensitive,
-        module: resolveUrl(key),
-        imports: resolveImports(output.imports),
-        hasAction: sourceExports.includes("action"),
-        hasLoader: sourceExports.includes("loader"),
-        hasCatchBoundary: sourceExports.includes("CatchBoundary"),
-        hasErrorBoundary: sourceExports.includes("ErrorBoundary"),
-      };
+      let groupedRoute = routesByFile.get(entryPointFile);
+      invariant(
+        groupedRoute,
+        `Cannot get route(s) for entry point ${output.entryPoint}`
+      );
+      for (let route of groupedRoute) {
+        let sourceExports = await getRouteModuleExports(config, route.id);
+        routes[route.id] = {
+          id: route.id,
+          parentId: route.parentId,
+          path: route.path,
+          index: route.index,
+          caseSensitive: route.caseSensitive,
+          module: resolveUrl(key),
+          imports: resolveImports(output.imports),
+          hasAction: sourceExports.includes("action"),
+          hasLoader: sourceExports.includes("loader"),
+          hasCatchBoundary: sourceExports.includes("CatchBoundary"),
+          hasErrorBoundary: sourceExports.includes("ErrorBoundary"),
+        };
+      }
     }
   }
 
diff --git a/packages/remix-dev/config/routes.ts b/packages/remix-dev/config/routes.ts
index 9d97158d0..7f1e5696e 100644
--- a/packages/remix-dev/config/routes.ts
+++ b/packages/remix-dev/config/routes.ts
@@ -54,6 +54,12 @@ export interface DefineRouteOptions {
    * Should be `true` if this is an index route that does not allow child routes.
    */
   index?: boolean;
+
+  /**
+   * An optional unique id string for this route. Use this if you need to aggregate
+   * two or more routes with the same route file.
+   */
+  id?: string;
 }
 
 interface DefineRouteChildren {
@@ -141,7 +147,7 @@ export function defineRoutes(
       path: path ? path : undefined,
       index: options.index ? true : undefined,
       caseSensitive: options.caseSensitive ? true : undefined,
-      id: createRouteId(file),
+      id: options.id || createRouteId(file),
       parentId:
         parentRoutes.length > 0
           ? parentRoutes[parentRoutes.length - 1].id
@@ -149,6 +155,12 @@ export function defineRoutes(
       file,
     };
 
+    if (route.id in routes) {
+      throw new Error(
+        `Unable to define routes with duplicate route id: "${route.id}"`
+      );
+    }
+
     routes[route.id] = route;
 
     if (children) {


Test patch:
diff --git a/packages/remix-dev/__tests__/defineRoutes-test.ts b/packages/remix-dev/__tests__/defineRoutes-test.ts
index d4766d004..dbd73350d 100644
--- a/packages/remix-dev/__tests__/defineRoutes-test.ts
+++ b/packages/remix-dev/__tests__/defineRoutes-test.ts
@@ -87,4 +87,80 @@ describe("defineRoutes", () => {
       }
     `);
   });
+
+  it("allows multiple routes with the same route module", () => {
+    let routes = defineRoutes((route) => {
+      route("/user/:id", "routes/index.tsx", { id: "user-by-id" });
+      route("/user", "routes/index.tsx", { id: "user" });
+      route("/other", "routes/other-route.tsx");
+    });
+
+    expect(routes).toMatchInlineSnapshot(`
+      Object {
+        "routes/other-route": Object {
+          "caseSensitive": undefined,
+          "file": "routes/other-route.tsx",
+          "id": "routes/other-route",
+          "index": undefined,
+          "parentId": undefined,
+          "path": "/other",
+        },
+        "user": Object {
+          "caseSensitive": undefined,
+          "file": "routes/index.tsx",
+          "id": "user",
+          "index": undefined,
+          "parentId": undefined,
+          "path": "/user",
+        },
+        "user-by-id": Object {
+          "caseSensitive": undefined,
+          "file": "routes/index.tsx",
+          "id": "user-by-id",
+          "index": undefined,
+          "parentId": undefined,
+          "path": "/user/:id",
+        },
+      }
+    `);
+  });
+
+  it("throws an error on route id collisions", () => {
+    // Two conflicting custom id's
+    let defineNonUniqueRoutes = () => {
+      defineRoutes((route) => {
+        route("/user/:id", "routes/user.tsx", { id: "user" });
+        route("/user", "routes/user.tsx", { id: "user" });
+        route("/other", "routes/other-route.tsx");
+      });
+    };
+
+    expect(defineNonUniqueRoutes).toThrowErrorMatchingInlineSnapshot(
+      `"Unable to define routes with duplicate route id: \\"user\\""`
+    );
+
+    // Custom id conflicting with a later-defined auto-generated id
+    defineNonUniqueRoutes = () => {
+      defineRoutes((route) => {
+        route("/user/:id", "routes/user.tsx", { id: "routes/user" });
+        route("/user", "routes/user.tsx");
+      });
+    };
+
+    expect(defineNonUniqueRoutes).toThrowErrorMatchingInlineSnapshot(
+      `"Unable to define routes with duplicate route id: \\"routes/user\\""`
+    );
+
+    // Custom id conflicting with an earlier-defined auto-generated id
+    defineNonUniqueRoutes = () => {
+      defineRoutes((route) => {
+        route("/user", "routes/user.tsx");
+        route("/user/:id", "routes/user.tsx", { id: "routes/user" });
+      });
+    };
+
+    expect(defineNonUniqueRoutes).toThrowErrorMatchingInlineSnapshot(
+      `"Unable to define routes with duplicate route id: \\"routes/user\\""`
+    );
+  });
 });