source

Angular.js에서 다른 환경을 설정하려면 어떻게 해야 합니까?

manysource 2022. 11. 3. 21:55

Angular.js에서 다른 환경을 설정하려면 어떻게 해야 합니까?

다양한 환경의 구성 변수/정수를 어떻게 관리합니까?

예를 들어 다음과 같습니다.

는 rest API로 할 수 .localhost:7080/myapi/ 하에 내 를 배치하고 있습니다.localhost:8099/hisapi/.

다음과 같은 것이 있다고 가정합니다.

angular
    .module('app', ['ngResource'])

    .constant('API_END_POINT','<local_end_point>')

    .factory('User', function($resource, API_END_POINT) {
        return $resource(API_END_POINT + 'user');
    });

환경에 따라 API 엔드포인트의 올바른 값을 동적으로 삽입하려면 어떻게 해야 합니까?

PHP를 하여 이러한 합니다.config.username.xml기본 구성 파일(config.xml)을 사용자 이름으로 인식되는 로컬 환경 구성 파일과 병합합니다.그런데 자바스크립트로 이런 걸 어떻게 관리해야 하는지 모르겠어요?

좀 늦었지만 Grunt를 사용한다면 에서 큰 성공을 거뒀습니다.

ngconstant 집에서는Gruntfile.js가 마치

ngconstant: {
  options: {
    name: 'config',
    wrap: '"use strict";\n\n{%= __ngModule %}',
    space: '  '
  },
  development: {
    options: {
      dest: '<%= yeoman.app %>/scripts/config.js'
    },
    constants: {
      ENV: 'development'
    }
  },
  production: {
    options: {
      dest: '<%= yeoman.dist %>/scripts/config.js'
    },
    constants: {
      ENV: 'production'
    }
  }
}

「 」를 사용하는 ngconstant

grunt.registerTask('server', function (target) {
  if (target === 'dist') {
    return grunt.task.run([
      'build',
      'open',
      'connect:dist:keepalive'
    ]);
  }

  grunt.task.run([
    'clean:server',
    'ngconstant:development',
    'concurrent:server',
    'connect:livereload',
    'open',
    'watch'
  ]);
});

grunt.registerTask('build', [
  'clean:dist',
  'ngconstant:production',
  'useminPrepare',
  'concurrent:dist',
  'concat',
  'copy',
  'cdnify',
  'ngmin',
  'cssmin',
  'uglify',
  'rev',
  'usemin'
]);

달리기를 하다grunt server 를 will will a a가 됩니다.config.jsapp/scripts/ 것 같다

"use strict";
angular.module("config", []).constant("ENV", "development");

마지막으로 필요한 모듈에 대한 의존성을 선언합니다.

// the 'config' dependency is generated via grunt
var app = angular.module('myApp', [ 'config' ]);

이제 내 상수는 필요한 곳에 종속성을 주입할 수 있습니다.예.,

app.controller('MyController', ['ENV', function( ENV ) {
  if( ENV === 'production' ) {
    ...
  }
}]);

다른 모든 모듈이 의존하는 다른 각형 모듈로 모든 환경 고유의 값을 분리하는 것이 하나의 솔루션일 수 있습니다.

angular.module('configuration', [])
       .constant('API_END_POINT','123456')
       .constant('HOST','localhost');

그런 다음 이러한 엔트리를 필요로 하는 모듈이 엔트리에 대한 의존관계를 선언할 수 있습니다.

angular.module('services',['configuration'])
       .factory('User',['$resource','API_END_POINT'],function($resource,API_END_POINT){
           return $resource(API_END_POINT + 'user');
       });

이제 더 멋진 것에 대해 생각해 볼 수 있습니다.

설정을 포함하는 모듈은 페이지에 포함된 configuration.js로 나눌 수 있습니다.

이 스크립트는 git에 별도의 파일을 체크하지 않는 한 각자 쉽게 편집할 수 있습니다.단, 설정이 다른 파일에 있는 경우 체크인을 하지 않는 것이 더 쉽습니다.또한 로컬로 분기할 수도 있습니다.

ANT나 Maven과 같은 빌드 시스템이 있는 경우 추가 단계는 빌드 시간 동안 특정 값으로 대체되는 API_END_POINT 값의 플레이스 홀더를 구현하는 것입니다.

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★.configuration_a.js ★★★★★★★★★★★★★★★★★」configuration_b.js이치노

