Это продолжение ответов на вопросы, размещенные в известном репо Node Beyond Basics, спасибо автору за создание такого блестящего ресурса по Node. Для просмотра предыдущих частей перейдите по следующим ссылкам:

19. Когда можно использовать методы файловой системы *Sync?

Методы *Sync представляют собой синхронную блокирующую версию функций spawn, exec и execFile из модуля child_process, которая будет ожидать завершения дочернего процесса.

const { spawnSync, execSync, execFileSync } = require(“child_process”);

Эти синхронные версии потенциально полезны при попытке упростить задачи сценариев или любые задачи обработки при запуске, но в противном случае их следует избегать.

20. Почему переменные верхнего уровня не являются глобальными?

Переменные верхнего уровня не являются глобальными из-за метода require(), так как всякий раз, когда нам требуется файл в другом файле, require будет обертывать наш код, который при необходимости предоставит частную область для каждого файла.

21. Объекты exports, require и module глобально доступны в каждом модуле, но в каждом модуле они разные. Как?

Перед компиляцией модуля Node оборачивает код модуля в функцию, которую мы можем проверить с помощью свойства оболочки модуля.

~ $ node
> require (‘module’).wrapper
> [ ‘(function (exports, require, module, __filename, __dirname}) { ‘,
> ‘\n});’
>

Node не выполняет код, который вы пишете в файле напрямую. Он выполняет эту функцию-оболочку, в теле которой будет ваш код. Это то, что удерживает переменные верхнего уровня, определенные в любом модуле, в пределах этого модуля.

22. Если вы запустите файл JavaScript с единственной строкой: console.log(arguments); with Node, что именно Node напечатает?

Если мы запустим файл JavaScript, просто распечатав в нем аргументы, он напечатает следующий фрагмент:

{
‘0’: {},
‘1’: [Function: require] {
resolve: [Function: resolve] { paths: [Function: paths] },
main: Module {
id: ‘.’,
path: ‘/Users/navitas28/Work/Learning/Node’,
exports: {},
filename: ‘/Users/navitas28/Work/Learning/Node/args.js’,
loaded: false,
children: [],
paths: [Array]
},
extensions: [Object: null prototype] {
‘.js’: [Function (anonymous)],
‘.json’: [Function (anonymous)],
‘.node’: [Function (anonymous)]
},
cache: [Object: null prototype] {
‘/Users/navitas28/Work/Learning/Node/args.js’: [Module]
}
},
‘2’: Module {
id: ‘.’,
path: ‘/Users/navitas28/Work/Learning/Node’,
exports: {},
filename: ‘/Users/navitas28/Work/Learning/Node/args.js’,
loaded: false,
children: [],
paths: [
‘/Users/navitas28/Work/Learning/Node/node_modules’,
‘/Users/navitas28/Work/Learning/node_modules’,
‘/Users/navitas28/Work/node_modules’,
‘/Users/navitas28/node_modules’,
‘/Users/node_modules’,
‘/node_modules’
]
},
‘3’: ‘/Users/navitas28/Work/Learning/Node/args.js’,
‘4’: ‘/Users/navitas28/Work/Learning/Node’
}

Первый аргумент — это объект exports, который начинается пустым. Затем у нас есть объекты require/module, оба из которых являются экземплярами, связанными с исполняемым нами файлом args.js. Это не глобальные переменные. Последние два аргумента — это путь к файлу и путь к его каталогу.

23. Как модуль может быть одновременно «требуемым» для других модулей и исполняемым непосредственно с помощью команды node?

Это достижимо благодаря свойству main объекта require. Свойство main используется, чтобы различать, выполняется ли сценарий напрямую или требуется. Мы можем легко различить оба случая, как показано ниже.

if (require.main === module) {
// the script is being executed directly here.
} else {
// the script is being required.
}

24. Какой пример встроенного потока в Node, который доступен как для чтения, так и для записи?

zlib.createGzip — это поток преобразования, доступный как для чтения, так и для записи. По сути, это дуплексный поток, который можно использовать для изменения или преобразования данных по мере их записи и чтения.