【问题标题】:Cannot find module that is defined in tsconfig `paths`找不到在 tsconfig `paths` 中定义的模块
【发布时间】:2019-11-01 04:37:14
【问题描述】:

我正在尝试为我的模拟服务器设置别名。每当我尝试编译 ts 文件时,它都会返回错误,即即使在 tsconfig,json->paths 中定义了正确的模块,它也找不到合适的模块。

文件夹结构:

├── server
│   └── src
│       └──/json
├── src
│   └──/modules
├── tsconfig.json

这是我的tsconfig.json

{
    "compilerOptions": {
        "baseUrl": "./src",
        "experimentalDecorators": true,
        "jsx": "react",
        "lib": [
            "dom",
            "es2015",
            "es2015.promise"
        ],
        "module": "commonjs",
        "moduleResolution": "node",
        "noImplicitAny": true,
        "noUnusedLocals": true,
        "esModuleInterop": true,
        "paths": {
            "@project/app/modules/*": [
                "modules/*"
            ],
            "@project/server/data/*": [
                "../server/src/json/*"
            ]
        },
        "sourceMap": true,
        "target": "es5"
    },
    "exclude": [
        "node_modules",
        "tools"
    ]
}

错误: Error: Cannot find module '@project/server/data/accounts/accountsList'

