rpt2 does not resolve pnpm symlinked dependencies
See original GitHub issueWhat happens and why it is wrong
When trying to build a project installed with pnpm
, rpt2
fails to resolve the created symlinked dependencies in node_modules
(non-flat).
Setting check: false
is (arguably) a workaround.
Reproduction
Repository: https://github.com/davelsan/rpt2-pnpm-symlinks Config: https://github.com/davelsan/rpt2-pnpm-symlinks/blob/master/rollup.config.js
The provided repro is a minimal vue3
plugin that imports the App
interface from vue
in index.ts
import { App } from 'vue'
This import causes the following error on build:
[!] (plugin rpt2) Error: semantic error TS2305: Module '"../node_modules/vue/dist/vue"' has no exported member 'App'.
Setting the check
option to false
in rollup.config.js
eliminates the error.
Versions
- typescript: 4.2.3
- rollup: 2.41.5
- rollup-plugin-typescript2: 0.30.0
rollup.config.js
import path from 'path';
import rpt2 from 'rollup-plugin-typescript2';
import pkgJson from './package.json';
export default {
input: './src/index.ts',
external: ['vue'],
plugins: [
rpt2({
check: true,
tsconfig: path.resolve(__dirname, 'tsconfig.json'),
})
],
output: [
{
file: pkgJson.browser, // dist/index.esm.js
format: 'es',
sourcemap: true,
},
],
}
tsconfig.json
A snippet with the relevant module resolution options only.
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
}
}
package.json
A snippet with the relevant dependencies only.
{
"peerDependencies": {
"vue": "^3.0.7"
},
"devDependencies": {
"rollup": "^2.41.5",
"rollup-plugin-typescript2": "^0.30.0",
"typescript": "^4.2.3",
"vue": "^3.0.7"
}
}
Issue Analytics
- State:
- Created 3 years ago
- Reactions:2
- Comments:17 (1 by maintainers)
Top Results From Across the Web
rpt2 does not resolve pnpm symlinked dependencies - - Bountysource
When trying to build a project installed with pnpm , rpt2 fails to resolve the created symlinked dependencies in node_modules (non-flat). Setting check:...
Read more >Symlinked `node_modules` structure - PNPM
This article only describes how pnpm's node_modules are structured when there are no packages with peer dependencies. For the more complex scenario of ......
Read more >pnpm/pnpm - Gitter
they are not used by default because symlinks on Windows require admin ... Hi, this is just a symlink, dependencies of pretender won't...
Read more >@pnpm/symlink-dependency - npm
Start using @pnpm/symlink-dependency in your project by running `npm i ... There are 5 other projects in the npm registry using ...
Read more >Error: EPERM: operation not permitted, mkdir 'C:\Users\Chirag' Code ...
//I ran the command. 7. //C:/Users/NANDIN~1/AppData/Roaming/npm-cache" --global. 8. . 9. HOPE THIS WILL WORK BECAUSE ITS THE ONLY REASON OF YOUR QUERY.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Fixed the issue!
So I believe I’ve found a fix for this long-standing issue! See #332
Notes on root cause analysis / debugging
Red herring to look at
resolveId
hook etcIt was helpful to see this previous research, but this seemed to be a bit of a red herring… I’ll explain shortly.
This issue doesn’t list “plugin output with
verbosity: 3
” as requested in the issue template, but #330 did, and I confirmed the fix in its reproduction. I also took the reproduction here and addedverbosity: 3
and confirmed it had very similar logs. I also confirmed (by locally editing rpt2 innode_modules
) that the fix works for this reproduction as well.Notably, the logs don’t output anything about “resolving”, so the bug here isn’t in the
resolveId
hook at all. Which is why looking atresolve
etc was a red herring. That portion of the code also resolves directly with TS and withtsModule.sys
as its host. As I found out later,ts.sys
has a default implementation ofrealpath
, which turns out to be the important missing piece here.Error is in
transform
hook actuallyIt actually errors right after the “transpiling” log statement, which means the error is actually in the
transform
hook, specifically ingetEmitOutput
, which is implemented by TS and doesn’t have host-specific code for it… But apparently it seems to relyhost.realpath
under-the-hood.Implementing
host.realpath
fixes thisSo I tried implementing
host.realpath
(as #332 shows), and then everything worked and the type-error disappeared! The typings were generated correctly as well now (#330 had broken typings when usingcheck: false
).TS docs on Compiler APIs leave a lot to be desired… 😕 😞
The TS docs are incredibly sparse when it comes to Compiler integrations such as this plugin. The Compiler API basically has two small docs/examples in the TS Wiki… and that’s it. Notably, there is no mention of
realpath
what-so-ever in either of those.Honestly the root cause of a lot of TS integration issues can come down to poor documentation of the Compiler API, which has been noted in lots of places. As a result, this requires even more significant domain knowledge to figure out issues like this, as the docs aren’t even helpful – I had to literally read through the Compiler source code… and have had to do that a handful of times in the past too. That’s obviously not ideal, though at least we can do something like that in open-source.
Basically you need to be a TS Compiler subject matter expert to figure out some of these things, and I’m not sure I would even call myself that despite being a regular contributor to the TS tooling ecosystem (compilers are huge after all!).
Note on Other Rollup TS plugins
I’m honestly not sure how these plugins manage to get around this issue as neither of them implement
host.realpath
I’ve mentioned this elsewhere, but why I decided to contribute here (and now I help maintain this repo) as opposed to
rollup-plugin-ts
is because this repo was significantly simpler to wrap my head around.rollup-plugin-ts
has quite a lot of features – which is great! But it also means that one actually needs even more domain knowledge of its structure to contribute.@rollup/plugin-typescript
historically wasn’t well maintained (that’s why this fork came into existence after all), but is quite a bit better maintained nowadays.I believe all 3 plugins (including this one) have different approaches toward various problems, so unfortunately the code can differ quite a bit. And all 3 plugins have their own sets of bugs and features too 😕
Shared core tooling would be great!
I’d love for TS tooling to use more shared packages though where the approach is the same!
E.g. the
host
implementation andtsconfig
parsing are two areas that could probably be de-duped; I’m personally working on this in my very limited free time (and notably I started contributing here during my time solo-maintaining TSDX, so already investing upstream). Shared packages and composition are especially useful for complicated and poorly documented subareas of TS (or any codebase that needs significant domain knowledge for that matter).(one example of composition would be running
rollup-plugin-dts
on top of this plugin or@rollup/plugin-typescript
vs. usingrollup-plugin-ts
’s built-in custom transformer for declaration bundling. Both of these have their own issues / bugs too – TS doing this itself would be the ideal, then the whole ecosystem benefits and can use it!)Misc
false
is actually the default ofresolve
, Rollup itself, TS itself, which all reflect how Node itself treats symlinks (i.e.require.resolve
). And that was a red herring anywayI also think we may not need
resolve
as a dep at all since we can use built-in Node methods (resolve
was originally created forbrowserify
after all).Released in 0.32.0 🎉