예제가 포함 된 JavaScript 모듈 패턴 [닫힘]


136

두 개 이상의 서로 다른 모듈이 함께 작동하는 방법을 보여주는 액세스 가능한 예제를 찾을 수 없습니다.

그래서 모듈이 함께 작동하는 방법을 설명하는 예제를 작성할 사람이 있는지 물어보고 싶습니다.


지난 4 년 동안이 모든 것이 바뀌었지만 열성적인 지나친 조정 덕분에이 오래된 정보는 영원히 사라질 것 입니다. ES6 모듈에 대한 MDN 페이지 는 다음과 같습니다 .
bbsimonbb

답변:


256

모듈 식 디자인 패턴에 접근하려면 먼저 다음 개념을 이해해야합니다.

즉시 호출 된 함수 표현식 (IIFE) :

(function() {
      // Your code goes here 
}());

기능을 사용할 수있는 두 가지 방법이 있습니다. 1. 함수 선언 2. 함수 표현.

함수 표현식을 사용하고 있습니다.

네임 스페이스 란 무엇입니까? 위의 코드에 네임 스페이스를 추가하면

var anoyn = (function() {
}());

JS의 폐쇄 란 무엇입니까?

변수 범위가있는 함수를 다른 함수 내부에 선언하면 (다른 함수 내에서 함수를 선언 할 수 있습니다!) 항상 함수 범위를 계산합니다. 즉, 외부 함수의 변수는 항상 읽습니다. 같은 이름의 전역 변수 (있는 경우)를 읽지 않습니다. 이것은 또한 이름 충돌을 피하는 모듈 식 디자인 패턴을 사용하는 목표 중 하나입니다.

var scope = "I am global";
function whatismyscope() {
    var scope = "I am just a local";
    function func() {return scope;}
    return func;
}
whatismyscope()()

이제 위에서 언급 한 세 가지 개념을 적용하여 첫 번째 모듈 식 디자인 패턴을 정의하겠습니다.

var modularpattern = (function() {
    // your module code goes here
    var sum = 0 ;

    return {
        add:function() {
            sum = sum + 1;
            return sum;
        },
        reset:function() {
            return sum = 0;    
        }  
    }   
}());
alert(modularpattern.add());    // alerts: 1
alert(modularpattern.add());    // alerts: 2
alert(modularpattern.reset());  // alerts: 0

위의 코드에 대한 jsfiddle.

목표는 외부 세계에서 변수 접근성을 숨기는 것입니다.

도움이 되었기를 바랍니다. 행운을 빕니다.


iife의 이름을 지정하는 것이 더 좋을까요? 의미 적 목적과 더 나은 스택 추적을 위해? 코드에서 아무것도 변경됩니까?
Jeroen

2
첫 번째 예는 (function() { /* Your code goes here */}());당신도 그에게 IIAFE (즉시 호출하기 익명 기능 식)를 호출에 인생에 더 참조 할 수 있도록이 이름이없는 사촌 실제로 (즉시 기능 식 호출)는 인생이다, 확인은 익명의 stackoverflow.com/questions/ 2421911 /…
Adrien 수

왜 return 문이 사용 되었습니까? return {}을 생략하면 add 및 reset 함수가 공개되고 로컬 변수 sum에 액세스 할 수 있다고 생각합니까? 내가 맞아?
Mou

두 번째 예제는 객체처럼 보이거나 내가 옳지 않습니까?
초에 이유

4
이것은 OP의 질문을 다루지 않습니다. OP가 원하는대로 여러 모듈이 함께 작동하는 방법의 예가 아니라 모듈 패턴에 대한 설명입니다.
Erik Trautman

39

Addy Osmani의 무료 서적을 읽으려면이 주제를 입력하는 모든 사람을 추천합니다.

"자바 스크립트 디자인 패턴 배우기".

http://addyosmani.com/resources/essentialjsdesignpatterns/book/

이 책은 유지 관리가 쉬운 JavaScript를 작성하기 시작했을 때 엄청나게 도움이되었지만 여전히 참조로 사용합니다. 그의 다른 모듈 패턴 구현을 살펴보면 실제로 잘 설명합니다.


또한 Addy Osmani의 책에서 다루지 않은 "Definitive Module Pattern"에 대한 기사를 읽는 것이 좋습니다. github.com/tfmontague/definitive-module-pattern
tfmontague

1
어떻게 이런 일이의 Stoyan 스테파노으로 "자바 스크립트 패턴"에 비교하면
JohnMerlino

4
스토얀의 책은 훨씬 더 포괄적입니다. 높은 수준의 패턴뿐만 아니라 다른 JS 모범 사례에 대해 더 깊이 이야기합니다.
코드 11

1
"학습 자바 스크립트 디자인 패턴"의 리뷰 amazon.com/product-reviews/1449331815
아드 리앙은 수

3
의 Stoyan 스테파노에 의한 "자바 스크립트 패턴"의 리뷰 amazon.com/product-reviews/0596806752 . 참고 : "Learning JavaScript Design Patterns"의 것보다 훨씬 나아 보입니다
Adrien Be

19

모듈에 응용 프로그램을 어떻게 맞추는 지에 대해 이야기하면서 위의 대답을 확장한다고 생각했습니다. 나는 더그 크록 포드 책에서 이것에 대해 읽었지만 자바 스크립트에 익숙하지 않은 것은 여전히 ​​조금 신비했습니다.

나는 AC # 배경에서 왔으므로 거기에서 유용한 용어를 추가했습니다.

HTML

당신은 일종의 최상위 html 파일을 가질 것입니다. 이것을 프로젝트 파일로 생각하면 도움이됩니다. 프로젝트에 추가하는 모든 자바 스크립트 파일은이 작업을 수행하려고하지만 불행히도이 도구에 대한 지원을받지 못합니다 (IDEA를 사용하고 있습니다).

다음과 같은 스크립트 태그를 사용하여 프로젝트에 파일을 추가해야합니다.

        <script type="text/javascript" src="app/native/MasterFile.js" /></script>
        <script type="text/javascript" src="app/native/SomeComponent.js" /></script>

태그가 무너지면 문제가 발생합니다. xml처럼 보이지만 실제로는 더 까다로운 규칙이 있습니다!

네임 스페이스 파일

MasterFile.js

myAppNamespace = {};

그게 다야. 이것은 우리 코드의 나머지 부분에 하나의 전역 변수를 추가하기위한 것입니다. 중첩 된 네임 스페이스를 여기 (또는 자체 파일)로 선언 할 수도 있습니다.

모듈

SomeComponent.js

myAppNamespace.messageCounter= (function(){

    var privateState = 0;

    var incrementCount = function () {
        privateState += 1;
    };

    return function (message) {
        incrementCount();
        //TODO something with the message! 
    }
})();

우리가 여기서하는 일은 애플리케이션의 변수에 메시지 카운터 기능을 할당하는 것입니다. 바로 실행 하는 함수를 반환하는 함수입니다 .

개념

SomeComponent의 최상위 라인을 무언가를 선언하는 네임 스페이스로 생각하는 것이 도움이된다고 생각합니다. 이것에 대한 유일한주의 사항은 모든 네임 스페이스가 다른 파일에 먼저 나타나야한다는 것입니다. 응용 프로그램 변수에 의해 근본이 된 객체 일뿐입니다.

난 단지 순간 (내가 그것을 테스트 할 수 있도록 extjs라는 응용 프로그램 중 일부 일반 자바 스크립트를 리팩토링있어)에서이 사소한의 조치를 취했지만 그것은 당신의 수렁 피하면서 작은 기능 단위를 정의 할 수있는 아주 좋은 것 '이 ' .

이 스타일을 사용하여 함수 컬렉션이있는 객체를 반환하는 함수를 반환하고 즉시 호출하지 않으면 생성자를 정의 할 수 있습니다.


6

여기 https://toddmotto.com/mastering-the-module-pattern 당신은 철저하게 설명 된 패턴을 찾을 수 있습니다. 모듈 식 JavaScript의 두 번째 사항은 코드를 여러 파일로 구성하는 방법입니다. 많은 사람들이 AMD와 함께 가라고 조언 할 수도 있지만, 많은 HTTP 요청으로 인해 느린 페이지 응답으로 어느 시점에 끝날 것이라고 경험에서 말할 수 있습니다. 해결 방법은 JavaScript 모듈 (파일 당 하나씩)을 CommonJS 표준에 따라 단일 파일로 사전 컴파일하는 것입니다. 여기에 샘플을보십시오 http://dsheiko.github.io/cjsc/


모든 AMD 구현은 단일 파일로 사전 컴파일을 제공합니다.
I-Lin Kuo

1
맞습니다. 그러나 결과 최적화 된 파일에는 로더 라이브러리가 필요합니다 (r.js v2.1.14로 다시 확인). 코드를 컴파일하자마자 비동기식으로로드 된 종속성을 해결할 필요가 없으므로이 라이브러리가 필요하지 않습니다. 우리는 모듈을 AMD로 포장합니다. 그것은 비동기를 의미합니다. 로드 한 다음 단일 파일로 컴파일 (더 이상 별도로드하지 않음)하지만 전체 라이브러리를로드하여 해당 파일을 처리합니다 (현재 중복되는 항목). 그것은 나에게 최적의 방법으로 들리지 않습니다. 비동기 적으로로드하지 않을 때 AMD가 전혀 필요하지 않은 이유는 무엇입니까?
Dmitry Sheiko

almond.js는 RequireJS보다 완성 된 프로덕션 코드에 더 작은 중량 로더를 제공하지만, 비교적 단일 한 HTTP 요청을 만들지 않는 것의 성능 이점은 로더 코드를 모듈에 추가하는 비용을 능가하므로 최적이 아니지만 덜 최적화됩니다. 훨씬 작은 규모로. 내 생각에 문제는 바뀌어야합니다. 브라우저가 없을 때 왜 동기 성을 가정합니까? 필자는 실제로 RequireJS와 CommonJS 모두 약속 구현이 내장되어야한다고 생각합니다.
I-Lin Kuo

두 형식 모두 CommonJS Modules / 2.0에 대한 유효한 경로이며 동일한 확장 성을 제공합니다. 나에 관해서는-CJS 모듈 / 1.1 (CommonJS가 의미하는 바)을 다루는 것이 훨씬 쉽습니다. 코드가 깨끗 해 보입니다.
Dmitry Sheiko

다음과 같은 AMD의 이점을 충족했습니다. * JavaScript 파일 이상을로드 할 수 있습니다. * 경로 별명; CommonJS Compiler는 이러한 문제를 해결합니다. JavaScipt / JSON 이외의 종속성을 데이터로로드하고 빌드 구성 (별명 포함)을 제공 할 수 있습니다. 건물이 필요하다는 유일한 단점. 그러나 오늘날 모든 사람들은 CSS 프리 프로세서를위한 프로젝트를 구축하고 있습니다. 그래서 그것은 Grunt / Gulp에 대한 추가 작업을 추가하는 것에 관한 것입니다.
Dmitry Sheiko

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.