从终端或npm bin命令执行时节点服务器的不同行为

z6psavjg  于 2023-03-12  发布在  其他
关注(0)|答案(1)|浏览(140)

所以我做了一个代理nodejs服务器,它在被调用时执行python库。
如果我直接从终端运行服务器,然后执行对服务器的调用,我会得到正确的行为:我的调用脚本等待服务器响应,然后得到预期的结果。
现在这个服务器的思想是创建一个包(A),我可以从另一个包(B)调用它。
为此,我使用包A的package.json的bin选项。

"bin": {
  "issuer": "bin/index.js"
}

其思想是,消费包(B)将启动服务器(issuer start &),然后对所述服务器执行它需要执行的任何操作。
index.js是一个入口脚本,用于使CLI更好:

#!/usr/bin/env node

const { exec } = require('child_process');
const path = require('path');

const command = process.argv[2];

if (command === 'help') {
  console.log(`
  Main invocation: issuer
  Available commands:
    - help: show help
    - start: start proxy server to python issuer
    - stop: stop server
  `)
  return;
}

if (command === 'start') {
  exec(`node ${path.join(__dirname, './start-server.js')}`, {
    cwd: path.join(__dirname, '..')
  }, (err) => {
    if (err){
      console.error(err);
    }
  });
  return;
}

if (command === 'stop') {
  exec(`node ${path.join(__dirname, './kill-server.js')}`, {
    cwd: path.join(__dirname)
  }, (err) => {
    if (err) {
      console.error(err);
    }
  });
  return;
}

console.log('issuer unknown command', command, 'run `issuer help` for a list of available commands');

js是一个简单的快速服务器创建:

#!/usr/bin/env node

const express = require('express');
const bodyParser = require('body-parser');
const issue = require('./middlewares/issue');
const server = express();
const port = require('./port');

server.use(bodyParser.json({limit: '5mb'}));

server.post('/issue', issue);

server.listen(port, () => console.log(`issuer-node-wrapper app listening at http://localhost:${port}`));

但使用该入口脚本时,有两件事不起作用:

  • 没有stdout,所以我看不到issuer-node-wrapper app listening at http://localhost:${port}的输出,但是服务器确实启动了(端口被占用,lsof -t -i:3000给了我一个pid,我可以稍后删除),如果我改变bin直接运行js脚本,即issuer-start: ./bin/start-server.js,我确实看到了控制台日志输出,但是我更希望有一个带参数的命令。
  • 在这两种情况下,当我稍后执行对服务器(http://localhost:3000/issue)的调用时,响应会立即出现,并且响应解析失败,并显示:
Error: FetchError: invalid json response body at http://localhost:3000/issue reason: Unexpected token < in JSON at position 0

据我所知,这是因为Promise在执行then部分时没有正确终止,所以它实际上是在解析<Pending>(因此出现<无效字符错误):

const res = await fetch('http://localhost:3000/issue', {
    method: 'POST',
    body: JSON.stringify({
      certificates,
      ...issuerPath && {
        issuerPath
      }
    }),
    headers: {'Content-Type': 'application/json'}
  }).then(res => {
    const decoded = res.json(); <<<< HERE
    return decoded;
  }).catch (err => {
    // throw new Error(err);
    console.error('Error:', err);
  });

所以一定有什么我不明白在一个低层次,无法找到原因,当execspawn的服务器从bin命令,这将以某种方式使服务器丢失在不同的线程,或什么?
我的问题是,当我运行npm "bin"时,实际上发生了什么事情,使服务器在启动时的行为不同?

bnlyeluc

bnlyeluc1#

我想通了,
问题是cwd或执行上下文没有被使用__dirname的服务器上的执行脚本适当地考虑。
所以问题出在椅子和屏幕之间,而不是节点本身。

相关问题