AndreaNobili
AndreaNobili

Reputation: 43077

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:

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?

Upvotes: 0

Views: 96

Answers (2)

Arkin Solomon
Arkin Solomon

Reputation: 605

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

Upvotes: 1

Nicholas Carey
Nicholas Carey

Reputation: 74375

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.

Upvotes: 1

Related Questions