"Unknown provider: aProvider <-a" 원래 프로바이더를 찾으려면 어떻게 해야 하나요?
미니 파일을 로드하는 경우(Uglify 경유)JS) My Angular 버전JS 응용 프로그램에서 콘솔에 다음 오류가 표시됩니다.
Unknown provider: aProvider <- a
이것은 변수 이름 망글링에 의한 것임을 알 수 있습니다.엉켜있지 않은 버전은 잘 작동한다.그러나 변수 이름 망글링을 사용하면 JS 출력 파일의 크기가 대폭 줄어들기 때문에 사용하고 싶습니다.
그 때문에 빌드 프로세스에서는 ngmin을 사용하고 있습니다만, 과거에 도움이 되었지만, 이 문제는 해결되지 않는 것 같습니다.
이 문제를 디버깅하기 위해 uglify grunt 태스크에서 소스 맵을 활성화했습니다.이 맵은 정상적으로 생성되며 Chrome은 서버에서 맵을 로드합니다.그러나 프로바이더의 원래 이름을 표시해야 한다고 생각했지만 여전히 도움이 되지 않는 오류 메시지가 나타납니다.
Chrome이 소스 맵을 사용하여 문제가 있는 프로바이더를 알려 주거나 다른 방법으로 프로바이더를 특정하려면 어떻게 해야 합니까?
이 문제의 원인이 된 소스코드의 위치를 어떻게 찾을 수 있었는지 알고 싶지만, 그 후 수동으로 문제를 찾을 수 있었습니다.
스코프에서 이 함수는 '컨트롤러'를 ..controller()
응용 프로그램모듈을 클릭합니다.
그래서 이런 게 있었어요.
function SomeController( $scope, i18n ) { /* ... */ }
이것은 Angular JS에서는 정상적으로 동작합니다만, 머글링을 올바르게 동작시키기 위해서, 다음과 같이 변경할 필요가 있었습니다.
var applicationModule = angular.module( "example" );
function SomeController( $scope, i18n ) { /* ... */ }
applicationModule.controller( "SomeController", [ "$scope", "i18n", SomeController ] );
추가 테스트 결과 문제의 원인이 되는 컨트롤러의 인스턴스를 실제로 발견했습니다.이러한 방법으로 모든 파일의 소스를 수동으로 찾았습니다.
우선, ugliify 옵션에서 출력 미화를 유효하게 하는 것이 중요하다고 생각합니다.델의 그른트 태스크는 다음을 의미합니다.
options : {
beautify : true,
mangle : true
}
그런 다음 Chrome에서 DevTools를 열고 프로젝트 웹사이트를 열었습니다.그러면 다음과 같은 오류가 기록됩니다.
우리가 관심 있는 통화 추적 방법은 화살표로 표시한 방법입니다.이것은 에 있습니다.예외 발생 지점에 중단점을 둘 수 있습니다.
이 시점에서 어플리케이션을 재실행하면 브레이크포인트가 히트하여 콜스택을 점프할 수 있습니다.에서 콜이 발생하며, "Intrect Injection Token" 문자열에서 인식할 수 있습니다.
locals
(''로 )d
code에 문제가 하게 알 수 .
»grep
많은 를 수 있다.modalInstance
그러나, 거기서부터, 소스에서 이 스팟을 발견하는 것은 쉬웠습니다.
var ModalCreateEditMeetingController = function( $scope, $modalInstance ) {
};
다음 항목으로 변경해야 합니다.
var ModalCreateEditMeetingController = [ "$scope", "$modalInstance", function( $scope, $modalInstance ) {
} ];
가 유용한 하지 못할 더할 수도 또, 「」에의 콜을, 「」로 설정할 필요가 .invoke
추가 힌트가 있어야 합니다.
이 문제가 재발하지 않도록 하다
이제 문제를 발견하셨으면 좋겠지만, 앞으로 이런 일이 재발하지 않도록 하는 최선의 방법을 말씀드려야 할 것 같습니다.
물론 인라인 배열 주석을 어디에서나 사용할 수 있습니다.또는 (기호에 따라) 속성 주석을 사용하여 나중에 잊지 않도록 할 수도 있습니다.이 경우 이와 같은 오류를 조기에 검출하기 위해 완전 의존성 주입 모드를 netable로 해야 합니다.
조심해!Angular Batarang을 사용하는 경우 StrictAngular Batarang이 주석 없는 코드를 삽입하기 때문에 DI가 작동하지 않을 수 있습니다(Bad Batarang!).
아니면 ng-notate에게 맡겨도 돼다음과 같이 이 영역에서 오류가 발생할 가능성을 많이 제거할 수 있으므로 이 방법을 사용하는 것이 좋습니다.
- DI 주석이 없습니다.
- DI 주석이 불완전합니다.
- DI 주석 순서가 잘못되었습니다.
주석을 최신 상태로 유지하는 것은 귀찮은 일이며, 자동으로 할 수 있다면 할 필요가 없습니다.ng-notate는 바로 그렇게 합니다.
grunt-ng-ng-ng-ngnotate 및 gul-ng-ng-ng-ngnotate를 사용하여 빌드 프로세스에 적절하게 통합됩니다.
올리버 잘츠부르크의 글은 환상적이었다.투표수가 늘었다.
이 오류가 있을 수 있는 사용자에게 팁입니다.단순히 명령어 컨트롤러에 어레이를 전달하는 것을 잊어버린 것이 원인입니다.
나빠
return {
restrict: "E",
scope: {
},
controller: ExampleDirectiveController,
templateUrl: "template/url/here.html"
};
좋아요.
return {
restrict: "E",
scope: {
},
controller: ["$scope", ExampleDirectiveController],
templateUrl: "template/url/here.html"
};
ng-app과 함께 ng-param-di 사용
Angular 1.3을 사용하는 경우 ngStrictDi 디렉티브를 ngApp과 함께 사용하면 피해를 피할 수 있습니다.
<html lang="en" ng-app="myUglifiablyGreatApp" ng-strict-di>
이제 (미니메이션 전) 주석을 사용하지 않는 모든 콘솔이 파괴되고 스택 트레이스를 통해 헌팅하지 않고도 빌어먹을 이름을 볼 수 있습니다.
문서별:
애플리케이션은 명시적 함수 주석을 사용하지 않는 함수 호출에 실패한다(따라서 최소화에 적합하지 않음).
주의사항 중 하나는 주석이 있는 것만 감지하고 주석이 완전하다는 것은 감지하지 않는다는 것입니다.
의미:
['ThingOne', function(ThingA, ThingB) { … }]
ThingB가 주석의 일부가 아니라는 것을 알아채지 못할 것이다.
이 팁에 대한 공적은 ng-notate 사용자에게 돌아간다. 이는 현재 폐지된 ngMin보다 권장된다.
각도를 최소화하려면 선언을 "array" 선언 "mode"로 변경하면 됩니다. 예를 들어 다음과 같습니다.
송신원:
var demoApp= angular.module('demoApp', []);
demoApp.controller(function demoCtrl($scope) {
} );
로.
var demoApp= angular.module('demoApp', []);
demoApp.controller(["$scope",function demoCtrl($scope) {
}]);
공장 서비스를 어떻게 신고합니까?
demoApp.factory('demoFactory', ['$q', '$http', function ($q, $http) {
return {
//some object
};
}]);
방금 같은 문제가 발생하여 단순히 ngmin(지금은 권장되지 않음)을 ng-notate로 대체하여 문제를 해결했습니다.
이 커밋에서는 yoman angular도 ng-commitate를 사용하도록 갱신된 것 같습니다.https://github.com/yeoman/generator-angular/commit/3eea4cbeb010eeaaf797c17604b4a3ab5371eccb
하지만 저처럼 오래된 버전의 yoman angular를 사용하고 있다면 패키지에 있는 ng-min을 ng-notate로 대체해 주세요.json:
- "grunt-ngmin": "^0.0.3",
+ "grunt-ng-annotate": "^0.3.0",
달려.npm install
(옵션으로)npm prune
편집 커밋의 변경에 따릅니다.Gruntfile.js
.
원래 변수 이름이 무엇이었는지 알기 위해 uglife가 변수를 망치는 방법을 변경할 수 있습니다.
../node_module/grunt-module-uglify/node_module-module/lib/module.js
SymbolDef.prototype = {
unmangleable: [...],
mangle: function(options) {
[...]
this.mangled_name = s.next_mangled(options, this)+"_orig_"+this.orig[0].name;
[...]
}
};
그리고 이제 오류는 훨씬 더 명백해졌습니다.
Error: [$injector:unpr] Unknown provider: a_orig_$stateProvider
http://errors.angularjs.org/1.3.7/$injector/unpr?p0=a_orig_%24stateProvider
at eval (eval at <anonymous> (http://example.com/:64:17), <anonymous>:3155:20)
편집
이제 알 것 같아...
Gruntfile.js
uglify: {
example: {
options: {
beautify: true,
mangle: true
},
[...]
},
[...]
}
../node_module/grunt-module-uglify/node_module-module/lib/module.js
var numberOfVariables = 1;
SymbolDef.prototype = {
unmangleable: [...],
mangle: function(options) {
[...]
this.mangled_name = s.next_mangled(options, this)+"_orig_"+this.orig[0].name+"_"+numberOfVariables++;
[...]
}
};
이제 각 변수는 원래 값을 포함하는 고유한 값으로 엉켜집니다.miniated javascript를 열고 "a_orig_$stateProvider_91212"를 검색하면 됩니다.본연의 맥락으로 보게 될 겁니다
이보다 더 쉬울 순 없어
또한 잊지 마십시오.resolve
루트의 속성.또한 어레이로 정의해야 합니다.
$routeProvider.when('/foo', {
resolve: {
bar: ['myService1', function(myService1) {
return myService1.getThis();
}],
baz: ['myService2', function(myService2) {
return myService2.getThat();
}]
}
});
제너레이터-굴프-각선 포함:
/** @ngInject */
function SomeController($scope, myCoolService) {
}
각 컨트롤러, 서비스, 지시문 앞에 /** @ngInject */ 라고 씁니다.
Uglify가 변수 이름을 magle/false할 필요가 없는 경우 이를 위한 빠르고 더러운 수정은 Grunt 파일에서 magle = false를 설정하는 것입니다.
uglify: {
compile: {
options: {
mangle : false,
...
},
}
}
언급URL : https://stackoverflow.com/questions/21688681/unknown-provider-aprovider-a-how-do-i-find-the-original-provider
'IT' 카테고리의 다른 글
함수에 외부 파일을 포함합니다.php WordPress (0) | 2023.02.10 |
---|---|
Telem API와의 상호작용 방법 (0) | 2023.02.10 |
WordPress 테마에서 jQuery를 $로 재매핑한 후 js 파일 외부에서 함수를 트리거할 수 없습니다. (0) | 2023.02.10 |
angular 1.5에서 ui.bootstrap.modal과 함께 angular 구성 요소를 사용하는 방법 (0) | 2023.02.10 |
루프에서 약속으로 변수 전달 (0) | 2023.02.10 |