Open lavcraft opened 1 year ago
I'll need to look into this more as it's been a while since I've seen this kind of issue, but really quick off the top of my head (and on my phone): setting rootDir: "src/"
in tsconfig
was often the solution with directory placement.
If the rootDir
is up a directory, that would make sense why src
is in the typings. In this case, it seems like it might be defaulting to the root of the monorepo?
Workspaces (I don't think I've used NPM's variant of them before) and project references could complicate things a bit though.
I'll come back with more details and previous issue references. EDIT: See https://github.com/ezolenko/rollup-plugin-typescript2/issues/275#issuecomment-1107881058
EDIT2: nvm, the rootDir
is correct, see below comment
Oh there are indeed some complications in your case. I see you have configured TS paths
, and that it goes up two directories. That would indeed set your rootDir
to be packages
.
Unfortunately, aliases are not truly supported by TS. #201 has pretty significant details and several workarounds to support aliases. IIRC, there are some related issues on monorepos specifically that I might be able to pull up as well (#237 is one)
Using one of those workarounds can probably fix your issue. Also not sure if @shared
is meant to be compiled in or meant as a separate external
package reference when published.
Thanks for your comment @agilgur5
According comment about rootDir - try it and what will happen when i set rootDir (previously deleted because found some recommendation in issues)
rootDir
Problem — different behaviour with tsc and rollupTry to use
npm run -w @project/sdk build
npm run -w @project/sdk rollup
In rollup variant number 2 we will see next error:
[!] (plugin rpt2) RollupError: src/actions/create.ts:1:20 - error TS6059: File '<...>/rollup-ws-problem/packages/shared/src/test/util.ts' is not under 'rootDir' '<...>/rollup-ws-problem/packages/sdk/src'. 'rootDir' is expected to contain all source files.
But in tsc variant number 1 - it works fine
I can avoid this mistake when delete rootDir
Thanks for this workarounds: https://github.com/ezolenko/rollup-plugin-typescript2/issues/237 https://github.com/ezolenko/rollup-plugin-typescript2/issues/201
But in my opinion my example highlight another kind of problem. I try to process resulting declarations, but it's hard, because located in strange directories (also located strange dir when i set declarationDir, but also copied into declaration dir with <workspace_dir>/src
prefix)
I guess it's not reliable behaviour (i may be wrong). I am trying to find a consistent solution to avoid problems in the future.
In my example with rollup, shared workspace sources are inlined into the resulting sdk perfectly. But types have some problems, because previously when i have used @rollup/plugin-typescript
, I process resulting d.ts files via dts plugin with respectExternal
prop and inline all my shared d.ts into sdk project and replace paths in declarations. But with typescript2 this workaround doesn't work
@agilgur5 could you help me with one more advice for avoiding excess .d.ts files generation in <workspace_dir_name/src/*/.d.ts dirs? Workarounds from previous message related to other issues or not working in this case i guess
In rollup variant number 2 we will see next error:
[!] (plugin rpt2) RollupError: src/actions/create.ts:1:20 - error TS6059: File '<...>/rollup-ws-problem/packages/shared/src/test/util.ts' is not under 'rootDir' '<...>/rollup-ws-problem/packages/sdk/src'. 'rootDir' is expected to contain all source files.
Sorry, I probably should have clarified in my second comment that you could ignore my first comment after I saw you actually are trying to import from a sibling directory. I've hid both of our comments on that to cause less confusion. Will also hide this comment.
Will respond in a separate comment to the rest.
In my example with rollup, shared workspace sources are inlined into the resulting sdk perfectly. inline all my shared d.ts
Ah ok, so you are trying to in-line the JS without in-lining the types? Or in-line both? In-lining both is what rpt2 is currently doing in your repro example.
In your repro example, you might notice that npm run -w @project/sdk build
, the tsc
variant, just treats @shared
as an external:
// create.js
import { test } from "@shared/test/util";
export function create(user) {
console.log(`user = ${user}`);
test(() => { });
}
tsc
will not in-line @shared
and does not produce declarations for @shared
, as that's a separate project.
With Rollup, you can mark @shared
as an external
to not in-line it.
Unfortunately, however, rpt2 is still producing declarations for @shared
. I was able to get it to not produce declarations for @shared
when I added it to rpt2's exclude
, however it still outputs sdk
's declarations in build/sdk/src/
.
~I spent a good amount of time trying to debug this and unfortunately hit a bit of a wall~ 😕
~This seems to be because rpt2's internal TS LanguageService
is still interpreting your rootDir
as packages
instead of sdk/src
.
I was able to confirm that by setting rootDir: 'src/'
and then tracing the error with verbosity: 3
. rpt2 is getting an error during semantic diagnostics on create.ts
, which it leaves entirely up to the TS LanguageService
.~
~So for some reason the LanguageService
is interpreting your project reference differently from tsc
. Unfortunately, the LanguageService
API is barely documented, so folks writing TS compiler integrations (like rpt2) have to effectively "reverse engineer" some of the behavior. This seems to be one of those instances where we have to do that, as it's unclear why it's acting differently right now when given the same tsconfig
.
I dug into the TS Compiler source code a bit but this area of it is really dense with variables referencing variables referencing variables in a very long and deep chain.~
~As a note, it had this behavior even when I removed the aliases and just manually referenced the other project, so this does not seem to be due to integration with TS paths
.~
EDIT: It actually was due to the paths
aliases 😕 . See below comment.
~Given the significant analysis / reverse-engineering and debugging this requires, I don't think this will be solved soon (unless someone happens to make a really good guess). As such, I would recommend using a workaround for now~
OH. I got it to work.
As a note, it had this behavior even when I removed the aliases and just manually referenced the other project, so this does not seem to be due to integration with TS
paths
.
It seems like it may indeed be paths
related. Specifically, I changed your paths
to use the output directory, shared/build/*
, instead of shared/src/*
:
"paths": {
"@shared/*": [
- "../../shared/src/*"
+ "../../shared/build/*"
]
}
and then it worked with no other changes needed 😮
it output .js
and .d.ts
to build/actions
and build/models
with no extra build/sdk/src
directory for the declarations.
adding /@shared/
to external
will get rid of the Rollup warning as well.
EDIT: sent a PR with fixes: https://github.com/lavcraft/rollup-typescript-project-references-example-problems/pull/1
@agilgur5 yes, main purpose is inlining both - js and .d.ts. But secondary - simply build and make it more reliable (across versions and updates). That mean, i wan't to use ts project reference for use rollup dev mode
and auto build dependencies and caching. If i change paths.@shared
from ../../shared/src/*
to ../../shared/build/*
i miss this ability
I believe - separate code into sub projects — provide more understandable project structure without limits
In my opinion, current behaviour in my example contain only one thing, that should be fixed for purposes. And how it can be achieved in manual way:
npm run -w @project/sdk rollup
build/sdk/src
and build/shared/src
to appropriate build
dir.This problem looks like rpt2 plugin doesn't add sources from referenced projects into rootDirs set, however compile and build related files
That mean, i wan't to use ts project reference for use rollup
dev mode
and auto build dependencies and caching. If i changepaths.@shared
from../../shared/src/*
to../../shared/build/*
i miss this ability
So I responded in https://github.com/lavcraft/rollup-typescript-project-references-example-problems/pull/1#issuecomment-1630010944, but this was working fine for me.
use rollup
dev mode
Not sure what you meant by this, but Rollup can't really process project references the same way tsc
can. That requires starting two Rollup processes and having two rollup.config.js
. rpt2, as a Rollup plugin, cannot do that itself -- that would be out-of-scope.
yes, main purpose is inlining both - js and .d.ts.
So in this case, the current behavior is correct. The common rootDir
between shared
and sdk
is one directory up, in packages
. So TS is calculating the common rootDir
correctly and outputting declarations based on that rootDir
, giving you the sdk/src/
and shared/src
directories for declarations. I wrote this in https://github.com/lavcraft/rollup-typescript-project-references-example-problems/pull/1#issuecomment-1630010944 as well.
This problem looks like rpt2 plugin doesn't add sources from referenced projects into rootDirs set
I'm not sure what you mean by this. As far as I know, TS itself does not add project references into rootDirs
either? Those are separate configurations.
Either way, rpt2 passes your tsconfig
directly to TS (with a few changes for Rollup compatibility, as stated in the README).
In my opinion, current behaviour in my example contain only one thing, that should be fixed for purposes.
Sorry, what is the "one" problem that remains? It seems like everything is working as intended in your list
So I responded in https://github.com/lavcraft/rollup-typescript-project-references-example-problems/pull/1#issuecomment-1630010944, but this was working fine for me.
It works only if shared project builded. In this way, i need to run independent process for building shared project, and then — rebuild sdk project when build/*js was changed. I want to simplify project build with ts project reference, but this thing with src -> build in paths nullifies efforts
Not sure what you meant by this, but Rollup can't really process project references the same way tsc can. That requires starting two Rollup processes and having two rollup.config.js. rpt2, as a Rollup plugin, cannot do that itself -- that would be out-of-scope.
Sure. It's main goal — avoid complex build with multiple process, and replace it with project references. I use comparison with tsc only for d.ts generating, because:
Sorry, what is the "one" problem that remains? It seems like everything is working as intended in your list
Sorry, i mean problem with types :) And if i try to fix it with your workaround, unfortunately, nullifies profit from typescript project reference and need to run two rollup process for each project and manage it manually (because in paths i must reference into build dir instead of src)
Try to a new way:
I can adopt to new types structure with next package.json types:
"typesVersions": {
"*": {
"*": [
"build/sdk/src/*",
"build/shared/src/*",
"build/sdk/src/*/index.d.ts",
"build/shared/src/*/index.d.ts"
]
}
}
@agilgur5 could you advice, how process types in sdk/src
and shared/src
directories for replace @shared alias in sdk/src/**/*.d.ts
?
Found this solution — https://github.com/ezolenko/rollup-plugin-typescript2/issues/201#issuecomment-1014261983 But i dont't understand how use this tscAlias function. My question:
Troubleshooting
My reproducible example - https://github.com/lavcraft/rollup-typescript-project-references-example-problems
You need
Follow to next instructions
tsc
have the same output? If so, please explain why this is incorrect behaviorRun
npm run -w @project/sdk build
- tsc variant works fine and generate d.ts files into correct directoriesI guess order is correct:
My example - https://github.com/lavcraft/rollup-typescript-project-references-example-problems Follow to README or read next lines:
Two commands for feel difference between tsc and rollup in my case:
TSC baseline
npm run -w @project/sdk build
- tsc variantAll d.ts files existed in right location (except d.ts from project from project reference, but it is ok for tsc i guess)
Rollup variant
rm -rf packages/sdk/build && npm run -w @project/sdk rollup
Created to excess directories with typings - sdk and shared
Please help me to explain right behaviour or workaround. Because my next step is apply dts plugin for obtain valid d.ts files without internal paths. But some difficulties happened when all this d.ts located in strange directories :)
Environment
Versions
```js import commonjs from '@rollup/plugin-commonjs'; import {nodeResolve} from '@rollup/plugin-node-resolve'; import typescript2 from 'rollup-plugin-typescript2'; import fs from 'fs'; import path from 'path'; import * as url from 'url'; const __dirname = url.fileURLToPath(new URL('.', import.meta.url)); /** * @type {import('rollup').RollupOptions} */ const config = { input: { ...files('actions'), ...files('models'), }, output: { sourcemap: true, dir: 'build', preserveModules: false, format: 'esm' }, plugins: [ nodeResolve(), typescript2({ // build: true, // useTsconfigDeclarationDir: true, // declarationDir: './types', }), // commonjs(), ], external: [ 'undici', 'querystring', 'mobx', 'mobx-react-lite', 'mobx-utils', 'react', ], watch: { chokidar: true, exclude: ['build/**', '**/*.d.ts', '**/*.js'] } }; function files(dir = '.', exclude = ['__tests__']) { return fs .readdirSync(path.resolve(__dirname, `src/${dir}`)) .reduce((prev, current) => { if (exclude.includes(current)) return prev; const targetName = current.replace('.ts', ''); prev[`${dir}/${targetName}`] = `./src/${dir}/${current}`; return prev; }, {}); } export default [config]; ```
:rollup.config.js