使用pm2 + ts-node部署koa+ts项目产生的问题

使用pm2部署koa+ts项目产生的问题

项目背景:

  1. 使用Koa+ts装饰器模式
  2. pm2执行命令:"start": "export NODE_ENV=prod&& pm2 start --interpreter ./node_modules/.bin/ts-node ./src/app.ts --name app -i 2 --watch"
  3. 服务器CentOS7.4版本,安装node16.17.0版本
  4. 我的tsconfig.json文件如下
    {
      "compilerOptions": {
        "target": "ES5",
        "useDefineForClassFields": false,
        "module": "CommonJS",
        "rootDir": "./src",
        "outDir": "./tsbuild",
        "moduleResolution": "Node",
        "allowJs": true,
        "strict": true,
        "sourceMap": true,
        "baseUrl": ".",
        "resolveJsonModule": true,
        "isolatedModules": true,
        "esModuleInterop": true,
        "lib": ["ESNext", "DOM"],
        "skipLibCheck": true,
        "noEmit": true,
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true,
        "paths": {
          "@/*": ["src/*"]
        }
      },
      "include": ["src/**/*.ts", "src/**/*.d.ts"]
    }
    

问题1:在执行npm run start的时候,会一直报一个Error:(21, 3) TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option in your 'tsconfig' or 'jsconfig' to remove this warning.
分析1:自己项目的根目录tsconfig.json确实有设置experimentalDecorators,但是问题就在于未生效,可是经过测试,在tsconfig.json修改部分属性是可以生效的,导致我误以为tsconfig.json是生效的,这也是我疑惑的点,可是经过测试就是ts-node在运行的时候没有读取到我们的tsconfig.json的配置,难道是默认使用tsconfig.json和我们的tsconfig.json有个默认合并规则吗,这里我的实力还无法验证。
解决1:得想个办法让pm2在运行ts-node使用到我们根目录的tsconfig.json配置文件,这里原始的pm2.config.js配置文件为

module.exports = {
  apps: [
    {
      name: 'app',
      script: 'src/app.ts',
      watch: true,
      ignore_watch: ['logs', 'node_modules'],
      out_file: 'logs/out/out.log',
      error_file: 'logs/error/error.log',
      interpreter: './node_modules/.bin/ts-node',
      interpreter_args: '-P ./server -r tsconfig-paths/register',
      instances: 1,
      autorestart: true,
      exec_mode: 'cluster',
      env: {
        NODE_ENV: 'dev', // prod
        port: '3000', // 3001
      },
    },
  ],
}

执行脚本"pmconf": "pm2 start pm2.config.js",这里会引出其他问题,比如WARNING: TO LOAD AN ES MODULE, SET “TYPE“: “MODULE“ IN THE PACKAGE.JSON OR USE THE .MJS EXTENSION.,然后会引出其他问题,然后继续深入又是修改tsconfig.json和package.json的数据,最后还是无法解决问题,这里修改更正一个有效的pm2.config.js配置文件,使用script属性和args属性代替interpreter和interpreter_args属性,同时需要自行安装一下npm i tsconfig-paths这个库

module.exports = {
  apps: [
    {
      name: 'app',
      // script: 'src/app.ts',
      watch: true,
      ignore_watch: ['logs', 'node_modules'],
      out_file: 'logs/out/out.log',
      error_file: 'logs/error/error.log',
      // interpreter: './node_modules/.bin/ts-node',
      script: './node_modules/.bin/ts-node',
      args: '-T -r tsconfig-paths/register ./src/app.ts',
      instances: 1,
      autorestart: true,
      exec_mode: 'cluster',
      env: {
        NODE_ENV: 'dev', // prod
        port: '3000', // 3001
      },
    },
  ],
}

最后装饰器的问题都解决了,参考配置如下
"pmconf": "pm2 start ecosystem.config.js",

// pm2.config.js
module.exports = {
  apps: [
    {
      name: 'app',
      // script: 'src/app.ts',
      watch: true,
      ignore_watch: ['logs', 'node_modules'],
      out_file: 'logs/out/out.log',
      error_file: 'logs/error/error.log',
      // interpreter: './node_modules/.bin/ts-node',
      script: './node_modules/.bin/ts-node',
      args: '-T -r tsconfig-paths/register ./src/app.ts',
      instances: 1,
      autorestart: true,
      exec_mode: 'cluster',
      env: {
        NODE_ENV: 'dev', // prod
        port: '3000', // 3001
      },
    },
  ],
}
// tsconfig.json
{
  "compilerOptions": {
    "target": "ES5",
    "useDefineForClassFields": false,
    "module": "CommonJS",
    "rootDir": "./src",
    "outDir": "./tsbuild",
    "moduleResolution": "Node",
    "allowJs": true,
    "strict": true,
    "sourceMap": true,
    "baseUrl": ".",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "esModuleInterop": true,
    "lib": ["ESNext", "DOM"],
    "skipLibCheck": true,
    "noEmit": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "paths": {
      "@/*": ["src/*"]
    }
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts"]
}

自己补充的一个类装饰器的点

export function Controller(modulePath: string = '/') {
  console.log('进入装饰器类')
  return function (targetClass: { new (...args: any): any }) {
    // 使用下面的方式获取请求上的方法名时,Object.keys(targetClass.prototype)获取的值是[],导致我们的Controller的方法压根没有注册到路由中去
    Object.keys(targetClass.prototype).forEach((methodName) => {
    })
    // 使用下面的方式获取的才是Controller中的各种方法组成的数组
    Object.keys(Object.getOwnPropertyDescriptors(targetClass.prototype)).filter(
      (item) => item !== 'constructor'
    )
  }
}
  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值