"अज्ञात प्रदाता: aProvider <-" मुझे मूल प्रदाता कैसे मिलेगा?


100

जब मैं अपने AngularJS एप्लिकेशन के लघु संस्करण (UglifyJS के माध्यम से) लोड कर रहा हूं, तो मुझे कंसोल में निम्नलिखित त्रुटि मिलती है:

Unknown provider: aProvider <- a

अब, मुझे एहसास हुआ कि यह परिवर्तनशील नाम के कारण है। असम्बद्ध संस्करण ठीक काम करता है। हालाँकि, मैं वैरिएबल नेम मैनबलिंग का उपयोग करना चाहता हूं , क्योंकि यह हमारे जेएस आउटपुट फाइल के आकार को काफी कम कर देता है।

इस कारण से, हम अपनी निर्माण प्रक्रिया में एनकमिन का उपयोग कर रहे हैं , लेकिन यह इस समस्या को हल करने के लिए प्रतीत नहीं होता है, भले ही यह हमें अतीत में अच्छी तरह से परोसा गया हो।

इसलिए, इस समस्या को दूर करने के लिए, मैंने स्रोत मानचित्रों को हमारे कुरूपित ग्रन्ट कार्य में सक्षम किया। वे बस ठीक से उत्पन्न होते हैं और क्रोम सर्वर से नक्शे को लोड करता है। फिर भी, मुझे अभी भी वही त्रुटिहीन संदेश मिलता है, भले ही मैं इस धारणा के तहत था कि मुझे अब प्रदाता का मूल नाम देखना चाहिए।

मुझे यह बताने के लिए कि मुझे कौन सी प्रदाता समस्या है, या वैकल्पिक रूप से, मैं दूसरे तरीके से प्रदाता का पता कैसे लगा सकता हूं?


आप प्रत्येक JS स्रोत फ़ाइल (यदि पहले से ही मामला नहीं है) में अलग-अलग टिप्पणियाँ जोड़ने का प्रयास कर सकते हैं, और UglifyJS के संरक्षित विकल्प का उपयोग कर सकते हैं: जो आपको यह अनुमान देगा कि किस फ़ाइल में गलत कोड है।
जेबी निज़ेट

क्या आप डेकोरेटर का उपयोग कर रहे हैं? मैंने पाया है कि डेकोरमिन ने डेकोरेटर को फिर से लिखना ठीक नहीं समझा है जब मैंने इसे अतीत में इस्तेमाल किया है जिसके परिणामस्वरूप आपकी तरह त्रुटियां होती हैं।
dherman

@ जेबीएनज़ेट: मुझे यह विचार पसंद है, लेकिन विकल्पों में उस निर्देश को जोड़ने से कोई प्रभाव नहीं पड़ता है।
डेर होकस्टापलर

@ डरमन: क्या आप मुझे डेकोरेटर्स का उदाहरण दे सकते हैं? मुझे यकीन नहीं है कि वे इस संदर्भ में क्या करेंगे।
डेर होकस्टापलर

देखें github.com/gruntjs/grunt-contrib-uglify (यदि आप घुरघुराना उपयोग करें)। विकल्प का मूल्य "सभी" होना चाहिए।
जेबी निज़ेट

जवाबों:


193

मुझे यह जानने में अभी भी अच्छा लगेगा कि मुझे हमारे स्रोत कोड में कैसे जगह मिल सकती है जो इस मुद्दे का कारण बनती है, लेकिन मैं तब से समस्या को मैन्युअल रूप से ढूंढने में सक्षम हूं।

.controller()अनुप्रयोग मॉड्यूल पर कॉल का उपयोग करने के बजाय, वैश्विक दायरे पर एक नियंत्रक फ़ंक्शन घोषित किया गया था ।

तो ऐसा कुछ था:

function SomeController( $scope, i18n ) { /* ... */ }

