Как поделиться кодом между Node.js и браузером?

Опубликовано: 6 Августа, 2021

В этой статье мы рассмотрим, как писать модули JavaScript, которые могут использоваться как клиентскими, так и серверными приложениями.

У нас есть небольшое веб-приложение с клиентом JavaScript (работающим в браузере) и сервером Node.js. И у нас есть функция getFrequency (), которая должна использоваться как сервером, так и клиентом, чтобы получить частоту символов в данной строке. Мы хотим создать единый набор методов, который может облегчить задачу с обеих сторон.

Подход:
Написание кода для клиентской стороны (работающей в браузере) сильно отличается от серверного приложения Node.js. На стороне клиента мы в основном имеем дело с DOM или веб-API, такими как файлы cookie, но в Node. Другая причина, по которой мы не можем использовать модули узлов на стороне клиента, заключается в том, что узел использует модульную систему CommonJS, в то время как браузер использует стандартные модули ES, которые имеют другой синтаксис.

В узле мы используем module.exports для раскрытия функциональности или свойства. Однако это нарушит работу браузера, так как браузер не сможет распознать экспорт . Итак, чтобы он работал, мы проверяем, определен ли экспорт , если нет, то мы создаем разумный объект для экспорта функций. В браузере это может быть достигнуто путем создания глобальной переменной с тем же именем, что и у модуля.

Структура модуля будет выглядеть примерно так:
sampleModule.js




// Checking if exports is defined
if(typeof exports === "undefined"){
   var exports = this["sampleModule"] = {};
}
   
// The code define the functions,
// variables or object to expose as
// exports.variableName
// exports.functionName
// exports.ObjectName
   
// Function not to expose
function notToExport(){ }
   
// Function to be exposed
exports.test(){ }

У указанного выше формата есть проблема, заключающаяся в том, что все, что мы определяем в sampleModule.js, но не экспортируем, будет доступно браузеру, т.е. обе функции notToExport () и test () будут работать вне этого файла. Итак, чтобы преодолеть это, мы оборачиваем модуль закрытием.

sampleModule.js




( function (exports) {
// The code defines all the functions,
// variables or object to expose as:
// exports.variableName
// exports.functionName
// exports.ObjectName
}) ( typeof exports === 'undefined' ? this [ 'sampleModule' ]={}: exports);

Пример: давайте сделаем образец модуля, который содержит метод getFrequency для подсчета частоты символов в строке.

  • sharedModule.js




    // All the code in this module is
    // enclosed in closure
    ( function (exports) {
    // Helper function
    function toLC(str) {
    return str.trim().toLowerCase();
    }
    // Function to be exposed
    function getFrequency(str) {
    str = toLC(str);
    var freq = [];
    for ( var i = 0; i < 26; i++) {
    freq.push(0);
    }
    for ( var i = 0; i < str.length; i++) {
    freq[str.charCodeAt(i)-97]++;
    }
    freq; return
    }
    // Export the function to exports
    // In node.js this will be exports
    // the module.exports
    // In browser this will be function in
    // the global object sharedModule
    exports.getFrequency = getFrequency;
    })( typeof exports === 'undefined' ?
    this [ 'sharedModule' ]={}: exports);
  • nodeApp.js




    // Simple node.js script which uses sharedModule.js
    // Get module.exports of sharedModule
    const utilities = require( './sharedModule' );
    // Print ferquency of character
    console.log(utilities.getFrequency( "GeeksForGeeks" ));
  • clientApp.js




    // Use functionality getFrequency which
    // is available in sharedModule object
    document.write( this .sharedModule.getFrequency( "GeeksForGeeks" ));
  • index.html




    < script src = "./sharedModule.js" ></ script >
    < script src = "./clientApp.js" ></ script >

Шаги для запуска программы:

  • Скопируйте и вставьте весь код с соответствующими именами файлов и убедитесь, что все файлы находятся в одном каталоге.
  • Откройте терминал в том же каталоге и выполните node nodeApp.js .
  • Откройте index.html в любом браузере.

Выход:

  • Вывод на консоль node.js:
    [0, 0, 0, 0, 4, 1, 2, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0 , 0]
    
  • Вывод в браузере: