Closed WillsterJohnson closed 1 year ago
I've been able to track this down to the saveSvelteMetadata
function in the SvelteKit vite plugin, with the following change;
try {
+ console.log( svelteMetadataPath )
+ console.log((await fs5.stat(svelteMetadataPath)))
+ console.log({isdir: (await fs5.stat(svelteMetadataPath)).isDirectory()})
existingSvelteMetadata = await fs5.readFile(svelteMetadataPath, "utf8" );
+ console.log("Check if the above line causes issue")
} catch {
}
This is the output;
/media/will/NVMe250/$GITHUB/@WILLSTERJOHNSON/#ARGON/node_modules/.vite/_svelte_metadata.json
Stats {
dev: 66309,
mode: 33204,
nlink: 1,
uid: 1000,
gid: 1000,
rdev: 0,
blksize: 4096,
ino: 9049681,
size: 3006,
blocks: 8,
atimeMs: 1683125873260.6162,
mtimeMs: 1683125857596.494,
ctimeMs: 1683125857596.494,
birthtimeMs: 1683117266112.142,
atime: 2023-05-03T14:57:53.261Z,
mtime: 2023-05-03T14:57:37.596Z,
ctime: 2023-05-03T14:57:37.596Z,
birthtime: 2023-05-03T12:34:26.112Z
}
{ isdir: false }
node:internal/process/promises:289
triggerUncaughtException(err, true /* fromPromise */);
^
[Error: EISDIR: illegal operation on a directory, read] {
errno: -21,
code: 'EISDIR',
syscall: 'read'
}
This is as far as I think I'm able to go, I tried casting it to a URL but that didn't change the results.
However it looks like the problem is coming from fs5.readFile
which is from Node... I haven't been able to find any workaround with relative paths either.
I've also checked that the path being pointed to exists and is a file; it does and it is;
{"compilerOptions":{"css":"external","dev":true,"hydratable":true},"configFile":false,"extensions":[".svelte"],"preprocess":[{"script":"async script({ attributes, content, filename = \"\" }) {\n const lang = attributes.lang;\n if (!supportedScriptLangs.includes(lang))\n return;\n const { code, map } = await transformWithEsbuild(content, filename, {\n loader: lang,\n target: \"esnext\",\n tsconfigRaw: {\n compilerOptions: {\n // svelte typescript needs this flag to work with type imports\n importsNotUsedAsValues: \"preserve\",\n preserveValueImports: true\n }\n }\n });\n mapToRelative(map, filename);\n return {\n code,\n map\n };\n }","style":"async ({ attributes, content, filename = \"\" }) => {\n const lang = attributes.lang;\n if (!supportedStyleLangs.includes(lang))\n return;\n if (!transform) {\n let resolvedConfig;\n if (style.__resolvedConfig) {\n resolvedConfig = style.__resolvedConfig;\n } else if (isResolvedConfig(config)) {\n resolvedConfig = config;\n } else {\n resolvedConfig = await resolveConfig(\n config,\n process.env.NODE_ENV === \"production\" ? \"build\" : \"serve\"\n );\n }\n transform = getCssTransformFn(resolvedConfig);\n }\n const suffix = `${lang_sep}${lang}`;\n const moduleId = `${filename}${suffix}`;\n const { code, map, deps } = await transform(content, moduleId);\n removeLangSuffix(map, suffix);\n mapToRelative(map, filename);\n const dependencies = deps ? Array.from(deps).filter((d) => !d.endsWith(suffix)) : void 0;\n return {\n code,\n map: map ?? void 0,\n dependencies\n };\n }"},{"script":"({ content, filename }) => {\n\t\tif (!filename) return;\n\n\t\tconst basename = path.basename(filename);\n\t\tif (basename.startsWith('+page.') || basename.startsWith('+layout.')) {\n\t\t\tconst match = content.match(options_regex);\n\t\t\tif (match) {\n\t\t\t\tconst fixed = basename.replace('.svelte', '(.server).js/ts');\n\n\t\t\t\tconst message =\n\t\t\t\t\t`\\n${colors.bold().red(path.relative('.', filename))}\\n` +\n\t\t\t\t\t`\\`${match[1]}\\` will be ignored — move it to ${fixed} instead. See https://kit.svelte.dev/docs/page-options for more information.`;\n\n\t\t\t\tif (!warned.has(message)) {\n\t\t\t\t\tconsole.log(message);\n\t\t\t\t\twarned.add(message);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}","markup":"({ content, filename }) => {\n\t\tif (!filename) return;\n\n\t\tconst basename = path.basename(filename);\n\t\tif (basename.startsWith('+layout.') && !content.includes('<slot')) {\n\t\t\tconst message =\n\t\t\t\t`\\n${colors.bold().red(path.relative('.', filename))}\\n` +\n\t\t\t\t`\\`<slot />\\` missing — inner content will not be rendered`;\n\n\t\t\tif (!warned.has(message)) {\n\t\t\t\tconsole.log(message);\n\t\t\t\twarned.add(message);\n\t\t\t}\n\t\t}\n\t}"}]}
Interestingly though, this issue doesn't happen when I try the following minimum reproduction for fs.promises.readFile
const fs = require("fs");
const path = require("path");
async function test() {
const paths = [
path.resolve(__dirname, "./$dollar/text.txt"),
path.resolve(__dirname, "./$dollar/@at/text.txt"),
path.resolve(__dirname, "./$dollar/@at/#hash/text.txt"),
path.resolve(__dirname, "./@at/text.txt"),
path.resolve(__dirname, "./@at/#hash/text.txt"),
path.resolve(__dirname, "./#hash/text.txt"),
path.resolve(__dirname, "./text.txt"),
];
for (const p of paths) {
console.log(p, ">>", await fs.promises.readFile(p, "utf8"));
}
}
test();
$: node test.js
/media/will/NVMe250/TEST/$dollar/text.txt >> text
/media/will/NVMe250/TEST/$dollar/@at/text.txt >> text
/media/will/NVMe250/TEST/$dollar/@at/#hash/text.txt >> text
/media/will/NVMe250/TEST/@at/text.txt >> text
/media/will/NVMe250/TEST/@at/#hash/text.txt >> text
/media/will/NVMe250/TEST/#hash/text.txt >> text
/media/will/NVMe250/TEST/text.txt >> text
It turns out that only the #
causes this, @
and $
are fine. The issue will show up regardless of where in the file path to the project root the #
is.
For now I'll find a different symbol to use where I'm using #
, but it would be nice if this could be resolved
If it's only the #
, it could be a Vite issue. Curious, but do you get a different behaviour between Vite 4.2 and 4.3? We changed a bit of how it handles #
. The reason why #
can be problematic is because the file paths could appear as URLs as-is, and a #
is a URL hash which makes handling it tricky.
I tried downgrading vite to @4.2
;
$: pnpm vite -v
vite/4.2.2 linux-x64 node-v19.8.1
$: pnpm vite dev
node:internal/process/promises:289
triggerUncaughtException(err, true /* fromPromise */);
^
[Error: EISDIR: illegal operation on a directory, read] {
errno: -21,
code: 'EISDIR',
syscall: 'read'
}
Node.js v19.8.1
Same issue unfortunately, it's also present in 4.0 and 4.1, and anything pre-v4 Kit isn't compatible with (ie, instant crash).
And yes, it turns out after messing around with lots of silly dir names it's only #
which causes this. It would be nice if it didn't, but I can work around it for now by using a different character.
I actually discovered this weird bug when trying to work on a Kit+Tauri project which aims to make managing local dev files easier, which I find quite ironic.
Is it possible to reproduce this in a vanilla Vite (no SvelteKit) project? It might be worth opening an issue over there, as I suspect there's nothing we can do about it on our end
yup, lots of weirdness going on in a vanilla vite project. I'll bring the issue up over there.
Describe the bug
For organisation and clarity, I've recently taken to prefixing directory names as follows;
@<name>
(eg,@sveltejs
,@willsterjohnson
)#<name>
(eg,#kit
,#adapter-auto
)$<name>
(eg,$github
,$fiction-writing
)I accept that it's a little weird, but
@#$
are all valid characters for a directory name. To put it in perspective for those of you who only use alphanumeric directory names, read the rest of this issue as if the cause of the problem was using the letterQ
in a directory name.I've been migrating from my previous messy folder structure to this structure over the last few weeks, and today is the first time I've ran a kit project from the new structure.
Unfortunately, it appears that the presence of these characters at any point in the path causes an issue when running a Kit project in
dev
mode.Reproduction
Unfortunately a repo reproduction won't do anything as this issue is directly caused by things outside of the project itself.
Run the following command chain (intended for bash - don't run this on windows);
Or do the following steps however you like;
@#$
Logs
System Info
Severity
serious, but I can work around it
Additional Information
This appears to persist regardless of;
npm create svelte
options chosenIt also only effects the
dev
command;preview
,build
,check
, etc all work correctly, as does running arbitrary JS with node.I also went into vite's bin and added dozens of
console.log
in there and in various imported files. They all logged and then theEISDIR
was thrown. This may be a Vite issue, or potentially an issue with one of Vite's or SvelteKit's dependencies which manage file operations, but I'm not familiar enough with the internals of either project to properly debug this and find the correct source of the problem.