Gulp 사용자에게 gulp-ng-constantgulp-concat, event-streamyargs와 함께 사용할 수도 있습니다.

var concat = require('gulp-concat'),
    es = require('event-stream'),
    gulp = require('gulp'),
    ngConstant = require('gulp-ng-constant'),
    argv = require('yargs').argv;

var enviroment = argv.env || 'development';

gulp.task('config', function () {
  var config = gulp.src('config/' + enviroment + '.json')
    .pipe(ngConstant({name: 'app.config'}));
  var scripts = gulp.src('js/*');
  return es.merge(config, scripts)
    .pipe(concat('app.js'))
    .pipe(gulp.dest('app/dist'))
    .on('error', function() { });
});

설정 폴더에는 다음 파일이 있습니다.

ls -l config
total 8
-rw-r--r--+ 1 .. ci.json
-rw-r--r--+ 1 .. development.json
-rw-r--r--+ 1 .. production.json

다음 " " " " 를 실행할 수 .gulp config --env development러음

angular.module("app.config", [])
.constant("foo", "bar")
.constant("ngConstant", true);

또, 다음과 같은 사양이 있습니다.

beforeEach(module('app'));

it('loads the config', inject(function(config) {
  expect(config).toBeTruthy();
}));

그러기 위해서는 AngularJS Environment Plugin을 사용하는 것이 좋습니다.https://www.npmjs.com/package/angular-environment

다음은 예를 제시하겠습니다.

angular.module('yourApp', ['environment']).
config(function(envServiceProvider) {
    // set the domains and variables for each environment 
    envServiceProvider.config({
        domains: {
            development: ['localhost', 'dev.local'],
            production: ['acme.com', 'acme.net', 'acme.org']
            // anotherStage: ['domain1', 'domain2'], 
            // anotherStage: ['domain1', 'domain2'] 
        },
        vars: {
            development: {
                apiUrl: '//localhost/api',
                staticUrl: '//localhost/static'
                // antoherCustomVar: 'lorem', 
                // antoherCustomVar: 'ipsum' 
            },
            production: {
                apiUrl: '//api.acme.com/v2',
                staticUrl: '//static.acme.com'
                // antoherCustomVar: 'lorem', 
                // antoherCustomVar: 'ipsum' 
            }
            // anotherStage: { 
            //  customVar: 'lorem', 
            //  customVar: 'ipsum' 
            // } 
        }
    });

    // run the environment check, so the comprobation is made 
    // before controllers and services are built 
    envServiceProvider.check();
});

다음으로 컨트롤러에서 다음과 같은 변수를 호출할 수 있습니다.

envService.read('apiUrl');

도움이 됐으면 좋겠다.

하면 .lvh.me:9000Angular Angular앱에 , JS , , )lvh.me 하고, 127.0.0.1)을 포인트 하면 합니다.lvh.me★★★★★★★★★★★★★★★★★★:

app.service("Configuration", function() {
  if (window.location.host.match(/lvh\.me/)) {
    return this.API = 'http://localhost\\:7080/myapi/';
  } else {
    return this.API = 'http://localhost\\:8099/hisapi/';
  }
});

하고 를 사용합니다.Configuration.APIAPI:

$resource(Configuration.API + '/endpoint/:id', {
  id: '@id'
});

조금 투박하지만, 조금 다른 상황(API 엔드포인트는 생산과 개발이 다름)에서도 문제없이 작동합니다.

이런 것도 할 수 있어요.

(function(){
    'use strict';

    angular.module('app').service('env', function env() {

        var _environments = {
            local: {
                host: 'localhost:3000',
                config: {
                    apiroot: 'http://localhost:3000'
                }
            },
            dev: {
                host: 'dev.com',
                config: {
                    apiroot: 'http://localhost:3000'
                }
            },
            test: {
                host: 'test.com',
                config: {
                    apiroot: 'http://localhost:3000'
                }
            },
            stage: {
                host: 'stage.com',
                config: {
                apiroot: 'staging'
                }
            },
            prod: {
                host: 'production.com',
                config: {
                    apiroot: 'production'
                }
            }
        },
        _environment;

        return {
            getEnvironment: function(){
                var host = window.location.host;
                if(_environment){
                    return _environment;
                }

                for(var environment in _environments){
                    if(typeof _environments[environment].host && _environments[environment].host == host){
                        _environment = environment;
                        return _environment;
                    }
                }

                return null;
            },
            get: function(property){
                return _environments[this.getEnvironment()].config[property];
            }
        }

    });

})();

당신의 ★★★★★★★★★★★★★★★★★★★★★★★★★★에controller/service의존관계를 주입하고 액세스 속성을 가진 get 메서드를 호출할 수 있습니다.

(function() {
    'use strict';

    angular.module('app').service('apiService', apiService);

    apiService.$inject = ['configurations', '$q', '$http', 'env'];

    function apiService(config, $q, $http, env) {

        var service = {};
        /* **********APIs **************** */
        service.get = function() {
            return $http.get(env.get('apiroot') + '/api/yourservice');
        };

        return service;
    }

})();

$http.get(env.get('apiroot')URL 입니다.

좋은 질문입니다!

하나의 해결책은 config.xml 파일을 계속 사용하여 다음과 같이 백엔드에서 생성된html로 api 엔드포인트 정보를 제공하는 것입니다(예: php).

<script type="text/javascript">
angular.module('YourApp').constant('API_END_POINT', '<?php echo $apiEndPointFromBackend; ?>');
</script>

좋은 해결책은 아닐지 모르지만, 효과가 있을 거야.

다른 은 '있다'는 그대로 입니다.API_END_POINThosts-file의 URL을 지정합니다.

또는 다음과 같은 방법으로localStorage다음과 같이 합니다.

.factory('User',['$resource','API_END_POINT'],function($resource,API_END_POINT){
   var myApi = localStorage.get('myLocalApiOverride');
   return $resource((myApi || API_END_POINT) + 'user');
});

스레드에는 매우 늦은 시점이지만, Angular 이전 기법은 JSON과 JS의 유연성을 활용하여 수집 키를 동적으로 참조하고 JSON 데이터 구조 내에서 특정할 수 없는 사실(호스트 서버 이름, 현재 브라우저 언어 등)을 입력으로 사용하는 것입니다..

이는 단순히 전개 환경 컨텍스트(OP 단위)뿐만 아니라 i18n 또는 기타 필요한 모든 바리에이션을 동시에 제공하기 위한 임의의 컨텍스트(언어 등)를 제공합니다.또한 단일 구성 매니페스트 내에서 (이상적으로는) 중복되지 않고 쉽게 읽을 수 있습니다.

바닐라 JS 약 10줄 이내

지나치게 단순하지만 고전적인 예:JSON 형식의 속성 파일 내의 API 엔드포인트 기반 URL. 호스트 서버도 환경에 따라 다릅니다(natch).

    ...
    'svcs': {
        'VER': '2.3',
        'API@localhost': 'http://localhost:9090/',
        'API@www.uat.productionwebsite.com': 'https://www.uat.productionwebsite.com:9090/res/',
        'API@www.productionwebsite.com': 'https://www.productionwebsite.com:9090/api/res/'
    },
    ...

식별 기능의 열쇠는, 요구내의 서버 호스트명 뿐입니다.

이 키는 사용자의 언어 설정에 따라 추가 키와 조합할 수 있습니다.

    ...
    'app': {
        'NAME': 'Ferry Reservations',
        'NAME@fr': 'Réservations de ferry',
        'NAME@de': 'Fähren Reservierungen'
    },
    ...

식별/프리퍼런스의 범위는 개개의 키(상기와 같이)로 한정할 수 있습니다.여기서 "base" 키는 함수에 대한 입력에 일치하는 키+suffix가 있는 경우에만 덮어쓰며, 구조 자체는 일치하는 식별/프리퍼런스 접미사를 위해 재귀적으로 해석됩니다.

    'help': {
        'BLURB': 'This pre-production environment is not supported. Contact Development Team with questions.',
        'PHONE': '808-867-5309',
        'EMAIL': 'coder.jen@lostnumber.com'
    },
    'help@www.productionwebsite.com': {
        'BLURB': 'Please contact Customer Service Center',
        'BLURB@fr': 'S\'il vous plaît communiquer avec notre Centre de service à la clientèle',
        'BLURB@de': 'Bitte kontaktieren Sie unseren Kundendienst!!1!',
        'PHONE': '1-800-CUS-TOMR',
        'EMAIL': 'customer.service@productionwebsite.com'
    },

따라서 프로덕션 웹 사이트를 방문한 사용자가 독일어(de) 언어 기본 설정을 가지고 있는 경우 위의 구성은 다음과 같이 축소됩니다.

    'help': {
        'BLURB': 'Bitte kontaktieren Sie unseren Kundendienst!!1!',
        'PHONE': '1-800-CUS-TOMR',
        'EMAIL': 'customer.service@productionwebsite.com'
    },

JSON의 마법적인 선호/차별 기능은 어떤 기능일까요?많지 않다:

// prefer(object,suffix|[suffixes]) by/par/durch storsoc
// prefer({ a: 'apple', a@env: 'banana', b: 'carrot' },'env') -> { a: 'banana', b: 'carrot' }
function prefer(o,sufs) {
    for (var key in o) {
        if (!o.hasOwnProperty(key)) continue; // skip non-instance props
        if(key.split('@')[1]) { // suffixed!
            // replace root prop with the suffixed prop if among prefs
            if(o[key] && sufs.indexOf(key.split('@')[1]) > -1) o[key.split('@')[0]] = JSON.parse(JSON.stringify(o[key]));

            // and nuke the suffixed prop to tidy up
            delete o[key];

            // continue with root key ...
            key = key.split('@')[0];
        }

        // ... in case it's a collection itself, recurse it!
        if(o[key] && typeof o[key] === 'object') prefer(o[key],sufs);

    };
};

Angular 웹 사이트와 Pre-Angular 웹 사이트를 포함한 구현에서는 JSON을 prefer() 함수를 포함한 자기실행형 JS 클로저 내에 배치함으로써 Configuration을 다른 리소스 콜보다 훨씬 앞서 부트스트랩하고 호스트 이름과 언어 코드의 기본 속성을 제공합니다(필요한 추가 임의의 서픽스를 받아들입니다).):

