Есть некоторые сторонние библиотеки Javascript, которые обладают некоторыми функциями, которые я хотел бы использовать на сервере Node.js. (В частности, я хочу использовать библиотеку javascript QuadTree, которую я нашел.) Но эти библиотеки представляют собой простые .js
файлы, а не «библиотеки Node.js».
Таким образом, эти библиотеки не следуют exports.var_name
синтаксису, который Node.js ожидает от своих модулей. Насколько я понимаю, это означает, что когда вы это сделаете, module = require('module_name');
или module = require('./path/to/file.js');
вы получите модуль без общедоступных функций и т. Д.
Тогда мой вопрос: «Как мне загрузить произвольный файл javascript в Node.js, чтобы я мог использовать его функциональные возможности без необходимости переписывать его, чтобы он работал exports
?»
Я новичок в Node.js, поэтому, пожалуйста, дайте мне знать, если в моем понимании того, как это работает, есть явная дыра.
РЕДАКТИРОВАТЬ : изучая вещи больше, и теперь я вижу, что шаблон загрузки модуля, который использует Node.js, на самом деле является частью недавно разработанного стандарта для загрузки библиотек Javascript под названием CommonJS . Об этом говорится прямо на странице документации модуля для Node.js , но до сих пор я это пропустил.
Может оказаться, что ответ на мой вопрос: «подождите, пока авторы вашей библиотеки не займутся написанием интерфейса CommonJS, или сделайте это сами».
источник
Ответы:
Есть гораздо лучший метод, чем использование
eval
:vm
модуль.Например, вот мой
execfile
модуль, который оценивает сценарийpath
в любомcontext
или глобальном контексте:И его можно использовать так:
Где
example.js
содержится:Большим преимуществом этого метода является то, что у вас есть полный контроль над глобальными переменными в исполняемом скрипте: вы можете передавать пользовательские глобальные переменные (через
context
), и все глобальные переменные, созданные скриптом, будут добавлены вcontext
. Отладка также упрощается, потому что синтаксические ошибки и т.п. будут сообщаться с правильным именем файла.источник
runInNewContext
Использует ли глобальный контекст, еслиcontext
(иначе называемыйsandbox
в документации) не определен? (этот момент не был прояснен какими-либо документами, которые я нашел)vm
предложить модуль в этом случае?Вот что я считаю наиболее «правильным» ответом на эту ситуацию.
Скажем, у вас есть файл сценария с именем
quadtree.js
.Вы должны создать кастом
node_module
с такой структурой каталогов ...Все в вашем
./node_modules/quadtree/quadtree-lib/
каталоге - это файлы из вашей сторонней библиотеки.Затем ваш
./node_modules/quadtree/index.js
файл просто загрузит эту библиотеку из файловой системы и выполнит работу по правильному экспорту.Теперь вы можете использовать свой
quadtree
модуль как любой другой модуль узла ...Мне нравится этот метод, потому что нет необходимости менять какой-либо исходный код вашей сторонней библиотеки, поэтому его проще поддерживать. Все, что вам нужно сделать при обновлении, - это посмотреть их исходный код и убедиться, что вы по-прежнему экспортируете нужные объекты.
источник
npm link
вставить ее в свое приложение. Затем он обрабатывается, как если бы это был собственный пакет Node.js.Самый простой способ: он
eval(require('fs').readFileSync('./path/to/file.js', 'utf8'));
отлично подходит для тестирования в интерактивной оболочке.источник
AFAIK, именно так и должны загружаться модули. Однако вместо того, чтобы прикреплять все экспортируемые функции к
exports
объекту, вы также можете прикрепить ихthis
(что в противном случае было бы глобальным объектом).Итак, если вы хотите сохранить совместимость других библиотек, вы можете сделать это:
или, когда внешняя библиотека уже имеет собственное пространство имен, например
jQuery
(не то чтобы вы могли использовать это в серверной среде):В среде, отличной от Node, он
this
будет преобразован в глобальный объект, что сделает его глобальной переменной ... что уже было. Так что он ничего не должен сломать.Изменить : у Джеймса Хердмана есть хорошая статья о node.js для начинающих, в которой также упоминается об этом.
источник
Я не уверен, что действительно буду использовать это, потому что это довольно хакерское решение, но один из способов обойти это - создать небольшой импортер мини-модулей, подобный этому ...
В файле
./node_modules/vanilla.js
:Затем, когда вы захотите использовать функциональные возможности своей библиотеки, вам нужно будет вручную выбрать, какие имена экспортировать.
Итак, для библиотеки, такой как файл
./lib/mylibrary.js
...Если вы хотите использовать его функциональность в своем коде Node.js ...
Не знаю, насколько хорошо все это будет работать на практике.
источник
Я смог заставить его работать, очень легко обновив их сценарий, просто добавив
module.exports =
там, где это необходимо ...Например, я взял их файл и скопировал в ./libs/apprise.js. Тогда где это начинается с
Я назначил функцию
module.exports =
таким образом:Таким образом, я могу импортировать библиотеку в свой код следующим образом:
И мне было хорошо идти. YMMV, это было с веб-пакетом .
источник
Простая
include(filename)
функция с улучшенным обменом сообщениями об ошибках (стек, имя файла и т. Д.)eval
В случае ошибок:Но с nodejs становится еще грязнее: вам нужно указать это:
В противном случае вы не сможете использовать глобальные переменные в файлах, включенных в
include(...)
.источник