यह AngularJS के लिए ठीक काम करता है, लेकिन इसे सही तरीके से काम करने के लिए बनाने के लिए, मुझे इसे बदलना पड़ा:

var applicationModule = angular.module( "example" );
function SomeController( $scope, i18n ) { /* ... */ }
applicationModule.controller( "SomeController", [ "$scope", "i18n", SomeController ] );

आगे के परीक्षणों के बाद, मुझे वास्तव में अधिक नियंत्रकों के उदाहरण मिले जो मुद्दों का कारण भी बने। इस तरह से मुझे उन सभी का स्रोत मैन्युअल रूप से मिला :

सबसे पहले, मैं इसे कुरकुरा विकल्पों में आउटपुट सौंदर्यीकरण को सक्षम करने के बजाय महत्वपूर्ण मानता हूं। हमारे गंभीर कार्य का मतलब है कि:

options : {
    beautify : true,
    mangle   : true
}

मैंने तब क्रोम में प्रोजेक्ट वेबसाइट खोली, जिसमें DevTools खुले थे। जिसके परिणामस्वरूप त्रुटि हो सकती है जैसे नीचे लॉग इन किया जा रहा है:

यहां छवि विवरण दर्ज करें

जिस कॉल ट्रेस में हम रुचि रखते हैं, वह विधि वह है जिसे मैंने एक तीर से चिह्नित किया है। यह वह जगह है providerInjectorमेंinjector.js । आप एक ब्रेकपॉइंट रखना चाहते हैं जहां यह एक अपवाद फेंकता है:

यहां छवि विवरण दर्ज करें

जब आप अब एप्लिकेशन को फिर से चलाते हैं, तो ब्रेकपॉइंट मारा जाएगा और आप कॉल स्टैक को जंप कर सकते हैं। वहाँ से एक फोन हो जाएगा invokeमेंinjector.js , स्ट्रिंग "टोकन गलत इंजेक्शन" से पहचानने योग्य:

यहां छवि विवरण दर्ज करें

localsपैरामीटर (करने के लिए घायल dमेरी कोड में) एक बहुत अच्छा विचार है अपने स्रोत में जो वस्तु के बारे में समस्या है देता है:

यहां छवि विवरण दर्ज करें

grepहमारे स्रोत पर एक त्वरित स्थिति के कई उदाहरण मिलते हैं modalInstance, लेकिन वहां से जाने पर, इस स्थान को स्रोत में खोजना आसान था:

var ModalCreateEditMeetingController = function( $scope, $modalInstance ) {
};

जिसे बदलना होगा:

var ModalCreateEditMeetingController = [ "$scope", "$modalInstance", function( $scope, $modalInstance ) {
} ];

यदि वैरिएबल उपयोगी जानकारी नहीं रखता है, तो आप स्टैक पर आगे भी कूद सकते हैं और आपको एक कॉल करना invokeचाहिए, जिसमें अतिरिक्त संकेत होने चाहिए:

यहां छवि विवरण दर्ज करें

इसे दोबारा होने से रोकें

अब जब आपको उम्मीद है कि समस्या मिल गई है, तो मुझे लगता है कि मुझे इस बात का उल्लेख करना चाहिए कि भविष्य में फिर से ऐसा करने से कैसे बचें।

जाहिर है, आप हर जगह इनलाइन सरणी एनोटेशन का उपयोग कर सकते हैं , या (आपकी पसंद के आधार पर) $injectसंपत्ति एनोटेशन और बस भविष्य में इसके बारे में भूल नहीं करने का प्रयास करें। यदि आप ऐसा करते हैं, तो इस तरह की त्रुटियों को पकड़ने के लिए, सख्त निर्भरता इंजेक्शन मोड को सक्षम करना सुनिश्चित करें ।

ध्यान रहे! यदि आप कोणीय बातरंग का उपयोग कर रहे हैं, तो आपके लिए स्ट्रिक्टडीआई काम नहीं कर सकता है, क्योंकि कोणीय बातरंग आपके (ख़राब बतरंग!) में असम्बद्ध कोड इंजेक्ट करता है।

