Здесь задаются два разных (но, казалось бы, связанных) вопроса. Первый из них: «Как работают основные модули?». Второй: «Как NodeJS позволяет ссылаться на код c ++ и выполнять его в JavaScript?». Давайте возьмем их один за другим.
Как работают основные модули?
Основные модули упакованы с двоичным кодом NodeJS. И хотя они упакованы вместе с двоичным файлом, они не преобразуются в код c ++ перед упаковкой. Внутренние модули загружаются в память во время начальной загрузки процесса узла. Когда программа выполняется, скажем, require('fs')
, функция require просто возвращает уже загруженный модуль из кэша. Фактическая загрузка внутреннего модуля, очевидно, происходит в коде c ++ .
Как NodeJS позволяет ссылаться на код c ++ в JS?
Эта способность частично исходит от движка V8, который предоставляет возможность создавать и управлять конструкциями JS в C ++, и частично от NodeJS / LibUV, которые создают оболочку над V8 для обеспечения среды выполнения. Документация о таких узловых модулях может быть доступна здесь . Как указано в документации, эти модули c ++ могут использоваться в файле JS по требованию, как и любой другой обычный модуль JS.
Ваш пример использования функции c ++ в JS (loadPKCS12
), однако, является более частным случаем внутренней функциональности c ++ в NodeJS. loadPKCS12
вызывается для объекта SecureContext
, импортированного из модуля crypto
c ++. Если вы перейдете по ссылке на импорт SecureContext в _tls_common.js
выше, вы увидите, что крипто не загружается с использованием require()
, вместо этого используется специальный (глобальный) метод internalBinding
для получения ссылки. В последней строке в файле node_crypto.cc
зарегистрирован инициализатор для внутреннего модуля crypto
. Следуя цепочке инициализации, node::crypto::Initialize
вызывает node::crypto::SecureContext::Initialize
, которая создает шаблон функции, назначает соответствующие методы-прототипы и экспортирует его в target
. В конечном итоге эти экспортированные функции из мира C ++ импортируются и используются в JS-World с использованием internalBinding
.