【问题讨论】:

  • 它是否适用于@project/app/modules/*?
  • 不行,没有一个别名可以解析
  • 我的配置,包含指向 ['src'] 的标志。试试看。
  • 你碰巧在 webpack 中使用它吗?
  • 谢谢!最终使用 tsconfig-paths 包。

标签: typescript alias tsc tsconfig ts-node


【解决方案1】:

我遇到了同样的问题。我尝试了很多东西,现在我得到了一个适合我的解决方案。我的 Angular 项目中有一个应用程序和一个库。我想在我的应用中使用库别名。

我有以下结构:

├── projects
│   └── lib
│       └── src
│           └── lib
│               └── lib-service.ts
│           └── index.ts
│   └── app
│       └──tsconfig.app.json
├── tsconfig.json

在根文件夹的 tsconfig.json 文件中,我定义了以下路径:

"paths": {
  "my-lib": [
    "projects/lib/src/index.ts"
  ]
}

在那里我访问了一个 index.ts 文件,我在其中定义了我想要导出的内容。在我的情况下, index.ts 文件具有以下条目:

export * from './lib/lib-service';

现在我可以借助别名访问应用组件中的 LibService

import {LibService} from 'my-lib';

值得一提的是,如果我将此条目添加到 tsconfig.app.json 文件中,此解决方案将不起作用。我认为 IDE(在我的情况下为 WebStorm)在靠近根文件夹的 tsconfig.json 文件中搜索别名。所以我在我的 tsconfig.app.json

中扩展了 tsconfig.json
"extends": "../../tsconfig",

也许您必须重新启动 IDE 才能删除导入行的红色下划线。

我希望这个解决方案对你有用。您必须做更多的设置工作,因为您必须在 index.ts 文件中定义要导出的类。但在使用库的情况下,这是有意义的,因为您不想让其他应用程序看到所有内容。

【讨论】:

  • 应用程序就像一个 cham!但是打字稿在重新启动 IDE 后仍然抱怨错误:找不到模块。
  • 我不得不重新启动 VS Code 才能摆脱红色下划线!
  • @TaylorA.Leach 随机的东西,你通常可以通过在 VS 代码中重新启动 TS 服务器来摆脱红线。 cmd+shift+p 输入Restart TS Server
【解决方案2】:

经过一段时间的斗争后,我发现你需要在你的主要tsconfig.json 中包含所有使用tsconfig-paths 的目录。 tsconfig.json 文件的工作版本可能是

{
    "compilerOptions": {
        "baseUrl": ".",
...
        "paths": {
            "@project/app/modules/*": [
                "src/modules/*"
            ],
            "@project/server/data/*": [
                "server/src/json/*"
            ]
        },
    },

    "include": [
        "./src",
        "./server"
    ],
}

【讨论】:

  • 但是这样即使没有路径,它也会包含 src 中的所有文件夹。在我的项目中,我在 src 中的文件夹具有相同的名称,就像我包含的库一样。它在尝试在导入时读取本地文件夹而不是包时抱怨。
  • 它在开发模式下对我有用,但不适用于 tsc build 然后运行node dist/index.js 所以我将“dist/*”与“src/*”一起添加到路径中,键是“@/ *”,现在它可以工作了。
【解决方案3】:

以下tsconfig.json 为我工作,允许import { foo } from '@models' 等用于关联的index.ts 桶出口:

{
    "baseUrl": "./",
    "paths": {
      "@environment": ["./src/environments/environment.ts"],
      "@models": ["./src/app/shared/models/index.ts"],
      "@services": ["./src/app/shared/services/index.ts"]
    },
}

【讨论】:

    【解决方案4】:

    我的问题是我的tsconfig.app.json 扩展了我的tsconfig.json 错误地覆盖了"baseUrl" 选项。我从tsconfig.app.json 中删除了它,所以它没有"baseUrl""paths"。最后,我的tsconfig.json 有以下编译器选项:

    "baseUrl": "src/",
    "paths": {
        "@shared/*": ["shared/*"],
        "@client/*": ["client/*"],
        "@server/*": ["server/*"]
    }
    

    【讨论】:

      【解决方案5】:

      TLDR;

      npm i -D module-alias

      并将您的tsconfig.json 路径中的映射添加到您的package.json 中的_moduleAliases

      "_moduleAliases": {
        "foo": "dist"
      }
      

      至于其背后的原因,将"jsx": "react""module": "commonjs" 结合使用会阻止您使用绝对导入,即使baseUrlpaths 配置正确。详细的讨论可以在这个issue找到。

      【讨论】:

        【解决方案6】:

        TypeScript path 属性只能解析基于类型的 URL,例如接口。

        The intended behaviour is to allow TypeScript to resolve type information[1]

        我们大多数人似乎都经历过,指向实际依赖项的路径不会总是按我们预期的那样编译。尽管what the doc says,这显然是设计使然:

        {
          "compilerOptions": {
            "baseUrl": ".", // This must be specified if "paths" is.
            "paths": {
              "jquery": ["node_modules/jquery/dist/jquery"] // This mapping is relative to "baseUrl"
            }
          }
        }
        

        阅读 Mitchell Simoens 的精彩分析 - Why TypeScript Paths Failed Me

        在整个应用程序中为我的共享文件夹设置了@paths 后发现了这个。 在编译 TS 路径期间,中断和实际构建缺少各种模块。就个人而言,TS 无法以这种方式可靠地解决依赖关系,这令人非常失望。

        【讨论】:

          【解决方案7】:

          我把它放在webpack resolve alias 和 tsconfig 路径中​​,它就是这样工作的 :)

          【讨论】:

            【解决方案8】:

            路径存在一些问题,例如,如果您将路径设置为根目录,让我们说: @root/src 并且在 src 中没有 index.ts 具有默认值,那么这可能会失败...

            根据我的发现,这有点棘手。

            【讨论】:

              【解决方案9】:

              检查 angular.json 文件,如果它的 "build" -> "options" 配置将 "tsConfig" 选项设置为您更改的 tsconfig 文件。

              "architect": {
                "build": {
                  "builder": "@angular-devkit/build-angular:browser",
                  "options": {
                    "outputPath": "dist",
                    "tsConfig": "src/tsconfig.app.json",
                    "polyfills": "src/polyfills.ts",
                    "stylePreprocessorOptions": {
                      "includePaths": [
                        "src/assets/styles"
                      ]
                    },
              ............
              

              以上是我的angular.json文件,我配置为使用tsconfig.app.json。 在这种情况下,应该在 tsconfig.app.json 文件中添加“路径”。

              【讨论】:

                【解决方案10】:

                您可以像这样轻松定义简单的路径解析器:

                loader.js

                const Module = require("module");
                const originalResolveFilename = Module._resolveFilename;
                const tsConfig = require("./tsconfig.json");
                const Path = require("path");
                const fs = require('fs');
                if (!tsConfig.compilerOptions || !tsConfig.compilerOptions.baseUrl)
                    throw "Compiler options Base URL (compilerOptions.baseUrl) is required in tsconfig.json.";
                const basePath = Path.resolve(tsConfig.compilerOptions.baseUrl, tsConfig.compilerOptions.outDir);
                
                //Inspired by https://github.com/dividab/tsconfig-paths but that one does not work with VS Code
                Module._resolveFilename = function (request) {
                    if (tsConfig.compilerOptions && tsConfig.compilerOptions.paths[request] instanceof Array) { //Supports only without wildchars, but enough for our use
                        const pathsTried = [];
                        for (const reqPath of tsConfig.compilerOptions.paths[request]) {
                            const modPath = Path.resolve(basePath, reqPath) + ".js";
                            if (fs.existsSync(modPath)) return modPath;
                            pathsTried.push(reqPath);
                        }
                        throw "Module " + request + " not found, paths tried: " + pathsTried.join(", ");
                    }
                    const ret = originalResolveFilename.apply(this, arguments);
                    return ret;
                };
                

                然后从 VS Code 的 launch.json 中引用它,如下所示:

                "configurations": [
                {
                  "type": "node",
                  "request": "launch",
                  "name": "Node.js",
                  "runtimeArgs": ["-r", "./loader.js"],
                  "program": "${workspaceFolder}/run.ts",
                  "preLaunchTask": "tsc: build - tsconfig.json",
                  "outFiles": [
                    "${workspaceFolder}/out/**/*.js"
                  ]
                }]
                    
                

                它不支持paths 中的模式,但可以使用此存根添加它。

                tsconfig.json 应该是这样的:

                "compilerOptions": {
                    "outDir": "out", //required
                    "moduleResolution": "node",
                    "baseUrl": "./", //required
                    "paths": {
                        "InjectableStub": [ //requires 2
                            "myapp/myfolder/mymodule", //used in runtime
                            "./myfolder/mymodule //used in compile-time
                        ]
                    }
                }
                

                至少对我而言,tscout 中的根文件夹的名称创建子文件夹,这就是 2 次注册的原因。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-07-11
                  • 2012-07-27
                  • 1970-01-01
                  相关资源
                  最近更新 更多