IT박스

브라우저 내 자바 스크립트에 노드 스타일이 필요합니까?

itboxs 2020. 10. 25. 11:49
반응형

브라우저 내 자바 스크립트에 노드 스타일이 필요합니까?


Node와 동일한 유연성 / 모듈성 / 사용 편의성을 제공하는 브라우저 내 자바 스크립트 용 라이브러리가 require있습니까?

더 자세한 정보를 제공하기 위해 : 그 이유 require다음과 같습니다.

  1. 다른 위치에서 코드를 동적으로로드 할 수 있습니다 (HTML에서 모든 코드를 링크하는 것보다 스타일이 더 좋습니다).
  2. 모듈 구축을위한 일관된 인터페이스를 제공합니다.
  3. 모듈이 다른 모듈에 의존하기 쉽습니다 (예를 들어 jQuery가 필요한 API를 작성할 수 있으므로 jQuery.ajax()
  4. 로드 된 자바 스크립트는 범위지정되어 있습니다 . 즉,로드 var dsp = require("dsp.js");할 수 있고 액세스 할 수 있습니다 dsp.FFT. 이는 내 로컬을 방해하지 않습니다.var FFT

이를 효과적으로 수행하는 도서관을 아직 찾지 못했습니다. 내가 사용하는 해결 방법은 다음과 같습니다.

  • coffeescript-concat- 다른 js를 요구하는 것은 쉽지만 컴파일해야합니다. 즉, 빠른 개발에는 적합하지 않습니다 (예 : 테스트 중 API 빌드).

  • RequireJS- 인기 있고 간단하며 1-3을 해결하지만 범위 지정이 없다는 것은 실제 거래를 방해하는 요소 입니다 (나는 head.js 가 범위 지정이 없다는 점에서 비슷 하다고 생각 합니다.하지만 사용할 기회가 없었습니다. 마찬가지로 LABjs.wait()종속성 문제를 로드하고 수정 하지만 여전히 범위를 지정하지 않습니다.)

내가 알 수있는 한, 자바 스크립트의 동적 및 / 또는 비동기 로딩에 대한 많은 솔루션이있는 것처럼 보이지만 HTML에서 js를로드하는 것과 동일한 범위 지정 문제가있는 경향이 있습니다. 무엇보다도 전역 네임 스페이스를 전혀 오염시키지 않지만 여전히 라이브러리를로드하고 사용할 수 있도록하는 자바 스크립트를로드하는 방법을 원합니다 (노드의 요구 사항과 동일).

편집 (내 답변) : 이 글을 작성한 이후로 RequireJS를 광범위하게 사용 했습니다 (이제 훨씬 더 명확한 문서가 있음). RequireJS는 제 생각에 정말 올바른 선택이었습니다. 저처럼 혼란스러워하는 사람들을 위해 시스템이 어떻게 작동하는지 명확히하고 싶습니다.

require일상적인 개발에 사용하실 수 있습니다 . 모듈은 함수 (일반적으로 개체 또는 함수)에서 반환하는 모든 것이 될 수 있으며 매개 변수로 범위가 지정됩니다. 다음을 사용하여 배포를 위해 프로젝트를 단일 파일로 컴파일 할 수도 있습니다 r.js(실제로는 require스크립트를 병렬로로드 할 수 있더라도 거의 항상 빠릅니다 ).

RequireJS와 node-style require like browserify (tjameson이 제안한 멋진 프로젝트) 사용의 주요 차이점은 모듈이 설계되고 요구되는 방식입니다.

  • RequireJS는 AMD (Async Module Definition)를 사용합니다. AMD에서는 require로드 할 모듈 (자바 스크립트 파일) 목록과 콜백 함수를받습니다. 각 모듈을로드하면 각 모듈을 콜백에 대한 매개 변수로 사용하여 콜백을 호출합니다. 따라서 진정한 비동기식이므로 웹에 적합합니다.
  • Node는 CommonJS를 사용합니다. CommonJS에서 require모듈을로드하고이를 객체로 반환하는 차단 호출입니다. 파일이 파일 시스템에서 읽히기 때문에 노드에서는 잘 작동합니다. 파일 시스템은 충분히 빠르지 만 파일을 동기식으로로드하는 데 훨씬 오래 걸릴 수 있기 때문에 웹에서는 제대로 작동하지 않습니다.

실제로 많은 개발자가 AMD를보기 전에 Node (및 CommonJS)를 사용했습니다. 또한 많은 라이브러리 / 모듈이 exportsAMD ( define함수 에서 모듈 반환)가 아닌 CommonJS ( 객체 에 항목 추가) 용으로 작성됩니다 . 따라서 많은 Node-turned 웹 개발자가 웹에서 CommonJS 라이브러리를 사용하기를 원합니다. <script>태그 에서로드하는 것이 차단 되기 때문에 가능합니다 . browserify와 같은 솔루션은 CommonJS (노드) 모듈을 가져 와서이를 래핑하여 스크립트 태그에 포함시킬 수 있습니다.

따라서 웹용 다중 파일 프로젝트를 개발하는 경우 RequireJS가 진정 웹용 모듈 시스템이기 때문에 강력히 권장합니다 (공정한 공개에서 AMD는 CommonJS보다 훨씬 더 자연 스럽습니다). 최근에는 RequireJS가 기본적으로 CommonJS 구문을 사용할 수 있기 때문에 구별이 덜 중요해졌습니다. 또한 RequireJS를 사용하여 Node에서 AMD 모듈을로드 할 수 있습니다 (하지만 node-amd-loader 선호 함 ).


엔더를 확인하십시오 . 많은 일을합니다.

또한 browserify 는 꽤 좋습니다. 나는 require-kiss 를 사용했고 작동합니다. 아마 다른 것들이있을 것입니다.

RequireJS에 대해 잘 모르겠습니다. 노드와 동일하지 않습니다. 다른 위치에서로드하는 데 문제가 발생할 수 있지만 작동 할 수 있습니다. 제공 메소드 또는 호출 할 수있는 것이있는 한.

TL; DR- 저는 browserify 또는 require-kiss를 권장합니다.

최신 정보:

require-kiss는 이제 죽었고 저자는 그것을 제거했습니다. 나는 그 이후로 RequireJS를 문제없이 사용하고 있습니다. require-kiss의 저자는 pakmanagerpakman을 작성 했습니다 . 전체 공개, 저는 개발자와 협력합니다.

개인적으로 RequireJS가 더 좋습니다. 디버그하기가 훨씬 쉽고 (개발 중에 별도의 파일이 있고 프로덕션에 배포 된 단일 파일이있을 수 있음) 견고한 "표준"을 기반으로 구축되었습니다.


저는 자바 스크립트 파일의 비동기 및 동기 로딩을 허용하는 작은 스크립트를 작성했습니다. 종속성이 없으며 Node.js 및 CommonJS와 호환됩니다. 프로덕션 서버에서 HTTP 요청을 줄이기 위해 여러 모듈을 하나의 파일로 묶을 수도 있습니다. 사용법은 매우 쉽습니다.

<script type="text/javascript" src="require.js"></script>
<script type="text/javascript">
    var ModuleA = require('modulea') // Sync loading of a script in the module directory
    ModuleA.funcA();

    require('./path/moduleb.js', callbackB); // Async loading of a script anywhere else
    function callbackB(ModuleB) {
        ModuleB.funcB();
    }
</script>

자세한 내용과 코드는 내 블로그에서 찾을 수 있습니다. http://pixelsvsbytes.com/2013/02/js-require-for-browsers-better-faster-stronger/ 코드는 GitHub에도 있습니다 : https : // github .com / letorbi / tarp.require


Ilya Kharlamov 의 변형 , 크롬 개발자 도구와 잘 어울리는 코드가 있습니다.

//
///- REQUIRE FN
// equivalent to require from node.js
function require(url){
    if (url.toLowerCase().substr(-3)!=='.js') url+='.js'; // to allow loading without js suffix;
    if (!require.cache) require.cache=[]; //init cache
    var exports=require.cache[url]; //get from cache
    if (!exports) { //not cached
            try {
                exports={};
                var X=new XMLHttpRequest();
                X.open("GET", url, 0); // sync
                X.send();
                if (X.status && X.status !== 200)  throw new Error(X.statusText);
                var source = X.responseText;
                // fix (if saved form for Chrome Dev Tools)
                if (source.substr(0,10)==="(function("){ 
                    var moduleStart = source.indexOf('{');
                    var moduleEnd = source.lastIndexOf('})');
                    var CDTcomment = source.indexOf('//@ ');
                    if (CDTcomment>-1 && CDTcomment<moduleStart+6) moduleStart = source.indexOf('\n',CDTcomment);
                    source = source.slice(moduleStart+1,moduleEnd-1); 
                } 
                // fix, add comment to show source on Chrome Dev Tools
                source="//@ sourceURL="+window.location.origin+url+"\n" + source;
                //------
                var module = { id: url, uri: url, exports:exports }; //according to node.js modules 
                var anonFn = new Function("require", "exports", "module", source); //create a Fn with module code, and 3 params: require, exports & module
                anonFn(require, exports, module); // call the Fn, Execute the module
                require.cache[url]  = exports = module.exports; //cache obj exported by module
            } catch (err) {
                throw new Error("Error loading module "+url+": "+err);
            }
    }
    return exports; //require returns object exported by module
}
///- END REQUIRE FN

(function () {
    // c is cache, the rest are the constants
    var c = {},s="status",t="Text",e="exports",E="Error",r="require",m="module",S=" ",w=window;
    w[r]=function R(url) {
        url+=/.js$/i.test(url) ? "" : ".js";// to allow loading without js suffix;
        var X=new XMLHttpRequest(),module = { id: url, uri: url }; //according to the modules 1.1 standard
        if (!c[url])
            try {
                X.open("GET", url, 0); // sync
                X.send();
                if (X[s] && X[s] != 200) 
                    throw X[s+t];
                Function(r, e, m, X['response'+t])(R, c[url]={}, module); // Execute the module
                module[e] && (c[url]=module[e]);
            } catch (x) {
                throw w[E](E+" in "+r+": Can't load "+m+S+url+":"+S+x);
            }
        return c[url];
    }
})();

차단으로 인해 생산에 사용하지 않는 것이 좋습니다. (node.js에서 require ()는 블로킹 호출이 좋습니다).


Webmake bundles Node-style modules to Browser, give it a try.


Require-stub — provides node-compliant require in browser, resolves both modules and relative paths. Uses technic similar to TKRequire (XMLHttpRequest). Resulting code is fully browserifyable, in that require-stub can serve as a replacement for watchify.


Here is an extension to Lucio M. Tato's fantastic answer that allows for recursive loading of modules with relative paths.

Here is a github project to house the solution and an example of how to use it:

https://github.com/trausti/TKRequire.js

To use TKRequire.js, include the following line in your header

<script type="text/javascript" src="./TKRequire.js"></script>

Then load modules just like in node.js:

var MyModule = require("./relative/path/to/MyModule.js");

참고URL : https://stackoverflow.com/questions/6971583/node-style-require-for-in-browser-javascript

반응형