या आप एनजी-एनोटेट का ध्यान रख सकते हैं। मैं ऐसा करने की अत्यधिक सलाह देता हूं, क्योंकि यह इस क्षेत्र में गलतियों की बहुत संभावना को दूर करता है, जैसे:

  • डि एनोटेशन गायब
  • डि एनोटेशन अधूरा
  • गलत क्रम में डि एनोटेशन

एनोटेशन को अप-टू-डेट रखना केवल गधे में एक दर्द है और अगर आपको यह स्वचालित रूप से किया जा सकता है, तो आपको ऐसा नहीं करना चाहिए। एनजी-एनोटेट ठीक यही करता है।

यह grunt-ng-annotate और gulp-ng-annotate के साथ अपने निर्माण की प्रक्रिया में अच्छी तरह से एकीकृत होना चाहिए ।


12
यह एक शानदार लेखन है, जिसे देखभाल के साथ लिखा गया है। मैं बस इस मुद्दे में भाग गया, लगता है कि यह कहीं गहरे में एक मुद्दा है। आपके सुझावों ने मुझे यह जानने में मदद की कि मुझे कहाँ देखना है। अंत में मैंने अपने सभी कोणीय params सिर्फ "सरणी-आइफाइड" किया, और समस्या दूर हो गई। सभी पूर्व-निर्मित एनजी-मिनिफ़ाइड बस ठीक है, और कुछ भी नहीं बदला है। मैंने कोई वैश्विक फ़ंक्शन नहीं जोड़ा - यह बस कुछ नियंत्रक / निर्देश / सेवा / फ़िल्टर का प्रबंधन करके, रहस्यमय तरीके से काम करना बंद कर दिया?
झेनकॉन

यह मदद का एक बड़ा स्रोत था। मुझे नहीं पता था कि आपको अन्य कार्यों के लिए भी सरणी (इनलाइन) सिंटैक्स का उपयोग करना होगा, जैसे राउटर
रिज़ॉल्यूशन

4
मेरे मामले में यह निर्देशन में नियंत्रक था। यदि 'd' वैरिएबल में आपको $ attr दिखाई देगा, तो शायद यही समस्या है। आपको आंतरिक निर्देशन नियंत्रक के लिए सरणी कोष्ठक में परिम को लपेटना चाहिए। नियंत्रक: [ "$ गुंजाइश", समारोह ($ गुंजाइश) {...}] के बजाय नियंत्रक: समारोह ($ गुंजाइश) {...}
एलेक्स Naumov

Var फ़ंक्शन संदर्भ के लिए सुरक्षित निर्भरता इंजेक्शन / सरणी संकेतन का उपयोग करके आपके लिखने और समाधान के लिए बहुत बहुत धन्यवाद। मेरे पास भी यह त्रुटि थी और आपके समाधान के कारण मैं आगे बढ़ता रहा। आपने धमाल मचाया!
फ्रेंकी लोसावियो

1
जब भी मेरे पास यह मुद्दा होता है मैं इसे फिर से पढ़ता हूं और फिर से इसके लिए मतदान करना चाहता हूं। Btw, यहाँ कैसे gulp संस्करण सेटअप करने के लिए हैuglify({ output : { beautify : true }})
यूजीन Gluhotorenko

30

ओलिवर साल्ज़बर्ग का लेखन शानदार था। Upvoted।

जिस किसी के पास भी यह त्रुटि हो सकती है, उसके लिए युक्ति। एक डायरेक्टर कंट्रोलर के लिए एक ऐरे में पास होना भूल जाने के कारण मेरा बस हो गया:

खराब

return {
    restrict: "E",
    scope: {                
    },
    controller: ExampleDirectiveController,
    templateUrl: "template/url/here.html"
};

अच्छा