(function(prefs){ var props = {
    'svcs': {
        'VER': '2.3',
        'API@localhost': 'http://localhost:9090/',
        'API@www.uat.productionwebsite.com': 'https://www.uat.productionwebsite.com:9090/res/',
        'API@www.productionwebsite.com': 'https://www.productionwebsite.com:9090/api/res/'
    },
    ...
    /* yadda yadda moar JSON und bisque */

    function prefer(o,sufs) {
        // body of prefer function, broken for e.g.
    };

    // convert string and comma-separated-string to array .. and process it
    prefs = [].concat( ( prefs.split ? prefs.split(',') : prefs ) || []);
    prefer(props,prefs);
    window.app_props = JSON.parse(JSON.stringify(props));
})([location.hostname, ((window.navigator.userLanguage || window.navigator.language).split('-')[0])  ] );

Angular 이전 사이트에는 참조할 수 있는 축소된(@ 접미사가 붙은 키가 없음) window.app_props가 있습니다.

Angular 사이트는 부트스트랩/init 스텝으로서 폐기된 소품 객체를 $rootScope에 복사하고 (옵션으로) 글로벌/윈도 범위에서 파기합니다.

app.constant('props',angular.copy(window.app_props || {})).run( function ($rootScope,props) { $rootScope.props = props; delete window.app_props;} );

컨트롤러에 주입됩니다.

app.controller('CtrlApp',function($log,props){ ... } );

또는 뷰의 바인딩에서 참조됩니다.

<span>{{ props.help.blurb }} {{ props.help.email }}</span>

경고?@ 문자는 유효한 JS/JSON 변수/키 이름이 아니지만, 지금까지는 사용할 수 있습니다.이것이 거래 위반이라면, 「__」(이중 밑줄) 등, 마음에 드는 관습으로 대체해 주세요.

이 기술은 서버 측에서 적용할 수 있으며 Java 또는 C#으로 이식할 수 있지만 효율성/컴팩트성은 다를 수 있습니다.

또는 기능/컨벤션도 프런트 엔드 컴파일 스크립트의 일부로 사용할 수 있기 때문에 모든 환경/모든 언어의 JSON이 유선상으로 전송되지 않습니다.

갱신하다

하나의 키에 대해 여러 개의 서픽스를 허용하고 컬렉션을 사용하지 않도록(필요한 만큼 깊게 사용할 수 있음), 선호하는 서픽스의 순서를 따르도록 이 기술을 발전시켰습니다.

예(jsFiddle의 동작도 참조):

var o = { 'a':'apple', 'a@dev':'apple-dev', 'a@fr':'pomme',
          'b':'banana', 'b@fr':'banane', 'b@dev&fr':'banane-dev',
          'c':{ 'o':'c-dot-oh', 'o@fr':'c-point-oh' }, 'c@dev': { 'o':'c-dot-oh-dev', 'o@fr':'c-point-oh-dev' } };

/*1*/ prefer(o,'dev');        // { a:'apple-dev', b:'banana',     c:{o:'c-dot-oh-dev'}   }
/*2*/ prefer(o,'fr');         // { a:'pomme',     b:'banane',     c:{o:'c-point-oh'}     }
/*3*/ prefer(o,'dev,fr');     // { a:'apple-dev', b:'banane-dev', c:{o:'c-point-oh-dev'} }
/*4*/ prefer(o,['fr','dev']); // { a:'pomme',     b:'banane-dev', c:{o:'c-point-oh-dev'} }
/*5*/ prefer(o);              // { a:'apple',     b:'banana',     c:{o:'c-dot-oh'}       }

1/2(기본 사용법)는 '@dev' 키를 선호하며 다른 접미사가 붙은 키는 모두 폐기합니다.

3은 '@fr'보다 '@dev'를 선호하며, 다른 모든 것보다 '@dev&fr'을 선호합니다.

4(3과 동일하지만 '@dev'보다 '@fr'을 선호)

5 기본 접미사가 없고 접미사가 붙은 속성을 모두 삭제합니다.

속성을 반복하고 점수가 높은 접미사를 찾을 때 각 접미사의 점수를 매기고 접미사의 값을 접미사가 없는 속성으로 승격하여 이 작업을 수행합니다.

JSON에 대한 딥 복사 의존을 없애고 스코어링 라운드에서 살아남은 개체에만 재귀하는 등 이 버전에서는 다음과 같은 효율성이 있습니다.

function prefer(obj,suf) {
    function pr(o,s) {
        for (var p in o) {
            if (!o.hasOwnProperty(p) || !p.split('@')[1] || p.split('@@')[1] ) continue; // ignore: proto-prop OR not-suffixed OR temp prop score
            var b = p.split('@')[0]; // base prop name
            if(!!!o['@@'+b]) o['@@'+b] = 0; // +score placeholder
            var ps = p.split('@')[1].split('&'); // array of property suffixes
            var sc = 0; var v = 0; // reset (running)score and value
            while(ps.length) {
                // suffix value: index(of found suffix in prefs)^10
                v = Math.floor(Math.pow(10,s.indexOf(ps.pop())));
                if(!v) { sc = 0; break; } // found suf NOT in prefs, zero score (delete later)
                sc += v;
            }
            if(sc > o['@@'+b]) { o['@@'+b] = sc; o[b] = o[p]; } // hi-score! promote to base prop
            delete o[p];
        }
        for (var p in o) if(p.split('@@')[1]) delete o[p]; // remove scores
        for (var p in o) if(typeof o[p] === 'object') pr(o[p],s); // recurse surviving objs
    }
    if( typeof obj !== 'object' ) return; // validate
    suf = ( (suf || suf === 0 ) && ( suf.length || suf === parseFloat(suf) ) ? suf.toString().split(',') : []); // array|string|number|comma-separated-string -> array-of-strings
    pr(obj,suf.reverse());
}

Brunch를 사용하는 경우 Constangular 플러그인을 사용하여 다양한 환경의 변수를 관리할 수 있습니다.

질문과 답을 보셨나요?

앱에 대해 다음과 같이 글로벌하게 유효한 값을 설정할 수 있습니다.

app.value('key', 'value');

그리고 그것을 당신의 서비스에 사용할 수 있습니다.이 코드를 config.js 파일로 이동하여 페이지 로드 시 또는 다른 편리한 시간에 실행할 수 있습니다.

언급URL : https://stackoverflow.com/questions/16339595/how-do-i-configure-different-environments-in-angular-js