imported>Vix |
imported>Vix |
Строка 1: |
Строка 1: |
| При работе с node.js часто приходится подключать файлы, расположенные не в
| | '''ПОЛЕЗНОЕ:''' |
| текущей директории, и даже не в поддереве текущего каталога. Поэтому часто в
| | <hr> |
| модулях можно наблюдать что-то вроде
| | * [https://golangs.org/ Уроки для изучения Golang] |
| | | * [https://metanit.com/go/tutorial/2.11.php Функции и их параметры] |
| var obj = require('../../../a/b/c/someModule');
| | * [https://www.ibm.com/developerworks/ru/library/l-go_01/ Язык программирования go] |
| | | * [https://tproger.ru/translations/golang-basics/ Golang: основы для начинающих] |
| | | * [http://golang-book.ru/ Введение в программирование на Go] |
| Для меня гораздо удобнее подключать файлы относительно корня проекта (модуля),
| | * [https://medium.com/golang-notes/%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0-visual-studio-code-%D0%B4%D0%BB%D1%8F-go-647ea94aa795 Настройка Visual Studio Code для Go] |
| например
| | * [https://serverspace.by/support/help/ustanovka-go-na-windows-server/ Установка GoLang на Windows Server] |
| | | * [https://otus.ru/nest/post/1015/ GOPATH и GOROOT больше не нужны?] |
| var obj = require(base_dir + '/a/b/c/someModule');
| | * [https://nuancesprog.ru/p/5966/ Идеальная настройка вашего Golang проекта] |
| | | * [https://habr.com/ru/post/249449/ Кросс-компиляция в Go] |
| | | * [https://gobyexample.com/ Go by Example] |
| Однако и в этом случае довольно много писанины и необходимо откуда-то получать
| | * [https://golang.org/pkg/ Golang Packages] |
| base_dir.
| |
| Для себя я нашел решение проблемы, позволяющее больше не писать require и не
| |
| узнавать base_dir:
| |
| | |
| var obj = lib.a.b.c.someModule;
| |
| | |
| | |
| | |
| Идея решения
| |
| | |
| | |
| Решение проблемы — создание хитрого «класса» (да простят меня гуру javascript за
| |
| такое слово), свойствами которого являются директории и файлы указанной при
| |
| создании класса директории. Если свойство-директория не является модулем, то
| |
| данное свойство также является объектом нашего класса, свойствами которого
| |
| являются директории и файлы этой директории.
| |
| | |
| Чтобы стало понятнее — приведу пример. Предположим у нас имеется следующая
| |
| структура проекта:
| |
| | |
| | |
| Содержимое файлов:
| |
| \a\b\Foo.js
| |
| \a\c\Bar.js
| |
| \a\index.js
| |
| | |
| var LazyLoader = require('./LazyLoader');
| |
| global.lib = new LazyLoader(__dirname);
| |
| var foo = new lib.a.b.Foo();
| |
| console.log(foo.name);
| |
| console.log(foo.bar.name);
| |
| | |
| | |
| | |
| Foo.js
| |
| | |
| module.exports = function () {
| |
| this.name = 'Foo';
| |
| this.bar = new lib.a.c.Bar(); };
| |
| | |
| | |
| | |
| Bar.js
| |
| | |
| module.exports = function () { this.name = 'Bar'; };
| |
| | |
| | |
| | |
| LazyLoader.js
| |
| | |
| var fs = require('fs');
| |
| var path = require('path');
| |
| function getter(key, dir,file) {
| |
| delete this[key];
| |
| var fullPath = path.join(dir, file);
| |
| try
| |
| {require.resolve(fullPath);}
| |
| catch (e) {
| |
| if
| |
| (fs.existsSync(fullPath)) {
| |
| this[key] = new LazyLoader(path.join(dir, file));
| |
| }
| |
| return this[key];
| |
| }
| |
| this[key] = require(fullPath);
| |
| return this[key]; }
| |
| function LazyLoader(dir) {
| |
| var loader = this;
| |
| if (!fs.existsSync(dir)) {
| |
| return;
| |
| }
| |
| fs.readdirSync(dir).forEach(function(file) {
| |
| var key = file.replace(/\.js$/, '');
| |
| loader.__defineGetter__(key, getter.bind(loader, key, dir, file))
| |
| }); }
| |
| module.exports = LazyLoader;
| |
| | |
| | |
| | |
| При запуске node index.js в консоли распечатается (как и ожидалось)
| |
| | |
| Foo Bar
| |
| | |
| | |
| | |
| В данном примере я использовал глобальную переменную lib. Если вы противник
| |
| глобальных переменных (или вы просто разрабатываете отдельный публичный модуль)
| |
| — то можно отказаться от глобальной переменной — в Foo.js придется написать,
| |
| например, так:
| |
| | |
| var path = require('path');
| |
| var LazyLoader = require('../../LazyLoader');
| |
| var lib = new LazyLoader(path.join(__dirname, '../../'));
| |
| module.exports = function() {
| |
| this.name = 'Foo';
| |
| this.bar = new lib.a.c.Bar();
| |
| };
| |
| | |
| | |
| И если у вас всего 1-2 подключаемых файла, то возможно данный подход покажется
| |
| вам неуместным, но при большем количестве — вы должны ощутить существенное
| |
| облегчение.
| |
| Кроме того вы можете сохранять ссылки на директории для сокрашения записи,
| |
| например:
| |
| | |
| var lib = new LazyLoader(__dirname);
| |
| var logLig = lib.dir1.dir2.dir3.log;
| |
| var f1 = new logLib.ConsoleLogger();
| |
| var f2 = new logLib.FileLogger(); // вместо //
| |
| var f1 = new lib.dir1.dir2.dir3.log.ConsoleLogger(); //
| |
| var f2 = new lib.dir1.dir2.dir3.log.FileLogger(); // и вместо //
| |
| var f1 = new require(__dirname + '/dir1/dir2/dir3/log/ConsoleLogger)(); //
| |
| var f2 = new require(__dirname + '/dir1/dir2/dir3/log/FileLogger)();
| |
| | |
| | |
| | |
| | |
| '''Заключение'''
| |
| | |
| 1. Указанный подход позволяет имитировать аналог '''namespace''' в других языках.
| |
| | |
| 2. Приведенный в примере '''LazyLoader''' легко расширить для работы с несколькими
| |
| директориями, например, для смешвания или переопределения модулей:
| |
| | |
| var lib = new LazyLoader('globalLibDir', 'applicationSpecificLibDir');
| |
| | |
| | |
| | |
| 3. Если Вы нашли неточности, опечатки или у вас есть альтернативные решения
| |
| подключения модулей — пишите в ЛС.
| |
| | |
| ссылка на оригинал статьи http://habrahabr.ru/post/164665/
| |
| | |
| [http://savepearlharbor.com/?p=164665 взято тут...] | |