简体   繁体   中英

How exactly works this Node.js exports\require staatements?

I am pretty new in nodeJS and JS technologies in general (I came from Java). I am working on the following simple code and I have the following doubt about how this require statement actually works:

I have this file containing some mocha test code:

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);
    });
});

As you can see I have this line:

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

from what I can understand it is creating a JS object (please, correct me if I am doing wrong assertion) containing two fields retrieved by the ../compile "module" (in it compile a module?)

And here I have the following doubts: I suppose that it is related to the compile.js file that I have into the parent folder (parent related to the mocha script folder). This compile.js folder contains the following code:

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'];

The only thing that I can think is that this solc.compile(source, 1).contracts[':Inbox'] is an object containing some fields including these interface and bytcode fields.

So if I well understood it should works in this way:

  • The compile.js file exports (so it means that make available to the outside world) the entire object represented by solc.compile(source, 1).contracts[':Inbox'] .

  • then into the Inbox.test.js file it does:

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

But what exactly means this user of the require() statment? It means: take what was exported by the compile.js file? If so what is exported is a JavaScript object containing these interface and bytcode fields that are set as const.

Is it correct or am I missing something?

You might want to read the documentation for CommonJS modules:

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

It lays out for you what require() does.

Yes you would be correct. It returns whatever module.exports is defined as, which you can assign just as you would any variable. By default it is {} , an empty object. But if I wanted to export a function, I would do this:

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

Now module.exports has the value {myFunc: Function()} . So when I import the module from another file:

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

When you get a function by name within curly braces, you're destructuring the object, take a look at the MDN Web Docs . So when you have const { interface, bytecode } = require("../compile"); you're getting the interface and bytecode properties of the compile module. So you would be correct, that:

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

has fields which include interface and bytecode .

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

If you import without destructuring the require statement, you could refer to its properties as any other object.

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

You can set module.exports to anything, a string, a class, a function. For instance if you exported a string in myFile.js as such: module.exports = "foobar"; , and you imported the file:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM