这个 Node.js exports\require 语句究竟是如何工作的?
How exactly works this Node.js exports\require staatements?
总的来说,我对 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 和 bytcode 字段。
所以如果我很好地理解它应该以这种方式工作:
compile.js文件导出(所以意思是对外开放)表示的整个对象solc.compile(source, 1).contracts[':Inbox'].
然后进入 Inbox.test.js 文件:
const { interface, bytecode } = require('../compile');
但是 require() 语句的这个用户究竟意味着什么?意思是:取compile.js文件导出的内容?如果是这样,导出的是 JavaScript 对象,其中包含这些 interface 和 bytcode 字段,这些字段被设置为 const.
它是正确的还是我遗漏了什么?
您可能需要阅读 CommonJS 模块的文档:
https://nodejs.org/dist/latest-v16.x/docs/api/modules.html
它为您列出了 require()
的作用。
是的,你是对的。它 returns 无论 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
模块的 interface
和 bytecode
属性。所以你是对的,那就是:
solc.compile(source, 1).contracts[':Inbox'];
的字段包括 interface
和 bytecode
。
{
interface: Function(),
bytecode: Function()
}
如果导入时未解构 require 语句,则可以像引用任何其他对象一样引用其属性。
const compile = require("../compile");
compile.interface();
compile.bytecode();
您可以将 module.exports
设置为任何内容,一个字符串,一个 class,一个函数。例如,如果您在 myFile.js
中导出一个字符串:module.exports = "foobar";
,并且导入文件:
const myFile = require("./myFile");
console.log(myFile); //Prints: foobar
总的来说,我对 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 和 bytcode 字段。
所以如果我很好地理解它应该以这种方式工作:
compile.js文件导出(所以意思是对外开放)表示的整个对象solc.compile(source, 1).contracts[':Inbox'].
然后进入 Inbox.test.js 文件:
const { interface, bytecode } = require('../compile');
但是 require() 语句的这个用户究竟意味着什么?意思是:取compile.js文件导出的内容?如果是这样,导出的是 JavaScript 对象,其中包含这些 interface 和 bytcode 字段,这些字段被设置为 const.
它是正确的还是我遗漏了什么?
您可能需要阅读 CommonJS 模块的文档:
https://nodejs.org/dist/latest-v16.x/docs/api/modules.html
它为您列出了 require()
的作用。
是的,你是对的。它 returns 无论 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
模块的 interface
和 bytecode
属性。所以你是对的,那就是:
solc.compile(source, 1).contracts[':Inbox'];
的字段包括 interface
和 bytecode
。
{
interface: Function(),
bytecode: Function()
}
如果导入时未解构 require 语句,则可以像引用任何其他对象一样引用其属性。
const compile = require("../compile");
compile.interface();
compile.bytecode();
您可以将 module.exports
设置为任何内容,一个字符串,一个 class,一个函数。例如,如果您在 myFile.js
中导出一个字符串:module.exports = "foobar";
,并且导入文件:
const myFile = require("./myFile");
console.log(myFile); //Prints: foobar