【问题标题】:How exactly works this Node.js exports\require staatements?这个 Node.js 的 export\require 语句究竟是如何工作的?
【发布时间】:2022-02-01 01:54:22
【问题描述】:

我在 nodeJS 和一般的 JS 技术方面相当陌生(我来自 Java)。 我正在编写以下简单代码,我对这个 require 语句的实际工作方式有以下疑问:

我有这个文件包含一些 mocha 测试代码:

const assert = require('assert');
const ganache = require('ganache-cli');
const Web3 = require('web3');       // It is a constructor

const web3 = new Web3(ganache.provider());

const { interface, bytecode } = require('../compile');

let accounts;
let inbox;


beforeEach(async () => {
    // Get a list of all accounts:
    accounts = await web3.eth.getAccounts()         // use the web3 module to interact with ETH cryupto
       
    // Use one of these accounts to deploy the contract:
    inbox = await new web3.eth.Contract(JSON.parse(interface))
                    .deploy({ data: bytecode, arguments: ['Hi there!'] })
                    .send({ from: accounts[0], gas: '1000000' })
});

describe('Inbox', () => {
    it('depploys a contract', () => {
        console.log(accounts);
        console.log(inbox);
    });
});

如你所见,我有这一行:

const { interface, bytecode } = require('../compile');

据我所知,它正在创建一个 JS 对象(如果我做错了断言,请纠正我),其中包含由 ../compile “模块”(其中 编译一个模块?)

在这里我有以下疑惑:我想它与我在父文件夹中的compile.js文件有关(与mocha脚本文件夹相关的父)。此 compile.js 文件夹包含以下代码:

const path = require('path');
const fs = require('fs');
const solc = require('solc');

const inboxPath = path.resolve(__dirname, 'contracts', 'Inbox.sol');
const source = fs.readFileSync(inboxPath, 'utf-8');


console.log(solc.compile(source, 1).contracts[':Inbox']);    
module.exports = solc.compile(source, 1).contracts[':Inbox'];

我唯一能想到的是,这个 solc.compile(source, 1).contracts[':Inbox'] 是一个包含一些字段的对象,包括这些 interface字节码 字段。

所以如果我很好理解它应该以这种方式工作:

  • compile.js 文件导出(因此意味着向外界提供)由 solc.compile(source, 1).contracts[':Inbox 表示的整个对象'].

  • 然后进入 Inbox.test.js 文件:

     const { interface, bytecode } = require('../compile');
    

但是 require() 语句的这个用户究竟意味着什么?这意味着:获取 compile.js 文件导出的内容?如果是这样,则导出的是一个 JavaScript 对象,其中包含这些设置为 const 的 interfacebytcode 字段。

是正确的还是我遗漏了什么?

【问题讨论】:

    标签: javascript node.js node-modules


    【解决方案1】:

    是的,你是对的。它返回 module.exports 定义的任何内容,您可以像分配任何变量一样分配它。默认情况下它是{},一个空对象。但是如果我想导出一个函数,我会这样做:

    module.exports.myFunc = function(a){
      console.log(a);
    }
    

    现在module.exports 的值是{myFunc: Function()}。所以当我从另一个文件导入模块时:

    const myFile = require('./myFile');
    myFile.myFunc("Hello there!"); //Prints: Hello there!
    

    当您在花括号中按名称获取函数时,您正在解构对象,请查看MDN Web Docs。因此,当您拥有const { interface, bytecode } = require("../compile"); 时,您将获得compile 模块的interfacebytecode 属性。所以你是对的,那就是:

    solc.compile(source, 1).contracts[':Inbox'];

    具有包含interfacebytecode 的字段。

    {
      interface: Function(),
      bytecode: Function()
    }
    

    如果您在不解构 require 语句的情况下导入,则可以将其属性作为任何其他对象引用。

    const compile = require("../compile");
    compile.interface();
    compile.bytecode();
    

    您可以将module.exports 设置为任何东西,一个字符串、一个类、一个函数。例如,如果您将myFile.js 中的字符串导出为module.exports = "foobar";,然后导入文件:

    const myFile = require("./myFile");
    console.log(myFile); //Prints: foobar
    

    【讨论】:

      【解决方案2】:

      您可能想阅读 CommonJS 模块的文档:

      https://nodejs.org/dist/latest-v16.x/docs/api/modules.html

      它为您展示了 require() 的作用。

      【讨论】:

        猜你喜欢
        • 2021-04-11
        • 1970-01-01
        • 2018-03-03
        • 1970-01-01
        • 1970-01-01
        • 2021-01-27
        • 1970-01-01
        • 2013-12-05
        • 2016-11-30
        相关资源
        最近更新 更多