Conversation
1ee276a to
95ca8da
Compare
…ectRoot(projectRootPath)
| // TODO: export `binPaths` from `rescript` package so that we don't need to | ||
| // copy the logic for figuring out `target`. | ||
| const target = `${process.platform}-${process.arch}`; | ||
| const targetPackagePath = path.join(rescriptDir, "..", `@rescript/${target}/bin.js`) | ||
| const { binPaths } = await import(targetPackagePath); |
There was a problem hiding this comment.
Unfortunately I couldn't just do import(rescriptDir) to get bin paths as the rescript package only exports ./lib/ and ./package.json in the exports field of its package.json.
We probably either want to export ./common/bins.js or have a default export that reexports binPaths.
As for @rescript/${target}, I had to append /bin.js to the import path for it to work as, like rescript, the per-platform binary packages have no default export.
There was a problem hiding this comment.
Oh, you're right. I didn't re-export it because I wasn't sure the API from the compiler (it will be the first programmatic API, so...)
There was a problem hiding this comment.
As for @rescript/${target}, I had to append /bin.js to the import path for it to work as, like rescript, the per-platform binary packages have no default export.
There is the exports field. Importing the binary package without the /bin.js suffix should also work.
Don't forget to use the right compilerOptions.nodeResolution option in the tsconfig.json. Use NodeNext as long as possible, or Bundler.
There was a problem hiding this comment.
Don't forget to use the right compilerOptions.nodeResolution option in the tsconfig.json. Use NodeNext as long as possible, or Bundler.
Ah I didn't realise we were bundling as CJS, this explains the error messages I was getting when trying to import without bin.js. I'll have a go at tweaking compilerOptions.nodeResolution to make this work 👍
There was a problem hiding this comment.
I tried the following:
compilerOptions.moduleResolutionvaluesNodeNextandBundler- Updating typescript to v5.8.3
- ES2022 instead of ES1029
but I still can't get it to work :(
There was a problem hiding this comment.
This is still WIP, right? Or could we merge this and do the above in a follow up?
There was a problem hiding this comment.
We can improve the dynamic import path in a followup PR 👍
| ResponseMessage, | ||
| } from "vscode-languageserver-protocol"; | ||
| import fs from "fs"; | ||
| import fsAsync from "fs/promises"; |
There was a problem hiding this comment.
In a later PR we might want to replace sync fs functions with their promise-based alternatives.
| }, | ||
| "devDependencies": { | ||
| "@types/node": "^14.14.41", | ||
| "@types/semver": "^7.7.0", |
There was a problem hiding this comment.
I added semver to make parsing the rescript version easier.
If adding this dependency is fine, then I can also refactor incrementalCompilation.figureOutBscArgs and utils.runAnalysisAfterSanityCheck to use it.
rescript-vscode/server/src/utils.ts
Lines 211 to 220 in f4ba829
There was a problem hiding this comment.
I've done the proposed refactoring in this commit: d4cc19d
|
VSCode supports ESM-based extensions since very recently. If we bump the target version and use fewer legacy dependencies, we can entirely switch to ESM. Which accepts a fully asynchronous program, including top-level await, without bundler magic or TDZ-related bugs. |
| // Can't use the native bsb/rescript since we might need the watcher -w | ||
| // flag, which is only in the JS wrapper | ||
| binaryPath = path.join(rescriptDir, rescriptJSWrapperPath) | ||
| } else if (semver.gte(rescriptVersion, "12.0.0-alpha.13")) { |
There was a problem hiding this comment.
AFAIK, npm's default semver comparison doesn't work intuitively with pre-releases. This might need the includePrelease flag.
There was a problem hiding this comment.
You're right that we'll need that flag for range matching, so I added it in another place where we're checking major version numbers:
For semver.gte(rescriptVersion, "12.0.0-alpha.13") it won't be needed as we're not doing a range comparison.
|
Thank you for all this hard work! |
f5bb3c6 to
28f1170
Compare
28f1170 to
22bff6d
Compare
| // If ReScript < 12.0.0-alpha.13, then we want `{project_root}/node_modules/rescript/{c.platformDir}/{binary}`. | ||
| // Otherwise, we want to dynamically import `{project_root}/node_modules/rescript` and from `binPaths` get the relevant binary. | ||
| // We won't know which version is in the project root until we read and parse `{project_root}/node_modules/rescript/package.json` |
zth
left a comment
There was a problem hiding this comment.
Looks great, thank you very much! Let me know if this is good to merge as is or if there are ongoing things that need to be handled first.
|
Thanks 😄 I'm happy for this to be merged as-is. We can try to figure out how to improve the dynamic import path in a followup PR 👍 |
|
@mediremi awesome! One last thing - mind adding a changelog? |
|
Changelog entry added 👍 |
|
Amazing work @mediremi! |
I made
utils.findBinaryasync in order to allow us to get binary paths by dynamically importing therescriptpackage in the project root.Every upstream function that needs to be async due to this change has been converted as well.
I've tested this on a v11 and a v12 project and everything seems to work fine.