return {
    restrict: "E",
    scope: {                
    },
    controller: ["$scope", ExampleDirectiveController],
    templateUrl: "template/url/here.html"
};

2
यह इस तरह के एक अजीब था ... हाल ही में एक अद्यतन तक Uglify मेरे लिए यह कारण नहीं था!
सैममोरड्रेम्स

मेरा मुद्दा समान था, लेकिन यह पता चला है कि मुझे /* @ngInject */फ़ंक्शन को जोड़ने की आवश्यकता थी । ऐसा लगता है कि प्रत्येक शामिल मॉड्यूल को टाइप करने की आवश्यकता के बिना जटिल इंजेक्शन भाग करना है (मैं
योमन

25

एनजी-एप के साथ एनजी-सख्त-दी का उपयोग करें

यदि आप Angular 1.3 का उपयोग कर रहे हैं, तो आप ngApp के साथ ngStrictDi निर्देश का उपयोग करके अपने आप को चोट की दुनिया को बचा सकते हैं :

<html lang="en" ng-app="myUglifiablyGreatApp" ng-strict-di>

अब - प्री-मिनिफिकेशन - कुछ भी जो एनोटेशन का उपयोग नहीं करता है, आपके कंसोल को उड़ा देगा और आप मैंगल्ड स्टैक के निशान के माध्यम से बिना शिकार के फ्रिगिन का नाम देख सकते हैं।

डॉक्स के अनुसार:

एप्लिकेशन ऐसे फ़ंक्शन को लागू करने में विफल हो जाएगा जो स्पष्ट फ़ंक्शन एनोटेशन का उपयोग नहीं करते हैं (और इस प्रकार minification के लिए अनुपयुक्त हैं)

एक चेतावनी है, यह केवल का पता लगाता है कि कर रहे हैं एनोटेशन, नहीं है कि एनोटेशन पूरा कर रहे हैं।

अर्थ:

['ThingOne', function(ThingA, ThingB) {  }]

यह नहीं पकड़ेंगे कि थिंगब एनोटेशन का हिस्सा नहीं है।

इस टिप के लिए श्रेय एनजी-एनोटेट लोगों को जाता है , जो अब पदावनत एनजीएमिन की सिफारिश करता है।


इसके लिए अधिक उर्जा की जरूरत है। यह एक ऐप डिबग करने के लिए बहुत अच्छा है जो कभी भी उपयोग नहीं किया है या स्ट्रिंग सरणी सिंटैक्स।
माइकल पियर्सन

11

कोणीय की सब कुछ करने के लिए आपको अपनी घोषणा को उदाहरण के लिए "सरणी" घोषणा "मोड" में बदलना है:

से:

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
    };
}]);

मुझे पता है। इसीलिए हम एनमिन का इस्तेमाल करते हैं। मुझे संदेह है कि यह हमारे स्रोत या इसकी निर्भरता के कुछ हिस्से के साथ एक समस्या है। यही कारण है कि मैं इस मुद्दे की जड़ में जाने की कोशिश कर रहा हूं।
डेर होकस्टापलर

1
मेरी सिफारिश है कि आप अपना कोड इस तरह से बनाएं। तो आप किसी भी मिनिफाइजर का उपयोग कर सकते हैं
Dalorzo

3
मैं कर रहा हूँ हमारे कोड इस तरह का निर्माण। लेकिन हमारे पास बाहरी निर्भरताएं हैं जो नहीं हैं। एनकमिन ने अतीत में हमारे लिए इस समस्या को अच्छी तरह से हल किया है। मैं मानती हूं कि हालिया बदलाव ने यह मुद्दा बनाया है। मैं अब इस मुद्दे का स्रोत ढूंढना चाहूंगा ताकि मैं इसे हमारे कोड, हमारी निर्भरता या संभवतः स्वयं को एनमिन में ठीक से ठीक कर सकूं।
डेर होकस्टापलर

