Typescript 路径别名在运行时未正确解析

Posted

技术标签:

【中文标题】Typescript 路径别名在运行时未正确解析【英文标题】:Typescript path aliases not resolved correctly at runtime 【发布时间】:2020-05-20 20:45:41 【问题描述】:

我正在运行 VS Code,目前正在尝试在我的 typescript 项目上设置一些别名。

我的开发设置基于 nodemon 和 ts-node,代码被编译到 dist 文件夹。

到目前为止,我成功让 Typescript Hero 使用别名管理导入:

到目前为止,我的文件夹结构是:

.
└─┬ src
  ├──modules
  ├────Category
  ├────Ressource
  ├──shared
  ├────debug

// tsconfig.json

    "compilerOptions": 
        "module": "commonjs",
        "moduleResolution": "node",
        "pretty": true,
        "sourceMap": true,
        "target": "es6",
        "outDir": "./dist",
        "baseUrl": "./src",
        "paths": 
            "@shared/*": [
                "shared/*"
            ],
            "@modules/*": [
                "modules/*"
            ]
        ,
        "resolveJsonModule": true,
        "esModuleInterop": true
    ,
    "include": [
        "src/**/*.ts"
    ],
    "exclude": [
        "node_modules",
        "**/*.spec.ts",
        "**/*.test.ts",
    ]

这是第一个失败的别名导入。

//Server.ts file
import Print from '@shared/debug/Print.class';
import App from './App';

const MyApp: App = new App();

MyApp.ExpressApp.listen(MyApp.Config.ExpressPort, () => 
    Print.Log('Express server listening on port ' + MyApp.Config.ExpressPort);
);

但是,我收到一个错误:“Cannot find module '@shared/debug/Print.class'” on "cross-env NODE_ENV=development nodemon ts-node ./src/server. ts”。

这就是我的立场。

现在,我已经阅读了一些关于 SO 的 Q&A,似乎即使我设法使别名在 dev 中工作,它在生产中也会失败,因为我是从 Typescript src 文件夹中运行的,我的可交付成果是内置 dist ?如果是这样,有什么办法可以补救吗?非常感谢

【问题讨论】:

您能否确认在共享/调试文件夹中有一个 Print.class.ts 文件 我确实有这样的文件,目前它只是在开发/暂存环境中进行控制台日志。 【参考方案1】:

问题在于运行时的节点路径别名解析。即使打字稿在运行时由 ts-node 执行,别名也无法由节点按原样解析。 (我认为)

但这只是冰山一角。 稍后我会在我的玩笑设置和 JS 运行时遇到它。

我必须为我拥有的每个运行时找到一种方法来解释我的别名。有一些 npm 包,但其中很多需要更多声明。

而且我不想在我拥有的每个配置文件中声明我的别名,并且只依赖于我的 tsconfig 文件。

经过大量测试,只有两个节点模块需要安装tsconfig-paths 用于在 ts-node 上执行 typescript 运行时。 和@ef-carbon/tspm 将我的别名转换为构建目标。

npm i -D tsconfig-paths @ef-carbon/tspm

对于ts-node,脚本修改为:

ts-node -r tsconfig-paths/register ./src/server.ts

对于你的js编译,你只需要运行:

ef-tspm

开玩笑,ts-jest 是必需的,我已经有了它,但它没有正确配置。 我使用内置的助手来设置我的路径。 我的笑话配置文件现在看起来像这样:

//jest.config.js
const  pathsToModuleNameMapper  = require('ts-jest/utils');
const  compilerOptions  = require('./tsconfig');
module.exports = 
    roots: ['<rootDir>/src'],
    globals: 
        'ts-jest': 
            tsConfig: 'tsconfig.json',
            diagnostics: 
                warnOnly: true,
            ,
        ,
    ,
    clearMocks: true,
    coverageDirectory: 'coverage',
    testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$',
    moduleFileExtensions: ['js', 'json', 'jsx', 'node', 'ts', 'tsx'],
    testEnvironment: 'node',
    moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths,  prefix: '<rootDir>/src/' ),
    pathToJest: 'npm test',
    preset: 'ts-jest',
    testMatch: null,
;

这是我的脚本在我的 package.json 中的样子

  "scripts": 
    "dev:ts": "cross-env NODE_ENV=development nodemon",
    "dev:js": "cross-env NODE_ENV=development npm run start:js",
    "staging": "cross-env NODE_ENV=staging npm run start:js",
    "production": "cross-env NODE_ENV=production npm run start:js",

    "test": "cross-env NODE_ENV=testing jest --runInBand",
    "test:debug": "npm run test --detectOpenHandles",

    "start:js": "npm run build && nodemon --config nodemon-js.json",
    "build": "npm run compile && npm run post:compile && npm run copyAssets",
    "compile": "tsc",
    "post:compile": "ef-tspm",
    "copyAssets": "copyfiles -e ./src/**/*.ts -e ./src/**/*sample* -e ./src/**/*.json -u 1 ./src/**/* ./dist/"
  ,

看看情况如何,我可能会在之后添加一个 grunt/gulp 解决方案。但就目前而言,这已经足够了。

【讨论】:

ef-tspm 看起来很有希望,但它现在已存档。对于 2022 年以上的人来说,可能不是最佳选择

以上是关于Typescript 路径别名在运行时未正确解析的主要内容,如果未能解决你的问题,请参考以下文章

typescript项目配置路径别名(路径映射)

Webpack 无法正确解析我的别名

TypeScript导入路径别名

未找到 tsconfig.json 中的 TypeScript 路径别名

Typescript - 如何禁止两个解析为相同类型的类型别名互换使用?

带有 webpack 别名的 Vue-typescript 错误,找不到路径