«Node js & Подключение модулей без явного использования require или аналог namespace» и «Golang - библиотека начинающего»: разница между страницами

Материал из support.qbpro.ru
(Различия между страницами)
imported>Vix
Нет описания правки
 
imported>Vix
(Новая страница: «'''ПОЛЕЗНОЕ:''' <hr> * [https://golangs.org/ Уроки для изучения Golang] * [https://metanit.com/go/tutorial/2.11.php Функции и их...»)
 
Строка 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 взято тут...]

Версия от 09:13, 18 августа 2020