Как поделиться кодом между Node.js и браузером?
В этой статье мы рассмотрим, как писать модули JavaScript, которые могут использоваться как клиентскими, так и серверными приложениями.
У нас есть небольшое веб-приложение с клиентом JavaScript (работающим в браузере) и сервером Node.js. И у нас есть функция getFrequency (), которая должна использоваться как сервером, так и клиентом, чтобы получить частоту символов в данной строке. Мы хотим создать единый набор методов, который может облегчить задачу с обеих сторон.
Подход:
Написание кода для клиентской стороны (работающей в браузере) сильно отличается от серверного приложения Node.js. На стороне клиента мы в основном имеем дело с DOM или веб-API, такими как файлы cookie, но в Node. Другая причина, по которой мы не можем использовать модули узлов на стороне клиента, заключается в том, что узел использует модульную систему CommonJS, в то время как браузер использует стандартные модули ES, которые имеют другой синтаксис.
В узле мы используем module.exports для раскрытия функциональности или свойства. Однако это нарушит работу браузера, так как браузер не сможет распознать экспорт . Итак, чтобы он работал, мы проверяем, определен ли экспорт , если нет, то мы создаем разумный объект для экспорта функций. В браузере это может быть достигнуто путем создания глобальной переменной с тем же именем, что и у модуля.
Структура модуля будет выглядеть примерно так:
sampleModule.js
// Checking if exports is definedif(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 exposefunction notToExport(){ } // Function to be exposedexports.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 functionfunctiontoLC(str) {returnstr.trim().toLowerCase();}// Function to be exposedfunctiongetFrequency(str) {str = toLC(str);varfreq = [];for(vari = 0; i < 26; i++) {freq.push(0);}for(vari = 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 sharedModuleexports.getFrequency = getFrequency;})(typeofexports ==='undefined'?this['sharedModule']={}: exports); - nodeApp.js
// Simple node.js script which uses sharedModule.js// Get module.exports of sharedModuleconst utilities = require('./sharedModule');// Print ferquency of characterconsole.log(utilities.getFrequency("GeeksForGeeks")); - clientApp.js
// Use functionality getFrequency which// is available in sharedModule objectdocument.write(this.sharedModule.getFrequency("GeeksForGeeks")); - index.html
<scriptsrc="./sharedModule.js"></script><scriptsrc="./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]
- Вывод в браузере:
