Typescript:在使用符号链接时解决相对导入路径

huangapple go评论82阅读模式
英文:

Typescript: resolve relative import path when using symlinks

问题

这似乎是一个愚蠢的问题,但我很难找到答案。

情况

这是我的文件夹结构:

myProject/
├── module1/
│   ├── config.ts
│   └── init.ts #符号链接
├── module2/
│   ├── config.ts
│   └── init.ts #符号链接
└── symlinks/
    └── init.ts #真实的非重复文件

文件 init.js 如下方式导入本地文件:

import config from './config';

// ...

问题

问题是 TypeScript 报错 Cannot find module './config' or its corresponding type declarations

我尝试了调整 TypeScript 选项 preserveSymlinks 但没有解决我的问题

我知道其他实现我的目标的方式,但对于只有一个文件来说,这有点过于复杂,并且不解决依赖于相对路径的问题(例如创建一个 npm 模块,创建一个函数并将相对文件内容传递为参数,甚至在运行时生成文件...)

=> 我正在一个 monorepo 中使用 typescript

是否可能以这种方式使用符号链接?如果不行,是否有其他(简单的)替代方法?

编辑: 我创建了 这个示例存储库,您可以将其用作实验的基础。

英文:

This seems like a dumb question, but I struggle to find the answer.

The situation

Here is my folder structure:

myProject/
├── module1/
│   ├── config.ts
│   └── init.ts #symlink
├── module2/
│   ├── config.ts
│   └── init.ts #symlink
└── symlinks/
    └── init.ts # the real not duplicated file

The file init.js import local files like so:

import config from './config'

// ...

The problem

The problem is that typescript throws Cannot find module './config' or its corresponding type declarations

I tried playing with typescript option preserveSymlinks but it didn't solve my problem

I know about other ways to achieve my goal but it's overkill for just one file and it doesn't solve relaying on a relative path (like creating a npm module, creating a function and pass relative file content as parameter or even generating files at runtime...)

=> I am working with typescript in a monorepo.

Is it possible to use symlinks this way? If no, are there other (simple) alternatives?

EDIT: I have made this example repo, you can use it as a base for experiments

答案1

得分: 1

默认情况下,TypeScript 根据文件的物理路径而不是跟随任何符号链接后的解析路径来解析模块。所以在你的情况下,当你尝试从 ./config 导入 config 时,TypeScript 会在物理路径 myProject/module1/config.tsmyProject/module2/config.ts 查找文件,但实际上它位于 myProject/symlinks/config.ts

你可以通过在 tsconfig.json 文件中将 resolveSymlinks 选项设置为 true 来告诉 TypeScript 根据解析后的路径来解析模块:

{
  "compilerOptions": {
    // ...
    "resolveSymlinks": true
  },
  // ...
}

这将导致 TypeScript 在解析模块时跟随符号链接,因此应该能够找到你的 config 文件。请注意,如果你使用像 Webpack 这样可能更改解析路径的工具,你可能还需要将 preserveSymlinks 设置为 true

另一个选项是在 tsconfig.json 文件中使用模块别名,将 ./config 路径映射到正确的位置。例如:

{
  "compilerOptions": {
    // ...
    "baseUrl": ".",
    "paths": {
      "*": ["*", "symlinks/*"]
    }
  },
  // ...
}

这将告诉 TypeScript 在 symlinks 目录中查找所有模块,以及它们的原始位置。然后,你可以像这样导入 config

import config from 'module1/config';

这应该可以正常工作,无论 init.ts 是符号链接还是常规文件。

英文:

By default, TypeScript resolves modules based on the physical path of the file, not the resolved path after following any symbolic links. So, in your case, when you try to import config from ./config, TypeScript looks for the file at the physical path myProject/module1/config.ts or myProject/module2/config.ts, but it's actually located at myProject/symlinks/config.ts.

You can tell TypeScript to resolve modules based on the resolved path by setting the resolveSymlinks option to true in your tsconfig.json file:

{
  "compilerOptions": {
    // ...
    "resolveSymlinks": true
  },
  // ...
}

This will cause TypeScript to follow symbolic links when resolving modules, so it should be able to find your config file. Note that you may also need to set preserveSymlinks to true if you're using tools like Webpack that may alter the resolved path.

Another option is to use module aliases in your tsconfig.json file to map the ./config path to the correct location. For example:

{
  "compilerOptions": {
    // ...
    "baseUrl": ".",
    "paths": {
      "*": ["*", "symlinks/*"]
    }
  },
  // ...
}

This will tell TypeScript to look for all modules in the symlinks directory, as well as in their original locations. Then, you can import config like this:

import config from 'module1/config';

This should work regardless of whether init.ts is a symlink or a regular file.

huangapple
  • 本文由 发表于 2023年1月9日 23:59:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/75059874.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定