deepkit-framework
deepkit-framework copied to clipboard
`type-compiler` installation does not account for multiple Typescript versions when using `pnpm`
When using pnpm
as the package manager, any given package and version is installed only once and then symlinked, at least within a project or workspace. In the monorepo/workspace setting in particular, it is easy to end up with having packages use a variety of Typescript versions.
The deepkit-type-install
script does find the correct version when run from a project, but the injected code is set up such that it will end up using the root project's version by default.
This is due to order of the require
statements in the try-catch
block: https://github.com/deepkit/deepkit-framework/blob/c1d6c415199804d966ce17ceb235a050de011da3/packages/type-compiler/install-transformer.ts#L23-L27
Which for me ends up looking like (after fixing the Windows error described in #356):
try {
// This `require` statement is called from the symlinked module,
// so Node resolves it to the root project's version. In my case, pnpm had
// mapped the root version to:
// `node_modules/.pnpm/@[email protected][email protected]/node_modules/@deepkit/type-compiler`
// (Note that `4.8.1-rc` in the middle of that path)
typeTransformer = require('@deepkit/type-compiler');
} catch (error) {
// This path points directly to the correct module
typeTransformer = require('../../../../@[email protected][email protected]/node_modules/@deepkit/type-compiler/dist/cjs');
}
Simply flipping these statements resolves the issue, and I can't think of a reason why that wouldn't also work for npm
. It seems to make sense to attempt the very explicit import path first before falling back on Node's general import-resolution strategy, anyway.
The updated source would be changed to:
try {
typeTransformer = require('${deepkitDistPath}');
} catch (error) {
typeTransformer = require('@deepkit/type-compiler');
}
I would describe this as a major issue because it makes installation fragile and unpredictable in pnpm-managed monorepos. In particular, Deepkit currently does not work with Typescript 4.8+, and so the fact that Deepkit requires specific Typescript versions makes it particularly important that it properly handle the presence of multiple Typescript versions in a single workspace.
Isn't this solved by using Node's --preserve-symlinks? Then @deepkit/type-compiler
should be resolved correctly (I haven't tested it though)
Simply flipping these statements resolves the issue, and I can't think of a reason why that wouldn't also work for npm
Because it would break with two local packages using pnpm. The relative path would only work for one package, the other will use @deepkit/type-compiler
.