Локальные модули NodeJS для сложных структур приложений
В настоящее время я являюсь частью команды по созданию приложения для Windows 8 с использованием JavaScript. Мы используем npm и browserify для управления зависимостями и преобразования наших модулей в дружественный для AMD формат.
Одна проблема, с которой мы сталкиваемся, - это безумные пути. Это потому, что у нас есть папка верхнего уровня внутри "компонентов" нашего приложения. Эта папка содержит несколько вложенных компонентов / модулей пользовательского интерфейса. Этим модулям иногда требуются утилиты и помощники lib, которые находятся в каталоге lib.
Так, например, для модуля, находящегося в "my/app/ components / product / grid / item", может потребоваться вспомогательный модуль, который находится в "my/app/lib/helpers/view".
Путь require немного сумасшедший и очень некрасивый: require("../../../../lib/helpers/view");
Мы делаем все возможное, чтобы встроить приложение в модульную форму. Теперь я думаю, что правильный подход к этому состоит в том, чтобы наши модули компонентов зависели от этих вспомогательных модулей. Я мог бы поместить помощников lib в их собственное внешнее личное git-репо, но это было болезненно с точки зрения предоставления доступа другим командам (плюс, git-частные репозитории работают медленно). Плюс, поскольку эти модули используются только в приложении, внесение изменений, потеря изменений, возврат к приложению и обновление npm - пустая трата времени. Это хорошо для некоторых, но если мы действительно сломаем это, это может очень быстро состариться.
Я мог бы сделать npm установить "мой / app / lib / helpers / view" внутри компонентов package.json? Но npm install не сделает это за нас автоматически.
Я знаю несколько других способов обойти это (NODE_PATH, возможно, использовать хук установки npm или сценарий предустановки npm), но хотел узнать, есть ли у кого-нибудь еще подобная проблема и хорошее решение.
3 ответа
Вы можете поставить свой "my/app/components/product/grid/item"
файлы в node_modules/grid/item.js
а потом, когда ты require('grid/item')
в коде приложения вы получите файл, который вам нужен, с гораздо более кратким синтаксисом пути. Просто проверь node_modules/grid/item.js
и любые другие файлы в git. node_modules/
каталог даже не должен находиться на верхнем уровне, так как алгоритм require, используемый узлом и browserify, будет искать node_modules/
каталоги от текущего пути вплоть до /
пока не найдет соответствующий модуль.
Просто убедитесь, что добавили "grid"
к "bundledDependencies"
массив в вашем package.json, чтобы вы случайно не установили что-либо поверх него.
Вы можете прочитать больше о проверке модулей узлов в git.
Прочитайте раздел справочника browserify о том, как избежать../../../../../../ для получения дополнительной информации.
NODE_PATH - всегда плохая идея, и browserify не поддерживает ее. Никогда не используйте это когда-либо.
Одна вещь, которую вы могли бы сделать, это создать псевдоним для ваших помощников в вашей конфигурации config...
require.config({
paths: {
"helpers": "my/app/lib/helpers"
}
});
Это сократит ваши долгие пути.
Проблема функции require() состоит в том, что пути являются относительными из текущего файла. Вы можете поместить свои модули в каталог node_modules, но это худшее, что вы можете сделать. node_modules - это каталог, в котором живут все сторонние модули. Если вы следуете этому простому правилу, очень легко и удобно всегда оставаться в курсе событий, вы можете удалить все зависимости (удаление node_modules) и просто сделать npm install
,
Лучшее решение - определить собственную функцию require и сделать ее глобальной. Например:
Структура вашего проекта:
my-project
| tools
|- docs
|- logs
|- conf
`- src
|- node_modules
|- package.json
|- mod.js
|- a
| `- b
| `- c.js
`- d
`- app.js
mod.js
global.mod = function (file){
return require ("./" + file);
};
app.js
//This should be the first line in your main script
require ("../mod");
//Now all the modules are relative from the `src` directory
//You want to use the a/b/c.js module
var c = mod ("a/b/c");
Это все, легко. Если вы хотите получить сторонний модуль, расположенный в node_modules, используйте require(). Если вы хотите получить свои собственные модули, используйте mod().
И помните, node_modules только для сторонних модулей, правило № 1.