Псевдонимы пути в машинописном тексте не разрешаются правильно во время выполнения
Я использую VS Code, и сейчас я пытаюсь настроить псевдонимы для своего проекта машинописного текста.
Моя установка dev основана на 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);
});
Однако я получаю сообщение об ошибке: "Не удается найти модуль '@shared/debug/Print.class'" на "cross-env NODE_ENV=development nodemon ts-node ./src/server.ts".
И вот где я стою.
Теперь я прочитал несколько вопросов и ответов по SO, и кажется, что даже если бы мне удалось заставить псевдонимы работать в dev, он потерпел неудачу в производстве, так как я запускаю из папки Typescript src, и мои результаты построены в dist? Если да, есть ли способ исправить это? Большое спасибо
5 ответов
Проблема заключалась в разрешении псевдонимов путей к узлам во время выполнения. Даже если машинописный текст был выполнен во время выполнения ts-узлом, псевдонимы не могли быть разрешены узлом как есть. (Я думаю)
Но это была только верхушка айсберга. Я столкнусь с этим позже при моей настройке jest и во время выполнения JS.
Мне нужно было найти способ интерпретировать мои псевдонимы для каждой среды выполнения. Было несколько пакетов npm, но многие из них требовали дополнительных объявлений.
И я не хотел объявлять свои псевдонимы во всех файлах конфигурации, которые у меня были, и зависеть только от моего файла tsconfig.
После долгих испытаний осталось только два модуля узла для установки tsconfig-paths для выполнения машинописного текста на ts-узле. И @ef-carbon/tspm для преобразования моих псевдонимов в пункт назначения сборки.
npm i -D tsconfig-paths @ef-carbon/tspm
Для ts-узла сценарий был изменен как:
ts-node -r tsconfig-paths/register ./src/server.ts
Для вашего скомпилированного js вам нужно только запустить:
ef-tspm
Для шутки нужен ts-jest, он у меня уже был, но настроен неправильно. Я использовал встроенный помощник, чтобы настроить свои пути. Мой файл конфигурации 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. Но пока этого достаточно.
Я столкнулся с той же проблемой, и решение CrazyYoshi не работает должным образом в моем случае.
Я исправил это, поместив этот код в tsconfig.json:
{
"ts-node": {
// Do not forget to `npm i -D tsconfig-paths`
"require": ["tsconfig-paths/register"]
}
}
Документация: https://typestrong.org/ts-node/docs/paths/
Вы используетеts-node
иnodemon
для запуска вашего кода, поэтому вы должны добавить это в свойtsconfig.json
файл:
{
"ts-node": {
"require": ["tsconfig-paths/register"]
}
}
А затем установитьtsconfig-paths/register
как зависимость от разработчиков.
npm install --save-dev tsconfig-paths
Рекомендации
март 2023 г.
Просто потратил буквально часы, пытаясь заставить это работать. В конце концов я полностью отказался от ts-node и установил tsx , который работал прямо из коробки.
Судя по всему, это в конечном итоге появится в ts-node, хотя PR выглядит мертвым, так что кто знает:
https://github.com/TypeStrong/ts-node/pull/1585
Между тем, если вы действительно хотите использовать ts-node, вам может пригодиться следующее:
https://www.npmjs.com/package/@bleed-believer/path-alias
https://github.com/TypeStrong/ts-node/issues/1007
https://github.com/TypeStrong/ts-node/discussions/1450#discussioncomment-1806115
Я думаю, вы можете использовать пакет, называемый для решения этой проблемы.
Во-первых, установите его с помощью yarn, npm или pnpm, выберите тот, который вы используете.
Затем добавьте тот же псевдоним в свой
package.json
как:
{
"_moduleAliases": {
"@shared": "./src/shared",
"@modules": "./src/modules"
}
}
Наконец, для импорта
module-alias/register
в вашей первой строке (это важно)!
import 'module-alias/register'
// ... your other code
Это адрес г.module-alias
Вы можете обратиться к нему.
Я надеюсь, что мой ответ поможет вам решить эту проблему.