【问题标题】:can't find right way to write typescript server app找不到编写打字稿服务器应用程序的正确方法
【发布时间】:2022-01-16 00:04:11
【问题描述】:

在编写打字稿服务器应用程序并将其编译成js进行生产时遇到问题。

TLDR - https://github.com/kricha/ts-server-test

index.ts

'use strict';

import {Server, Socket} from "socket.io";
import {App} from '@tinyhttp/app';
import {logger} from './logger';

import * as fs from 'fs';
if (!fs.existsSync('./src/test.ts')) {
    logger.error(`NOK: No  ./src/test.ts`);
}

const port = 3000;

const app = new App();
const s1 = app
    .get('/', (_, res) => void res.send('<h1>Hello World</h1>'))
    .listen(port, () => console.log(`Started on http://localhost:${port}!`));
;

const io = new Server(s1, {
    cors: {
        origin: 'localhost',
        methods: ["GET", "POST"],
        credentials: true
    }
});

io.on("connection", (socket: Socket) => {
    // ...
});

logger.info('OK: end.');
console.log('end.');

logger.ts

'use strict'

import Log4js from 'log4js';

Log4js.configure({
    appenders: {
        predictive: {
            type: 'dateFile',
            filename: 'log/predictive.log',
            pattern: 'yyyy-MM-dd',
            compress: true,
            daysToKeep: 14,
            layout: {
                type: 'pattern',
                pattern: '%d{yy-MM-dd hh:mm:ss.SSS} [%p] %m',
            },
        },
        out: {
            type: 'stdout',
            layout: {
                type: 'pattern',
                pattern: '%[%d{yy-MM-dd hh:mm:ss.SSS} [%p]%] %m',
            },
        },
        file_log: {
            type: 'logLevelFilter',
            level: 'all',
            appender: 'predictive',
        },
        console_log: {
            type: 'logLevelFilter',
            level: 'info',
            appender: 'out',
        },
    },
    categories: {
        default: {appenders: ['file_log', 'console_log'], level: 'all'},
    },
    pm2: true,
});


export const logger = Log4js.getLogger();

package.json

{
  "type": "module",
  "devDependencies": {
    "@types/node": "^16.11.12",
    "ts-node": "^10.4.0",
    "tsm": "^2.2.1",
    "typescript": "^4.5.3"
  },
  "dependencies": {
    "@tinyhttp/app": "^2.0.13",
    "log4js": "^6.3.0",
    "socket.io": "^4.4.0"
  }
}

tsconfig.json

{
    "compilerOptions": {
      "rootDir": "src",
      "outDir": "dist",
      "target": "es5",
      "lib": [
        "es2020", "DOM"
      ],
      "module": "ESNext", // (A)
      "moduleResolution": "node", // (B)
      "esModuleInterop": true,
      "strict": true,
    //   "sourceMap": true,
    //   // Needed for CommonJS modules
      "allowSyntheticDefaultImports": true, // (C)
    //   //
      "declaration": true,
    }
  }

我的问题:

  1. 无法使用require(可能没问题,我只需要重新调整)
  2. tsc 无法正确将文件编译为 js(它会在导入时跳过 .js,我无法仅使用 node dist/index.js 运行)

所以:

刚刚运行:node dist/index.js

node:internal/errors:464
    ErrorCaptureStackTrace(err);
    ^

Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/app/dist/logger' imported from /app/dist/index.js
    at new NodeError (node:internal/errors:371:5)
    at finalizeResolution (node:internal/modules/esm/resolve:416:11)
    at moduleResolve (node:internal/modules/esm/resolve:932:10)
    at defaultResolve (node:internal/modules/esm/resolve:1044:11)
    at ESMLoader.resolve (node:internal/modules/esm/loader:422:30)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:222:40)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:76:40)
    at link (node:internal/modules/esm/module_job:75:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}

运行:node --experimental-specifier-resolution=node dist/index.js 正常:

21-12-11 20:56:00.508 [ERROR] NOK: No  ./src/test.ts
21-12-11 20:56:00.528 [INFO] OK: end.
end.
Started on http://localhost:3000!

运行:node --loader tsm src/index.ts 正常:

(node:31) ExperimentalWarning: --experimental-loader is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
(node:31) DeprecationWarning: Obsolete loader hook(s) supplied and will be ignored: getFormat, transformSource
21-12-11 20:57:36.931 [ERROR] NOK: No  ./src/test.ts
21-12-11 20:57:36.948 [INFO] OK: end.
end.
Started on http://localhost:3000!

所以,问题:

  • 可能需要在 tsconfig.json 中做一些更改以更好地编译?
  • 也许我在脚本代码中做错了什么?
  • 对于 prod,它将使用 pm2 在 docker 中运行,可以吗?

使用 github 进行快速测试运行。所有这些代码都只是示例。

谢谢!

【问题讨论】:

标签: javascript node.js typescript


【解决方案1】:

这已经讨论过了here

您在 nodejs 中使用 ES 模块(由您的 package.json 中的 type 字段指定。这是一种可能导致导入问题的新语法,例如因为 ESModules 要求您从文件而不是文件夹导入(此包括文件类型)。 此外,您不能从 CommonJS 模块导入 ESModules。

所以,您正在做的是将 ESModule @tinyhttp/app 与 TypeScript 结合使用的方法。但是由于 TypeScript 语法会阻止您在导入时指定文件类型 .js(NodeJS 需要使用 module 类型),因此您必须使用标志 --es-module-specifier-resolution=node 运行 node

所以你的做法是正确的。

【讨论】:

  • 您好,我在问题中发布了相同的信息。我重复了一个问题,因为上一个问题是在 1.5 年前被问到的。我问的是我做得对还是可以纠正。谢谢。
  • @kRicha 我试图解释为什么你正在做的事情是必要的,并且确实是运行打字稿应用程序的正确方法。你还在寻找更多的东西吗?
  • 好的,因为在过去的 1.5 年里,我对这种情况没有什么新的了解,而且我正在向右移动。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-21
  • 1970-01-01
  • 2015-06-24
  • 1970-01-01
  • 1970-01-01
  • 2019-07-27
  • 2015-11-21
相关资源
最近更新 更多