как проверить наличие модуля без возникновения ошибки?

<p>в angular 1.2 <code>ngroute</code> - это отдельный модуль, поэтому вы можете использовать другие маршрутизаторы сообщества, такие как <code>ui.router</code>.</p><p>я пишу модуль с открытым исходным кодом, который предназначен для работы с несколькими различными реализациями маршрутизаторов. итак, как я могу проверить, какой маршрутизатор загружен или существует?</p><p>я делаю следующее внутри фабрики в моем модуле, но это не работает так, как я ожидаю:</p><pre><code>if (angular.module("ngroute")) // do ngroute-specific stuff. else if (angular.module("ui.router")) // do ui.router-specific stuff. </code></pre><p>это вызывает ошибку для того, какой модуль не загружен. например, если приложение использует <code>ui.router</code>, для проверки <code>ngroute</code> возникает следующая ошибка:</p><blockquote> <p>неопознанная ошибка: [$ injector: nomod] модуль 'ngroute' недоступен! вы либо неправильно написали имя модуля, либо забыли загрузить его. если при регистрации модуля убедитесь, что вы указали зависимости как второй аргумент. </blockquote>

я не знаю способ проверки без возникновения ошибки; однако обратите внимание, что проблема в том, что это был uncaught error, а не в том, что была выдана ошибка. шаблон для обнаружения такой ошибки следующий.try { angular.module("ngroute") } catch(err) { / failed to require / } если обнаружена ошибка, вы можете попробовать другой модуль, а если нет, вы можете использовать первый.если ваше поведение будет одинаковым для каждого модуля, вы можете сделать что-то вроде следующего, в котором мы определяем функцию, которая будет пытаться выполнить первое из перечисленных имен модулей, и, если выдается ошибка, попробуйте следующую опцию.var trymodules = function(names) { // accepts a list of module names and // attempts to load them, in order. // if no options remain, throw an error. if( names.length == 0 ) { throw new error("none of the modules could be loaded."); } // attempt to load the module into m var m; try { m = angular.module(names[0]) } catch(err) { m = null; } // if it could not be loaded, try the rest of // the options. if it was, return it. if( m == null ) return trymodules(names.slice(1)); else return m; }; trymodules(["ngroute", "ui.router"]); 

я бы протестировал сервис вместо самого модуля.// in controller if($injector.has('$route')){ } if($injector.has('$state')){ } // in angular config if($injector.has('$routeprovider')){ } if($injector.has('$stateprovider')){ } 

оригинальный ответ является законным. однако, в качестве альтернативы, я написал это, когда мне нужно было «найти или создать» модули. существует несколько вариантов использования, но, как правило, это позволяет вам не беспокоиться о порядке загрузки файлов. вы можете либо поместить это в initialmodules.js..., либо в начало всех ваших отдельных служебных/директивных файлов начать что-то вроде этого. эта маленькая функция работает для меня как шарм:var initialmodules = [ {name: 'app.directives', deps: ['ui.mask']}, {name: 'app.services'}, {name: 'app.templates'}, {name: 'app.controllers'} ]; initialmodules.foreach(function(moduledefinition) { findorcreatemodule(moduledefinition.name, moduledefinition.deps); }); function findorcreatemodule(modulename, deps) { deps = deps || []; try { angular.module(modulename); } catch (error) { angular.module(modulename, deps); } } ///// or... in like "mydirective.js" findorcreatemodule('app.directives').directive('mydirective', mydirectivefunction); 

если вы декорируете angular.module для хранения имен в массиве, вы можете просто проверить, содержит ли массив имя вашего модуля.украсить angular.moduleсмотрите <a href="https://stackoverflow.com/a/24890518/1123275">@ dsfq ответ на so .это должно произойти после загрузки угловых модулей, но перед началом загрузки любых угловых модулей.проверьте свой модульif(angular.modules.indexof("ngroute") > -1) ...

гораздо лучшим решением будет просто выполнить проверку при создании модуля. вам просто нужна служебная функция для добавления обратного вызова.//create a utility function to add a callback to object methods //here we are making it a method of the underscore or lowdash object //but it could be added to the angular global object or anything else _.addcallback = function (obj, originalmethodname, callbackmethod, context){ var fnoriginal = obj[originalmethodname], outcome; context = context || obj; obj[originalmethodname] = function () { var outcome = fnoriginal.apply(this, arguments); callbackmethod.apply(this, arguments); return outcome; }; }; _.addcallback(angular, "module", function(smodulename, asdependencies){ if(_.contains(asdependencies, "ngroute")){ //your logic here //just loop through if you don't use underscore or lowdash } }); 

angularjs 1.6.3 и выше имеет <a href="https://code.angularjs.org/1.6.3/docs/api/auto/service/$injector#modules">способ проверить, загружен ли модуль</a> через сервис $ инжектор.также в 1.6.7 была добавлена  <a href="https://code.angularjs.org/1.6.7/docs/api/auto/service/$injector#loadnewmodules">возможность загружать новые модули</a> которые могут быть интересны для некоторых.</p>

<p>проблема автоматической загрузки или создания модуля может быть лучше решена с помощью чего-то вроде gulp-angular-filesort, хотя .. это работает действительно безупречно.</p><p>from <a href="https://github.com/klei/gulp-angular-filesort">gulp-angular-filesort</a> github page: <em>автоматически сортировать файлы приложения angularjs в зависимости от определений модуля и использования</em></p><p>используется вместе с gulp-inject для внедрения файлов приложений (скриптов) angularjs в правильном порядке, чтобы избавиться от всех <em>uncaught error: [$ injector: modulerr]</em>.</p><p><em>disclaimer</em>: я не связан с gulp-angular-filesort, я использую его только с большой прибылью.</p>