0

我正在研究一个我基本上重构现有代码的作品。我有两个文件:索引和服务器。我的索引是:

const md5File = require('md5-file');
const fs = require('fs');
const path = require('path');
const ignoreStyles = require('ignore-styles');
const register = ignoreStyles.default;
const extensions = ['.gif', '.jpeg', '.jpg', '.png', '.svg'];
...
require('@babel/polyfill');
require('@babel/register')({
  ignore: [/\/(build|node_modules)\//],
  presets: ['@babel/preset-env', '@babel/preset-react'],
  plugins: [
    '@babel/plugin-syntax-dynamic-import',
    '@babel/plugin-proposal-class-properties',
    'dynamic-import-node',
    'react-loadable/babel'
  ]
});
// Now that the nonsense is over... load up the server entry point
require('./server');

我的服务器是这样的:

import path from 'path';
import Loadable from 'react-loadable';
...
const main = async () => {
  // tell React Loadable to load all required assets
  await Loadable.preloadAll();

  process.on('unhandledRejection', err => {
    console.error(err);
    process.exit(1);
  });

  const server = fastify(config.fastify);
  server.register(require('./routes'), config);
  server.register(fastifyStatic, {
    root: path.resolve(__dirname, '../build')
  });
  if (require.main === module) {
    // called directly i.e. $ node index.js
    const address = await server.listen(config.address);
    // start listening - ROCK AND ROLL!
    server.log.info(`Server running at: ${address}`);
  } else {
    // required as a module => executed on aws lambda
    module.exports = server;
  }
};
main();

服务器在本地执行时应该运行 REST 服务,并导出该inject方法的服务器实例。这样,在 AWS Lambda 下运行时,代理可以附加到它。

我以前多次使用相同的设置。只有两个部分在同一个文件中,例如服务器在索引中。单个文件版本工作正常 -require.main比较告诉程序它是如何运行的,并在 Lambda 下运行时使用所需的方法module.exports公开服务器实例 [ ],并通过直接调用运行 REST 服务。serverinject

react-loadable但是,由于我这次需要导入,所以我将文件分成两部分。

现在,我可能需要弄清楚代码是如何在内部运行的,index.js因为server.js它没有被直接调用,然后将其传递给服务器。这可能不是太难。

我的主要问题是,如果我console.log(require('./server'))从索引开始,它会打印{}. 当服务器实例成功创建并且inject()存在时;我无法从 server.js 文件中导出它并正确导入 index.js,因此 [re-] 从 index.js 中导出它以供代理附加。

显然,我做错了什么。对我来说,似乎我的 require 没有服务器实例,因为实例是在 require 完成后创建的。由于我的 main() 是异步的,因此它是合理的。实现这一目标的正确方法是什么?

4

1 回答 1

1

首先,请注意您main()在 ./server.js 中的函数是async并且您正在module.exports从该异步函数中定义。其次,您require('./server.js')从 ./index.js 调用,而无需等待异步工作完成。Noderequire()立即将 -d 模块解析为空白对象(这就是{}您得到的),然后在任何异步或循环材料可用时扩展该对象。所以这就是为什么你看到你所看到的。

哪种解决方案适合或不适合您的用例将取决于您的 AWS/direct 调用应该如何工作的详细信息。这里有一个建议:

const md5File = require('md5-file');
const fs = require('fs');
const path = require('path');
const ignoreStyles = require('ignore-styles');
const register = ignoreStyles.default;
const extensions = ['.gif', '.jpeg', '.jpg', '.png', '.svg'];
// ...
require('@babel/polyfill');
require('@babel/register')({
  ignore: [/\/(build|node_modules)\//],
  presets: ['@babel/preset-env', '@babel/preset-react'],
  plugins: [
    '@babel/plugin-syntax-dynamic-import',
    '@babel/plugin-proposal-class-properties',
    'dynamic-import-node',
    'react-loadable/babel'
  ]
});

process.env.serverRunLocally = require.main === module;

// Now that the nonsense is over... load up the server entry point
require('./server').then(listen => listen());
import path from 'path';
import Loadable from 'react-loadable';
// ...
const main = async () => {
  // tell React Loadable to load all required assets
  await Loadable.preloadAll();

  process.on('unhandledRejection', err => {
    console.error(err);
    process.exit(1);
  });

  const server = fastify(config.fastify);
  server.register(require('./routes'), config);
  server.register(fastifyStatic, {
    root: path.resolve(__dirname, '../build')
  });
  if (process.env.serverRunLocally) {
    // called directly i.e. $ node index.js
    return () => {
       const address = await server.listen(config.address);
       // start listening - ROCK AND ROLL!
       server.log.info(`Server running at: ${address}`);
    }
  } else {
    // required as a module => executed on aws lambda
    return server;
  }
};

module.exports = main();
于 2021-01-25T15:16:32.650 回答