Node와 동일한 유연성 / 모듈성 / 사용 편의성을 제공하는 브라우저 내 자바 스크립트 용 라이브러리가 require
있습니까?
더 자세한 정보를 제공하기 위해 : 그 이유 require
는 다음과 같습니다.
- 다른 위치에서 코드를 동적으로로드 할 수 있습니다 (HTML에서 모든 코드를 연결하는 것보다 스타일이 더 좋습니다).
- 모듈 구축을위한 일관된 인터페이스를 제공합니다.
- 모듈이 다른 모듈에 의존하기 쉽습니다 (예를 들어 jQuery가 필요한 API를 작성할 수 있으므로
jQuery.ajax()
- 로드 된 자바 스크립트는 범위 가 지정되어 있습니다 . 즉,로드
var dsp = require("dsp.js");
할 수 있고 액세스 할 수 있습니다dsp.FFT
. 이는 내 로컬을 방해하지 않습니다.var FFT
이를 효과적으로 수행하는 도서관을 아직 찾지 못했습니다. 내가 사용하는 해결 방법은 다음과 같습니다.
-
coffeescript-concat- 다른 js를 요구하는 것은 쉽지만 컴파일해야합니다. 즉, 빠른 개발 (예 : 테스트 내 API 빌드)에는 적합하지 않습니다.
-
RequireJS- 인기 있고 간단하며 1-3을 해결하지만 범위 지정이 없다는 것은 실제 거래를 방해하는 요소 입니다 (나는 head.js 가 범위 지정이 없다는 점에서 비슷 하다고 생각 합니다.하지만 사용할 기회가 없었습니다. 마찬가지로 LABjs 는
.wait()
종속성 문제를 로드하고 수정 하지만 여전히 범위를 지정하지 않습니다.)
내가 알 수있는 한, 자바 스크립트의 동적 및 / 또는 비동기 로딩에 대한 많은 솔루션이있는 것처럼 보이지만 HTML에서 js를로드하는 것과 동일한 범위 지정 문제가있는 경향이 있습니다. 무엇보다도, 전역 네임 스페이스를 전혀 오염시키지 않지만 여전히 라이브러리를로드하고 사용할 수 있도록하는 자바 스크립트를로드하는 방법을 원합니다 (노드의 요구 사항과 마찬가지로).
2020 업데이트 : 모듈 은 이제 ES6의 표준이며 2020 년 중반부터 대부분의 브라우저에서 기본적으로 지원됩니다 . 모듈은 동기 및 비동기 (Promise 사용)로드를 모두 지원합니다. 나의 현재 권장 사항은 대부분의 새로운 프로젝트는 ES6 모듈을 사용하고 트랜스 파일러를 사용하여 레거시 브라우저 용 단일 JS 파일로 폴백하는 것입니다.
일반적으로 오늘날의 대역폭은 원래이 질문을 할 때보 다 일반적으로 훨씬 더 넓습니다. 따라서 실제로는 항상 ES6 모듈과 함께 트랜스 파일러를 사용하도록 합리적으로 선택하고 네트워크보다는 코드 효율성에 집중할 수 있습니다.
이전 편집 (또는 ES6 모듈이 마음에 들지 않는 경우) : 이 글을 작성한 후 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)를 사용했습니다. 또한 많은 라이브러리 / 모듈이 exports
AMD ( 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를 권장합니다.
최신 정보:
1 : require-kiss 는 이제 죽었고 저자는 그것을 제거했습니다. 나는 그 이후로 문제없이 RequireJS를 사용하고 있습니다. require-kiss의 저자는 pakmanager 및 pakman을 작성 했습니다 . 전체 공개, 저는 개발자와 협력합니다.
개인적으로 RequireJS가 더 좋습니다. 디버그하기가 훨씬 쉽고 (개발 중에 별도의 파일을 가질 수 있고 프로덕션에 배포 된 단일 파일을 가질 수 있음) 견고한 “표준”을 기반으로 구축되었습니다.
답변
여기서는 자바 스크립트 파일의 비동기 및 동기로드를 허용하는 작은 스크립트를 작성했습니다. 종속성이 없으며 Node.js 및 CommonJS와 호환됩니다. 설치는 매우 쉽습니다.
$ npm install --save @tarp/require
그런 다음 HTML에 다음 줄을 추가하여 메인 모듈을로드합니다.
<script src="/node_modules/@tarp/require/require.min.js"></script>
<script>Tarp.require({main: "./scripts/main"});</script>
메인 모듈 (및 모든 하위 모듈) 내 require()
에서 CommonJS / NodeJS에서 알고있는대로 사용할 수 있습니다 . 전체 문서와 코드는 GitHub 에서 찾을 수 있습니다 .
답변
코드를 구성하려는 초보자가있을 수 있음을 알고 있습니다. 이다 2020 , 당신은 모듈 JS 응용 프로그램을 고려하고 있다면, 당신은 시작한다 NPM 과 웹팩 지금.
시작하기위한 몇 가지 간단한 단계는 다음과 같습니다.
- 프로젝트 루트에서 실행
npm init -y
하여 npm 프로젝트를 초기화합니다. - Webpack 모듈 번 들러를 다운로드합니다.
npm install webpack webpack-cli
- index.html 파일을 만듭니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>App</title>
</head>
<body>
<script src="_bundle.js"></script>
</body>
</html>
_bundle.js
파일에 특별한주의를 기울 이십시오. 이것은 webpack에 의해 생성 된 최종 JS 파일이며 직접 수정하지 않습니다 (계속 읽으십시오).
<project-root>/app.js
다른 모듈을 가져올 파일을 만듭니다 .
const printHello = require('./print-hello');
printHello();
- 샘플
print-hello.js
모듈을 만듭니다 .
module.exports = function() {
console.log('Hello World!');
}
- 다음을
<project-root>/webpack.config.js
만들고 복사하여 붙여 넣습니다.
var path = require('path');
module.exports = {
entry: './app.js',
output: {
path: path.resolve(__dirname),
filename: '_bundle.js'
}
};
위의 코드에는 두 가지 점이 있습니다.
- 항목
app.js
은 JS 코드를 작성하는 곳입니다. 위에 표시된대로 다른 모듈을 가져옵니다. - 출력
_bundle.js
은 webpack에서 생성 한 최종 번들입니다. 이것이 당신의 html이 마지막에 보게 될 것입니다.
-7. 열려있는 package.js
및 교체 scripts
다음 명령을 :
"scripts": {
"start": "webpack --mode production -w"
},
- 마지막으로 스크립트 감시 를 실행하고 다음을 실행
app.js
하여_bundle.js
파일을 생성합니다npm start
.. - 코딩을 즐기십시오!
답변
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는 Node-style 모듈을 Browser에 번들로 제공합니다.
답변
Require-stub — require
브라우저에서 노드 호환 을 제공 하고 모듈과 상대 경로를 모두 확인합니다. TKRequire (XMLHttpRequest)와 유사한 기술을 사용합니다. 결과 코드는 완전히 브라우저 require-stub
화할 수 있으며 watchify
.