-
-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fully qualified names vs imports #285
Comments
Как можно было бы зайдя на Гитхаб догадаться, что NavigationExtras из Angular находится в https://github.com/angular/angular/blob/master/packages/router/src/router.ts ? В начале файла мы видим типичную портянку из нескольких десятков инклудов. Многие импорты являются тавтологиями:
Зачем переименовывать snake_case в camelCase? Не обошлось и без полного переименовывания:
Стоит обратить внимание, что зачастую импортируются сложносоставные имена типа: Какие имена могли бы быть без импортов: // import {Location} from '@angular/common';
$ng_location
// import {Compiler, Injector, NgModuleFactoryLoader, NgModuleRef, Type, isDevMode} from '@angular/core';
$ng_compiler , $ng_injector , $ng_loader , $ng_module , $ng_debug
// import {BehaviorSubject} from 'rxjs/BehaviorSubject';
$rx_behaviour
// import {Observable} from 'rxjs/Observable';
$rx_observable
// import {Subject} from 'rxjs/Subject';
$rx_subject
// import {Subscription} from 'rxjs/Subscription';
$rx_subscription
// import {of } from 'rxjs/observable/of';
$rx_of
// import {concatMap} from 'rxjs/operator/concatMap';
$rx_map_concat
// import {map} from 'rxjs/operator/map';
$rx_map
// import {mergeMap} from 'rxjs/operator/mergeMap';
$rx_map_merge
// import {applyRedirects} from './apply_redirects';
$ng_route_redirect
// import {LoadedRouterConfig, QueryParamsHandling, Route, Routes, validateConfig} from './config';
$ng_route_config , $ng_query_handling , $ng_route , $ng_route_list , $ng_validation
// import {createRouterState} from './create_router_state';
$ng_route_state
// import {createUrlTree} from './create_url_tree';
$ng_url_tree
// import {ActivationEnd, ChildActivationEnd, Event, GuardsCheckEnd, GuardsCheckStart, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, ResolveEnd, ResolveStart, RouteConfigLoadEnd, RouteConfigLoadStart, RoutesRecognized} from './events';
$ng_route_activated , $ng_route_child_ended , $ng_route_event , $ng_route_guarded , $ng_route_guarding , $ng_route_cancel , $ng_route_navigated , $ng_route_error , $ng_route_navigating , $ng_route_resolved , $ng_route_resolving , $ng_route_loaded , $ng_route_loading , $ng_route_recognized
// import {PreActivation} from './pre_activation';
$ng_route_activating
// import {recognize} from './recognize';
$ng_route_recognize
// import {DefaultRouteReuseStrategy, DetachedRouteHandleInternal, RouteReuseStrategy} from './route_reuse_strategy';
$ng_route_default , $ng_route_detached , $ng_route_strategy
// import {RouterConfigLoader} from './router_config_loader';
$ng_route_loader
// import {ChildrenOutletContexts} from './router_outlet_context';
$ng_route_outlet
// import {ActivatedRoute, ActivatedRouteSnapshot, RouterState, RouterStateSnapshot, advanceActivatedRoute, createEmptyState} from './router_state';
$ng_route_active , $ng_route_snapshot_active , $ng_route_state , $ng_route_snapshot , $ng_route_active_advance , $ng_route_empty
// import {Params, isNavigationCancelingError} from './shared';
$ng_route_params , $ng_route_error_cancel
// import {DefaultUrlHandlingStrategy, UrlHandlingStrategy} from './url_handling_strategy';
$ng_url_handling_default , $ng_url_handling
// import {UrlSerializer, UrlTree, containsTree, createEmptyUrlTree} from './url_tree';
$ng_url_serializer , $ng_url_tree , $ng_url_tree_empty
// import {forEach} from './utils/collection';
$ng_each
// import {TreeNode, nodeChildrenAsMap} from './utils/tree';
$ng_tree_node , $ng_tree_dict |
Типы импортов
В JS и во многих других языках есть импорты двух видов: конкретные и массовые.
Конкретные импорты
Импортируют одно конкретное имя в локальную область видимости.
или
или
Такие импорты ни чем принципиально не отличаются от локальных алиасов:
Массовые импорты
Импортируют все имена из удалённого пространства имён в локальную область видимости.
В JS/TS по факту сейчас не работают.
Проблемы коротких имён
Потенциальные конфликты имён
Чем короче и абстрактнее имена, тем выше риск конфликтов. Приходится переименовывать импортируемые сущности. Зачастую в имена закладывают полную семантику, даже, когда она и так понятна из пути к модулю:
Разное название одной сущности в разных контекстах
При работе со множеством файлов (что типично, когда модули очень маленькие, а значит их много), приходится постоянно сверяться со списком переименовываний, чтобы понимать по какому имени обращаться к нужной сущности.
Синхронное изменение в нескольких местах файла
Начиная использовать сущность необходимо импортировать её в начале файла. Прекращая её использовать, нужно проверить, что нигде в файле она не используется и удалить импорт.
Необходимость вырезать лишнее при сборке
Актуально, когда импортируются не все сущности из внешнего модуля, то есть почти всегда. RollUp, tree shaking и тому подобные костыли.
Избыточно, когда место использования всего одно
Вместо того, чтобы писать:
Можно было бы просто написать:
В инструментах разработчика отображается короткое имя, а не полное
Если класс объявлен как:
То в отладчике/профайлере/консоли отображаться будет именно это короткое имя. Если же использовать полные имена:
То работа с инструментами разработчика становится куда приятней, так как не нужно гадать "который это Page из 5 и где находится".
Невозможно в рантайме определить полный путь.
Если класс/функция объявлен как:
То, через свойство
name
можно получить полный путь, что можно использовать, например, для генерации глобально-уникальных человекопонятных css-классов в DOM:Если же класс/функция объявлены лишь с коротким путём:
То всё, что мы можем получить - это локальное имя, что достаточно бесполезно.
Нет простого доступа к области видимости внешнего модуля
Чтобы через консоль посмотреть состояние спрятанное в замыкании нужно поплясать с бубном.
Захламление исходников
Портянки импортов и экспортов могут занимать не один десяток строк. Типичный пример. Кроме того, появляется необходимость делать специальные "индексные модули", которые импортируют все модули из директирии и экспортят их как один объект.
Захламление исходников захламляет и диффы на код-ревью, а также повышает риск конфликтов при слиянии веток, которые приходится разрешать вручную.
Разные механизмы для разных языков
JavaScript импортируются по одним правилам, CSS по другим, шаблоны - третьим. Подключив скрипты нужно не забыть подключить стили, подключив стили - не забыть добавить деплой нужных им картинок и тп связанные вещи. А если стили завязаны на что-то типа modernizr - не забыть подключить соответствующий скрипт.
Вместо всей этой кутерьмы в $mol модулем является директория и все файлы внутри (на каких бы языках они ни были) включаются в соответствующие бандлы.
Попустительство бардаку в проекте
Сущность может называться Foo, а лежать в файле Bar. В общем случае по имени сущности не понять в каком файле она определена и где этот файл искать.
Достоинства коротких имён
Можно использовать короткие локальные имена
Однако всегда можно сделать короткий локальный алиас, если в этом действительно есть необходимость:
Интеграция с большинством новых библиотек
Так как import/export попали в стандарт ES, то многие уже вовсю пилят библиотеки используя эти конструкции. Соответственно воспользоваться такими библиотеками проще используя те же механизмы.
Примеры из других языков
PHP
Symfony
https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Kernel/MicroKernelTrait.php
Ребята перестарались с таксономией. Незачем делать такие глубокие иерархии и пытаться впихнуть в название половину её описания. Куда лаконичней смотрелось бы короткое, но полное имя:
D
VibeD
http://vibed.org/api/vibe.http.router/URLRouter
Так как в языке распространены массовые импорты, то часто классы именуют многосложно. И всё-равно не понятно какой класс из какого модуля приехал. Хотя, можно же было бы сделать проще:
The text was updated successfully, but these errors were encountered: