remix
remix copied to clipboard
Routes is not detected if the file is symlink
What version of Remix are you using?
1.7.5
Steps to Reproduce
Initialize the project.
npx @remix-run/[email protected] create ./remix-symlink
# ? What type of app do you want to create? Just the basics
# ? Where do you want to deploy? Choose Remix App Server if you're unsure; it's easy to change deployment targets.
# Cloudflare Workers
# ? TypeScript or JavaScript? TypeScript
# ? Do you want me to run `npm install`? Yes
cd ./remix-symlink
Make routes/index.tsx symlink.
mv app/routes app/routes_orig
mkdir app/routes
ln -s ${PWD}/app/routes_orig/index.tsx ${PWD}/app/routes/index.tsx
Show detected routes
npx remix routes --json
Expected Behavior
The routes that is symlink is detected
❯ npx remix routes --json
[
{
"id": "root",
"path": "",
"file": "root.tsx",
"children": [
{
"id": "routes/index",
"index": true,
"file": "routes/index.tsx"
}
]
}
]
Actual Behavior
routes/index.tsx is not detected as routes even though it exists.
❯ npx remix routes --json
[
{
"id": "root",
"path": "",
"file": "root.tsx"
}
]
This is due to https://github.com/remix-run/remix/blob/main/packages/remix-dev/config/routesConvention.ts#L214 using fs.lstatSync:
function visitFiles(
dir: string,
visitor: (file: string) => void,
baseDir = dir
): void {
for (let filename of fs.readdirSync(dir)) {
let file = path.resolve(dir, filename);
let stat = fs.lstatSync(file);
if (stat.isDirectory()) {
visitFiles(file, visitor, baseDir);
} else if (stat.isFile()) {
visitor(path.relative(baseDir, file));
}
}
}
lstatSync stats the link itself, not the file/dir it references, so both the isDirectory() and isFile() calls return false. Switching to statSync would follow the link.
This is an easy enough PR (I did a separate PR on routesConvention.ts yesterday so it's fresh in my mind), I just don't know if there's a reasoning behind not wanting to follow symlinks?
Nice. One of my first attempts to sharing route files was to use symlinks. Thanks for figuring out why Remix wasn't following links.
Converting this to a Proposal discussion, as per our Development Process.