चूंकि यह मुद्दा किसी विशेष घटक या कोड के लिए एक बहुत ही विशिष्ट जैसा लगता है, इसलिए मार्गदर्शन प्रदान करना कठिन है, कम से कम मेरे अंत से
Dalorzo

एनक्मिन आपको सरणी घोषणा मोड का उपयोग करने की आवश्यकता नहीं है, यह बहुत सारी बेकार घोषणाओं को जोड़ता है।
नैनोकॉम 23

8

मुझे बस एक ही समस्या थी और इसे अपने ग्रंट बिल्ड टास्क के लिए एनजी-एनोटेट के साथ बस एनक्मिन (अब पदावनत) की जगह देकर हल किया।

ऐसा लगता है कि Yeoman कोणीय भी एनजी-व्याख्या का उपयोग करने के लिए इस के रूप में प्रतिबद्ध अद्यतन किया गया है: https://github.com/yeoman/generator-angular/commit/3eea4cbeb010eeaaf797c17604b4a3ab5371eccb

हालाँकि, यदि आप मेरे जैसे पुराने कोणीय संस्करण का उपयोग कर रहे हैं, तो अपने पैकेज में एनजी-एनोटेट के साथ एनजी-मिन को बदलें।

-    "grunt-ngmin": "^0.0.3",
+    "grunt-ng-annotate": "^0.3.0",

चलाने npm install(तब वैकल्पिक रूप से npm prune), और संपादित करने के लिए प्रतिबद्ध में परिवर्तनों का पालन करें Gruntfile.js


7

यह जानने के लिए कि मूल चर नाम क्या था, आप इसे बदल सकते हैं कि चर को कैसे छोटा किया जाए:

../node_modules/grunt-contrib-uglify/node_modulesuglify-js/lib/scope.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_modules/grunt-contrib-uglify/node_modulesuglify-js/lib/scope.js

var numberOfVariables = 1;
SymbolDef.prototype = {
  unmangleable: [...],
  mangle: function(options) {
    [...]
    this.mangled_name = s.next_mangled(options, this)+"_orig_"+this.orig[0].name+"_"+numberOfVariables++;
    [...]
  }
};

अब प्रत्येक चर को एक अद्वितीय मान दिया जाता है, जिसमें मूल भी होता है ... बस कीमाधारित जावास्क्रिप्ट खोलें और "a_orig_ $ stateProvider_91212" या जो कुछ भी खोजते हैं ... आप इसे मूल रूप से देखेंगे ...

कोई आसान नहीं हो सकता ...


4

साथ resolveही मार्ग की संपत्ति को न भूलें । यह भी सरणी के रूप में परिभाषित किया जाना चाहिए:

$routeProvider.when('/foo', {
    resolve: {
        bar: ['myService1', function(myService1) {
            return myService1.getThis();
        }],
        baz: ['myService2', function(myService2) {
            return myService2.getThat();
        }]
    }
});

यह मेरे साथ तब हुआ जब मैंने अपने मार्गों में हल का एक गुच्छा जोड़ा। आपने संभावित रूप से मुझे दर्दनाक डिबगिंग के घंटे बचाए हैं, धन्यवाद।
पॉल मैकलीन

3

जनरेटर-गुल-कोणीय के साथ:

   /** @ngInject */
    function SomeController($scope, myCoolService) {

}

प्रत्येक नियंत्रक, सेवा, निर्देश से पहले / ** @ngInject * / लिखें ।


2

इसके लिए एक त्वरित और गंदे फिक्स यदि आपको Uglify की आवश्यकता नहीं है

    uglify: {
        compile: {
            options: {
                mangle   : false,
                ...
            },
        }
    }

यह समस्या को हल कर सकता है, लेकिन परिणामी बिल्ड आकार बड़ा होगा क्योंकि मंगल अक्षम है।
नोटबॉट

अभी भी छोटे से ज्यादा नहीं
बदसूरत
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.