[javascript] shim 구성을 사용하는 이유와시기

여기 API 에서 requirejs 문서를 읽었습니다.

requirejs.config({
    shim: {
        'backbone': {
            //These script dependencies should be loaded before loading
            //backbone.js
            deps: ['underscore', 'jquery'],
            //Once loaded, use the global 'Backbone' as the
            //module value.
            exports: 'Backbone'
        },
        'underscore': {
            exports: '_'
        },
        'foo': {
            deps: ['bar'],
            exports: 'Foo',
            init: function (bar) {
                //Using a function allows you to call noConflict for
                //libraries that support it, and do other cleanup.
                //However, plugins for those libraries may still want
                //a global. "this" for the function will be the global
                //object. The dependencies will be passed in as
                //function arguments. If this function returns a value,
                //then that value is used as the module export value
                //instead of the object found via the 'exports' string.
                return this.Foo.noConflict();
            }
        }
    }
});

그러나 나는 그것의 부분을 얻지 못하고 있습니다. shim을 사용해야하는 이유와 구성 방법에 대한 설명이 더 필요합니다.

우리가 shim을 사용해야하는 이유와시기를 예를 들어 설명해주십시오. 감사.



답변

shim의 주된 용도는 AMD를 지원하지 않는 라이브러리에 있지만 종속성을 관리해야합니다. 예를 들어 위의 Backbone 및 Underscore 예제에서 Backbone에 Underscore가 필요하다는 것을 알고 있으므로 다음과 같이 코드를 작성했다고 가정합니다.

require(['underscore', 'backbone']
, function( Underscore, Backbone ) {

    // do something with Backbone

}

RequireJS는 Underscore와 Backbone 모두에 대한 비동기 요청을 시작하지만 어떤 것이 먼저 돌아올 지 모르기 때문에 Backbone이로드되기 전에 Underscore로 무언가를 시도 할 수 있습니다.

참고 : 이 밑줄 / 백본 예제는 두 라이브러리가 AMD를 지원하기 전에 작성되었습니다. 그러나 원칙은 오늘날 AMD를 지원하지 않는 모든 라이브러리에 적용됩니다.

“init”훅을 사용하면 다른 고급 작업을 수행 할 수 있습니다. 예를 들어 라이브러리가 일반적으로 두 가지 다른 항목을 전역 네임 스페이스로 내보내지만 단일 네임 스페이스에서 재정의하려는 경우입니다. 또는로드중인 라이브러리의 메서드에 대해 원숭이 패치를 수행하고 싶을 수도 있습니다.

더 많은 배경 :


답변

RequireJS API 문서에 따라 shim을 사용하면

종속성을 선언하고 모듈 값을 설정하기 위해 define ()을 사용하지 않는 기존의 기존 “브라우저 전역”스크립트에 대한 종속성, 내보내기 및 사용자 정의 초기화를 구성하십시오.

-종속성 구성

2 개의 자바 스크립트 모듈 (moduleA 및 moduleB)이 있고 그중 하나 (moduleA)가 다른 하나 (moduleB)에 의존한다고 가정 해 보겠습니다. 둘 다 자신의 모듈에 필요하므로 require () 또는 define ()에 종속성을 지정하십시오.

require(['moduleA','moduleB'],function(A,B ) {
    ...
}

그러나 자체적으로 AMD를 따르도록 요구하기 때문에 어느 것이 조기에 가져올 지 알 수 없습니다. 이것은 심이 구출하는 곳입니다.

require.config({
    shim:{
       moduleA:{
         deps:['moduleB']
        }
    }

})

이렇게하면 moduleA가로드되기 전에 항상 moduleB를 가져옵니다.

-내보내기 구성

Shim 내보내기는 RequireJS에게 전역 개체 (물론 브라우저에 있다고 가정하는 창)의 구성원이 실제 모듈 값인지 알려줍니다. moduleA가 자신을 window‘modA'(jQuery와 underscore가 각각 $ 및 _ 로하는 것처럼)에 추가 하고 내보내기 값을 ‘modA’로 만듭니다.

require.config({
    shim:{
       moduleA:{
         exports:'modA'
        }
    }

RequireJS에이 모듈에 대한 로컬 참조를 제공합니다. 글로벌 modA는 페이지에도 여전히 존재합니다.

-이전 “브라우저 전역”스크립트에 대한 사용자 정의 초기화

이것은 아마도 우리 자신의 모듈에서 종속성으로 ‘브라우저 전역’, ‘비 AMD’스크립트 (모듈 패턴을 따르지 않음)를 추가 할 수있는 shim 구성의 가장 중요한 기능 일 것입니다.

moduleB가 funcA () 및 funcB () 함수 두 개만있는 평범한 오래된 자바 스크립트라고 가정 해 보겠습니다.

function funcA(){
    console.log("this is function A")
}
function funcB(){
    console.log("this is function B")
}

이 두 함수는 모두 창 범위에서 사용할 수 있지만 RequireJS는 혼란을 피하기 위해 전역 식별자 / 핸들을 통해 사용할 것을 권장합니다. 따라서 심을 다음과 같이 구성하십시오.

shim: {
    moduleB: {
        deps: ["jquery"],
        exports: "funcB",
        init: function () {
            return {
                funcA: funcA,
                funcB: funcB
            };
        }
    }
}

init 함수의 반환 값은 ‘exports’문자열을 통해 찾은 객체 대신 모듈 내보내기 값으로 사용됩니다. 이렇게하면 자체 모듈에서 funcB를 다음과 같이 사용할 수 있습니다.

require(["moduleA","moduleB"], function(A, B){
    B.funcB()
})

이것이 도움이 되었기를 바랍니다.


답변

선언하려면 requirejs.config에 경로를 추가해야합니다. 예 :

requirejs.config({
    paths: {
          'underscore' : '.../example/XX.js' // your JavaScript file
          'jquery' : '.../example/jquery.js' // your JavaScript file
    }
    shim: {
        'backbone': {
            deps: ['underscore', 'jquery'],
            exports: 'Backbone'
        },
        'underscore': {
            exports: '_'
        },
        'foo': {
            deps: ['bar'],
            exports: 'Foo',
            init: function (bar) {
                return this.Foo.noConflict();
            }
        }
    }
});


답변