공통 변수를 Node.js의 개별 모듈에 전달하는 가장 좋은 방법은 무엇입니까?
메인 앱과 인증 앱의 모듈로 별도의 라우터 파일을 사용합니다. 라우터에 변수 (db 클라이언트)를 전달하는 가장 좋은 방법을 찾을 수 없습니다. 하드 코딩하거나 다음과 같이 전달하고 싶지 않습니다.
module.exports = function(app, db) {
싱글 톤 레지스터를 사용하거나 전역 DB 변수를 사용하는 것이 가장 좋은 방법일까요?
디자인 패턴에 대한 경험은 무엇입니까? 어떤 방법이 가장 좋으며 그 이유는 무엇입니까?
나는 의존성 주입을 사용하여 물건을 전달하고 최고의 스타일임을 발견했습니다. 실제로 다음과 같이 보일 것입니다.
// App.js
module.exports = function App() {
};
// Database.js
module.exports = function Database(configuration) {
};
// Routes.js
module.exports = function Routes(app, database) {
};
// server.js: composition root
var App = require("./App");
var Database = require("./Database");
var Routes = require("./Routes");
var dbConfig = require("./dbconfig.json");
var app = new App();
var database = new Database(dbConfig);
var routes = new Routes(app, database);
// Use routes.
다음과 같은 여러 가지 이점이 있습니다.
- 대신 그들은 전화 파일의 중간 어딘가에 종속 관계를 숨기는, 명확한 종속성이있는 구성 요소로 시스템을 분리하는 당신을 강제로
require("databaseSingleton")
, 또는 더 나쁜global.database
. - 단위 테스트를 매우 쉽게 만듭니다.
Routes
격리 된 상태 로 테스트하려면 가짜app
와database
매개 변수를 삽입 하고Routes
코드 자체 만 테스트 할 수 있습니다. - 모든 객체-그래프 연결을 단일 위치, 즉 컴포지션 루트 (이 경우
server.js
에는 앱 진입 점)에 모 읍니다. 이를 통해 시스템에서 모든 것이 어떻게 조화를 이루는 지 확인할 수 있습니다.
이것에 대한 더 나은 설명 중 하나는 뛰어난 책 Dependency Injection in .NET의 저자 인 Mark Seeman과의 인터뷰입니다 . JavaScript, 특히 Node.js에도 많이 적용됩니다 . 모듈 시스템 대신 클래식 서비스 로케이터로 자주 사용됩니다.require
db 인스턴스와 'singleton'과 같이 전역 적으로 사용해야하는 다른 것들로 설정 파일을 만드는 것이 좋습니다.
예를 들어 redis db 클라이언트에 settings.js가 있습니다.
var redis = require('redis');
exports.redis = redis.createClient(6379, '127.0.0.1');
그리고 다른 여러 모듈에 다음을 포함합니다.
var settings = require('./settings');
setting.redis.<...>
그것을 포함하여 여러 번 나는 항상 하나의 db 연결 인스턴스를 가지고 있습니다.
의존성 주입 프레임 워크를 사용하면 모듈을 연결하는 모든 표준 코드를 저장할 수 있습니다.
이 답변 은 그중 몇 가지를 나열합니다. 여기에 더 간단한 DI 프레임 워크 도 구축했습니다 .
편집 : 아래는 페이지가 변경되는 경우 답변 양식의 사본입니다.
require
이다 Node.js를 종속성을 관리하는 방법을 확실하게 그것은 직관적이고 효과적이지만, 그것은 또한 한계가있다.
My advice is to take a look at some of the Dependency Injection containers available today for Node.js to have an idea on what are their pros/cons. Some of them are:
Just to name a few.
Now the real question is, what can you achieve with a Node.js DI container, compared to a simple require
?
Pros:
- better testability: modules accepts their dependencies as input
- Inversion of Control: decide how to wire your modules without touching the main code of your application.
- a customizable algorithm for resolving modules: dependencies have "virtual" identifiers, usually they are not bound to a path on the filesystem.
- Better extensibility: enabled by IoC and "virtual" identifiers.
- Other fancy stuff possible:
- Async initialization
- Module lifecycle management
- Extensibility of the DI container itself
- Can easily implement higher level abstractions (e.g. AOP)
Cons:
- Different from the Node.js "experience": not using
require
definitely feels like you are deviating from the Node way of thinking. - The relationship between a dependency and its implementation is not always explicit. A dependency may be resolved at runtime and influenced by various parameters. The code becomes more difficult to understand and debug
- Slower startup time
- Maturity (at the moment): none of the current solutions is really popular at the moment, so not so many tutorials, no ecosystem, not battle tested.
- Some DI containers will not play well with module bundlers like Browserify and Webpack.
It is completely outdated, but you can use global
in a script :
global.foo = new Foo();
in another script :
foo.bar();
You can also use already existing constant :
Object.foo = new Foo();
And here :
Object.foo.bar();
'programing tip' 카테고리의 다른 글
목록 / 세부 정보보기 및 페이지 매김이있는 앱의 Redux 상태 모양을 선택하는 방법은 무엇입니까? (0) | 2020.12.09 |
---|---|
C ++ 11 foreach 구문 및 사용자 지정 반복기 (0) | 2020.12.08 |
composer.lock : 어떻게 작동합니까? (0) | 2020.12.08 |
jquery 눈에 거슬리지 않는 유효성 검사 속성 참조? (0) | 2020.12.08 |
새로운 Google Now 및 Google+ 카드 인터페이스 (0) | 2020.12.08 |