如果脚本文件不是直接 运行,Nodejs 需要变量未定义吗?

Nodejs required variable undefined if script file not run directly?

对于问题的措辞,我深表歉意 - 将其概括为一个问题有点困难 - 如果您可以澄清,请随时进行编辑。此外,由于这是一个相当复杂且冗长的查询 - 感谢所有花时间阅读它的人!

作为我正在构建的项目的一部分,我有 4 个文件(与项目根目录树一起列出),该项目旨在抓取区块链并利用多核来完成工作:

  1. ./main.js
  2. ./scraper.js
  3. ./api/api.js
  4. ./api/litecoin_api.js

main.js

const { scraper } = require('./scraper.js')
const blockchainCli = process.env.BLOCKSCRAPECLI || 'litecoin-cli'

const client = (args) => {
  // create child process which returns a promise which resolves after
  // data has finished buffering from locally hosted node using cli
  let child = spawn(`${blockchainCli} ${args.join(' ')}`, {
    shell: true
  })
  // ... wrap command in a promise here, etc
}

const main = () => {
  // count cores, spawn a worker per core using node cluster, add
  // message handlers, then begin scraping blockchain with each core...
  scraper(blockHeight)
}

main()

module.exports = {
  client,
  blockchainCli
}

scraper.js

const api = require('./api/api.js')
const scraper = async (blockHeight) => {
  try {
    let blockHash = await api.getBlockHashByHeight(blockHeight)
    let block = await api.getBlock(blockHash)
    // ... etc, scraper tested and working, writes to shared writeStream
}

module.exports = {
  scraper
}

api.js

const { client, blockchainCli } = require('../main.js')
const litecoin = require('./litecoin_api')

let blockchain = undefined

if (blockchainCli === 'litecoin-cli' || blockchainCli === 'bitcoin-cli') {
  blockchain = litecoin
}
// PROBLEM HERE: blockchainCli (and client) are both undefined if and
// only if running scraper from main.js (but not if running scraper
// from scraper.js)

const decodeRawTransaction = (txHash) => {
  return client([blockchain.decodeRawTransaction, txHash])
}

const getBlock = (blockhash) => {
  return client([blockchain.getBlock, blockhash])
}

const getBlockHashByHeight = (height) => {
  return client([blockchain.getBlockHash, height])
}

const getInfo = () => {
  return client([blockchain.getInfo])
}

const getRawTransaction = (txHash, verbose = true) => {
  return client([blockchain.getRawTransaction, txHash, verbose])
}

module.exports = {
  decodeRawTransaction,
  getBlock,
  getBlockHashByHeight,
  getInfo,
  getRawTransaction
}

所以,我删除了文件中的大部分噪音,我认为这不是必需的,但它是开源的,所以如果您需要更多 take a look here

问题是,如果我从内部 scraper.js 开始抓取程序,比如,做这样的事情:scraper(1234567) 它就像一个魅力并将预期的数据输出到 csv 文件.

但是,如果我从 main.js 文件中启动抓取工具,我会得到这个错误:

Cannot read property 'getBlockHash' of undefined
    at Object.getBlockHashByHeight (/home/grayedfox/github/blockscrape/api/api.js:19:29)
    at scraper (/home/grayedfox/github/blockscrape/scraper.js:53:31)
    at Worker.messageHandler (/home/grayedfox/github/blockscrape/main.js:81:5)

我不知道为什么,当从 main.js 启动爬虫时,区块链是未定义的。我认为它可能来自解构,但是从示例 main.js 文件的第一行周围移除花括号不会改变任何东西(同样的错误)。

目前情况有点乱(在开发这个分支的过程中)——但现在的根本问题是我不清楚为什么 require 会失败(看不到 main.js 中的变量) 如果按以下方式使用:

但不会失败(可以看到main.js里面的变量)如果是运行像这样:

非常感谢您的宝贵时间!

您在 main 和 api 之间存在循环依赖,每个都需要另一个。 main 通过 scraper 需要 api 而 api 直接需要 main.这导致事情无法正常工作。

您必须通过将公共共享代码放入其自己的模块中来消除循环依赖,该模块可以被两者包含,但不包含其他包含它的模块。它只是需要更好的模块化。