Как поделиться кодом между Node.js и браузером?
В этой статье мы рассмотрим, как писать модули 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]
- Вывод в браузере: