TypeScript 相对导入中的符号链接未解析

rkttyhzu  于 23天前  发布在  TypeScript
关注(0)|答案(5)|浏览(16)

Bug报告

你好,我正在使用PNPM并尝试从'node_modules'导入一些内容以重用单例。但是解析机制似乎在使用符号链接时无法正常工作。

这里有一个实际的项目视频演示:
screen.mov

🔎 搜索关键词

pnpm, node_modules, 符号链接

🕗 版本与回归信息

pnpm: 5.18.7
tsc: 4.4.4

⏯ 复现方法

有一个可复现的仓库:

https://github.com/zheeeng/test-pkgs-baz

💻 代码

让我们看一下monorepo文件:
Foo包:

export type Foo = {
    method: () => string,
    str: string,
    num: number,
}

export const foo: Foo = {
    method () { return 'foo' },
    str: 'foo',
    num: 42,
}

Bar包:

import type { Foo } from 'test-pkgs-foo'

export interface Bar extends Foo {
    nil: null
}

export const bar: Bar = {
    method: () => 'bar',
    str: 'bar',
    num: 41,
    nil: null,
}

Baz包:

// **please toggle this comment:**
// import 'test-pkgs-bar'

import { Bar } from './node_modules/test-pkgs-bar'

const bar: Bar = {
    nil: null,
}

上面的注解影响了引用结果,如何确保在 Bar 包中正确引用 Foo 类型?

🙁 实际行为

Bar 类型丢失了 Foo 类型部分,因为解析失败。

🙂 预期行为

Bar 类型应该与 Foo 类型混合,并保持其自身结构。

gxwragnw

gxwragnw1#

我正在尝试使用测试来解决跟踪解析问题:
https://github.com/zheeeng/test-pkgs-baz
使用以下代码:

// please toggle this comment:
import 'test-pkgs-bar'
import { Bar } from './node_modules/test-pkgs-bar'

const bar: Bar = {
    nil: null,
}

tsc --traceResolution 打印的数字:

======== Resolving module 'test-pkgs-bar' from '/Users/zheeeng/Workspace/test-pkgs-baz/index.ts'. ========
Module resolution kind is not specified, using 'NodeJs'.
Loading module 'test-pkgs-bar' from 'node_modules' folder, target file type 'TypeScript'.
Found 'package.json' at '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-bar/package.json'.
'package.json' does not have a 'typesVersions' field.
File '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-bar.ts' does not exist.
File '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-bar.tsx' does not exist.
File '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-bar.d.ts' does not exist.
'package.json' does not have a 'typings' field.
'package.json' has 'types' field 'index.d.ts' that references '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-bar/index.d.ts'.
File '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-bar/index.d.ts' exist - use it as a name resolution result.
Resolving real path for '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-bar/index.d.ts', result '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/.pnpm/test-pkgs-bar@1.0.0/node_modules/test-pkgs-bar/index.d.ts'.
======== Module name 'test-pkgs-bar' was successfully resolved to '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/.pnpm/test-pkgs-bar@1.0.0/node_modules/test-pkgs-bar/index.d.ts' with Package ID 'test-pkgs-bar/index.d.ts@1.0.0'. ========
======== Resolving module './node_modules/test-pkgs-bar' from '/Users/zheeeng/Workspace/test-pkgs-baz/index.ts'. ========
Module resolution kind is not specified, using 'NodeJs'.
Loading module as file / folder, candidate module location '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-bar', target file type 'TypeScript'.
File '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-bar.ts' does not exist.
File '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-bar.tsx' does not exist.
File '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-bar.d.ts' does not exist.
Found 'package.json' at '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-bar/package.json'.
'package.json' does not have a 'typesVersions' field.
'package.json' does not have a 'typings' field.
'package.json' has 'types' field 'index.d.ts' that references '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-bar/index.d.ts'.
File '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-bar/index.d.ts' exist - use it as a name resolution result.
======== Module name './node_modules/test-pkgs-bar' was successfully resolved to '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-bar/index.d.ts' with Package ID 'test-pkgs-bar/index.d.ts@1.0.0'. ========
======== Resolving module 'test-pkgs-foo' from '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/.pnpm/test-pkgs-bar@1.0.0/node_modules/test-pkgs-bar/index.d.ts'. ========
Module resolution kind is not specified, using 'NodeJs'.
Loading module 'test-pkgs-foo' from 'node_modules' folder, target file type 'TypeScript'.
Directory '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/.pnpm/test-pkgs-bar@1.0.0/node_modules/test-pkgs-bar/node_modules' does not exist, skipping all lookups in it.
Found 'package.json' at '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/.pnpm/test-pkgs-bar@1.0.0/node_modules/test-pkgs-foo/package.json'.
'package.json' does not have a 'typesVersions' field.
File '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/.pnpm/test-pkgs-bar@1.0.0/node_modules/test-pkgs-foo.ts' does not exist.
File '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/.pnpm/test-pkgs-bar@1.0.0/node_modules/test-pkgs-foo.tsx' does not exist.
File '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/.pnpm/test-pkgs-bar@1.0.0/node_modules/test-pkgs-foo.d.ts' does not exist.
'package.json' does not have a 'typings' field.
'package.json' has 'types' field 'index.d.ts' that references '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/.pnpm/test-pkgs-bar@1.0.0/node_modules/test-pkgs-foo/index.d.ts'.
File '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/.pnpm/test-pkgs-bar@1.0.0/node_modules/test-pkgs-foo/index.d.ts' exist - use it as a name resolution result.
Resolving real path for '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/.pnpm/test-pkgs-bar@1.0.0/node_modules/test-pkgs-foo/index.d.ts', result '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/.pnpm/test-pkgs-foo@1.0.0/node_modules/test-pkgs-foo/index.d.ts'.
======== Module name 'test-pkgs-foo' was successfully resolved to '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/.pnpm/test-pkgs-foo@1.0.0/node_modules/test-pkgs-foo/index.d.ts' with Package ID 'test-pkgs-foo/index.d.ts@1.0.0'. ========

使用以下代码:

// please toggle this comment:
// import 'test-pkgs-bar'
import { Bar } from './node_modules/test-pkgs-bar'

const bar: Bar = {
    nil: null,
}

tsc --traceResolution 打印的数字:

======== Resolving module './node_modules/test-pkgs-bar' from '/Users/zheeeng/Workspace/test-pkgs-baz/index.ts'. ========
Module resolution kind is not specified, using 'NodeJs'.
Loading module as file / folder, candidate module location '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-bar', target file type 'TypeScript'.
File '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-bar.ts' does not exist.
File '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-bar.tsx' does not exist.
File '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-bar.d.ts' does not exist.
Found 'package.json' at '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-bar/package.json'.
'package.json' does not have a 'typesVersions' field.
'package.json' does not have a 'typings' field.
'package.json' has 'types' field 'index.d.ts' that references '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-bar/index.d.ts'.
File '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-bar/index.d.ts' exist - use it as a name resolution result.
======== Module name './node_modules/test-pkgs-bar' was successfully resolved to '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-bar/index.d.ts' with Package ID 'test-pkgs-bar/index.d.ts@1.0.0'. ========
======== Resolving module 'test-pkgs-foo' from '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-bar/index.d.ts'. ========
Module resolution kind is not specified, using 'NodeJs'.
Loading module 'test-pkgs-foo' from 'node_modules' folder, target file type 'TypeScript'.
Directory '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-bar/node_modules' does not exist, skipping all lookups in it.
File '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-foo.ts' does not exist.
File '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-foo.tsx' does not exist.
File '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-foo.d.ts' does not exist.
Directory '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/@types' does not exist, skipping all lookups in it.
Directory '/Users/zheeeng/Workspace/node_modules' does not exist, skipping all lookups in it.
Directory '/Users/zheeeng/node_modules' does not exist, skipping all lookups in it.
Directory '/Users/node_modules' does not exist, skipping all lookups in it.
Directory '/node_modules' does not exist, skipping all lookups in it.
Loading module 'test-pkgs-foo' from 'node_modules' folder, target file type 'JavaScript'.
Directory '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-bar/node_modules' does not exist, skipping all lookups in it.
File '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-foo.js' does not exist.
File '/Users/zheeeng/Workspace/test-pkgs-baz/node_modules/test-pkgs-foo.jsx' does not exist.
Directory '/Users/zheeeng/Workspace/node_modules' does not exist, skipping all lookups in it.
Directory '/Users/zheeeng/node_modules' does not exist, skipping all lookups in it.
Directory '/Users/node_modules' does not exist, skipping all lookups in it.
Directory '/node_modules' does not exist, skipping all lookups in it.
======== Module name 'test-pkgs-foo' was not resolved. ========

差异:

似乎在处理导入符号链接模块后的行为方面存在一些问题。预期的是解析为实际文件地址,而不是符号链接所在的地址。我已经尝试启用/禁用preserveSymlinks选项,但解析并没有从实际文件开始。如果从./node_modules/test-pkgs-bar导入,解析可能会将其扩展为./node_modules/.pnpm/test-pkgs-bar@1.0.0,我认为这个问题将会得到解决。对此有什么建议吗?

31moq8wy

31moq8wy2#

我们不对相对模块说明符的解析结果进行调用,这就是为什么它可以作为 "foo" 工作,但不能作为 "./node_modules/foo" 工作的原因。这种行为是有意在 #12020 中引入的,以修复 #10364 。与团队中的一些人讨论后,我们认为这可能是一个不太好的解决方案:
getCommonSourceDirectory 应该使用原始的预解析路径,就像我们的计算发射路径一样,这样可以更好地解决这个问题。

qyuhtwio

qyuhtwio3#

抱歉提及任何人,我想知道您对此问题有什么计划吗?我正在使用pnpm作为我的项目包管理器,它具有内置的monorepo功能,提供了稳定模块的结构。我想从第三方引用一些单例,它们安装在monorepo中的特定子包中。
我希望就这个问题取得任何进展,以获得正确的模块解析。

m4pnthwp

m4pnthwp4#

不,目前没有计划优先考虑这个。

yxyvkwin

yxyvkwin5#

我建议简单地提升依赖项的安装,它必须是一个单例。支持工作区的包管理器已经为您处理了这个问题。我从未见过有人声称在其他人的node_modules中的相对导入是必要的,所以我感到相当有信心,您可以使用包管理器和node_modules导入的方式来解决您的问题。

相关问题