HoudiniGraphql/houdini

Houdini vite plugin makes the svelte lsp crash

SeppahBaws opened this issue · 11 comments

Describe the bug

Whenever there's a <style> tag somewhere in some Svelte code, while using postcss (for tailwindcss) and houdini, the svelte LSP crashes.

After debugging the svelte LSP itself, the crash seemed to come from vite itself, which led me to believe that somewhere in Houdini's vite plugin it does something wrong, which makes the LSP crash with the following error:

Preprocessing failed
TypeError [
	.my-custom-class {
		margin-top: 2rem;
	}
]: [postcss] Expected array buffer, or typed array to be returned for the "source" from the "transformSource" function but got null.
    at new NodeError (node:internal/errors:406:5)
    at assertBufferSource (node:internal/modules/esm/translators:84:9)
    at stringify (node:internal/modules/esm/translators:94:3)
    at createCJSModuleWrap (node:internal/modules/esm/translators:219:12)
    at ModuleLoader.commonjsStrategy (node:internal/modules/esm/translators:301:10)
    at callTranslator (node:internal/modules/esm/loader:273:14)
    at ModuleLoader.moduleProvider (node:internal/modules/esm/loader:278:30)
    at async link (node:internal/modules/esm/module_job:76:21) {
  code: '\r\n\t.my-custom-class {\r\n\t\tmargin-top: 2rem;\r\n\t}\r\n',
  loc: { file: undefined, line: undefined, column: NaN },
  __source: 'Style'
}

Reproduction

https://github.com/SeppahBaws/houdini-postcss-svelte-lsp-crash

I have a similar error, where my postcss config is not being loaded correctly if houdini is included in the vite config:

Error: ENOENT: no such file or directory, open 'file:///Users/francis/project/postcss.config.cjs'
    at Object.openSync (node:fs:575:18)
    at Object.func [as openSync] (node:electron/js2c/node_init:2:2214)
    at readFileSync (node:fs:454:35)
    at t.readFileSync (node:electron/js2c/node_init:2:9900)
    at filesystem.readFileSync (file:///Users/francis/project/node_modules/houdini-svelte/build/plugin-esm/index.js:172562:10)
    at getSourceSync (node:internal/modules/esm/load:84:17)
    at getSource (node:internal/modules/esm/translators:72:10)
    at createCJSModuleWrap (node:internal/modules/esm/translators:282:32)
    at ModuleLoader.commonjsStrategy (node:internal/modules/esm/translators:365:10)
    at callTranslator (node:internal/modules/esm/loader:272:14)] {
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: 'file:///Users/francis/project/postcss.config.cjs',
  __source: 'Style'
}

I suspect it might be a language server change. I have rolled back my repository to over a year ago, when this problem was not occurring, and it still happens with packages installed as they were at that time. I first noticed this happening about a month ago.

Edit: yes, it is, downgrading to vscode 1.89.1 (april 2024) works fine. I will investigate and see exactly which version causes this problem.

Edit: @SeppahBaws @AlecAivazis I can confirm that this problem was introduced with the vscode 1.90.0 update.

@fnimick huh so the complete same package-lock and all, but just a different vs code version? Very curious...

Yep, you can try yourself, download 1.89.1 from https://code.visualstudio.com/updates/v1_89 after disabling automatic updates in your settings, and everything works fine.

I did some testing with the svelte extension, forcing the use of a svelte language server I manually installed. I rolled back its version and the svelte version repeatedly but couldn't find one that works.

I suspect it's due to the node version change. 1.90.2 uses 20.9.0, and 1.89.1 which works uses 18.18.2

I can confirm that the node update from 18.x to 20.x is the problem. In the extension, set the language server runtime to a node 18.x executable, and it works with the previous crashing version 1.90.x and the latest version of vscode, 1.92.0.

Edit: actually, this is incredibly strange! Setting the language server runtime to the same version, 20.9.0, installed elsewhere outside of vscode also fixes the problem. And the new vscode release with 20.14.0 still exhibits the problem if you don't set an external runtime for the svelte language server.

I've found the issue: the nodejs version running in electron can't load files beginning with the file:/// path. Logging all files loaded by the language server using readFileSync:

/Users/francis/project/.env
/Users/francis/project/package.json
/Users/francis/project/.env
/Users/francis/project/package.json
/Users/francis/project/.env
file:///Users/francis/project/postcss.config.cjs

If I monkey patch the houdini build to remove all file:/// paths, it works fine.

hmmm I wonder....

return ['win32', 'win64'].includes(os.platform()) ? 'file:///' + target : target

Found the problem. The issue is with the patch to fs.readFileSync in

const filepath = fp.toString()

Most of the time, the input is a string - but sometimes, it's an object such as:

URL {
  href: 'file:///Users/francis/project/postcss.config.cjs',
  origin: 'null',
  protocol: 'file:',
  username: '',
  password: '',
  host: '',
  hostname: '',
  port: '',
  pathname: '/Users/francis/project/postcss.config.cjs',
  search: '',
  searchParams: URLSearchParams {},
  hash: ''
}

Calling .toString() on this generates a file:/// prefixed URL which does not work with the node runtime bundled with electron.

@SeppahBaws I can confirm that my issues with language server crashes are all fixed with 1.2.54 - can you confirm as well?

I already checked it earlier with your branch and everything seemed to be working, but I'll double check tomorrow at work 👍
Edit: @fnimick yep it's working correctly now