Node.js와 브라우저간에 코드를 공유하려면 어떻게해야합니까?
JavaScript 클라이언트 (브라우저에서 실행)와 Node.js 서버로 WebSocket을 사용하여 통신하는 작은 응용 프로그램을 만들고 있습니다.
클라이언트와 서버간에 코드를 공유하고 싶습니다. 방금 Node.js로 시작했으며 현대 JavaScript에 대한 내 지식은 조금 녹슨 것입니다. 그래서 나는 여전히 CommonJS require () 함수를 둘러보고 있습니다. '내보내기'객체를 사용하여 패키지를 작성하는 경우 브라우저에서 동일한 JavaScript 파일을 사용하는 방법을 볼 수 없습니다.
메시지 인코딩 및 디코딩, 기타 미러링 된 작업을 용이하게하기 위해 양쪽 끝에 사용되는 메서드 및 클래스 집합을 만들고 싶습니다. 그러나 Node.js / CommonJS 패키징 시스템은 양면에서 사용할 수있는 JavaScript 파일을 만드는 것을 방해합니다.
또한 JS.Class를 사용하여 더 단단한 OO 모델을 얻으려고 시도했지만 제공된 JavaScript 파일을 require ()와 함께 작동시키는 방법을 알 수 없기 때문에 포기했습니다. 내가 여기서 놓친 것이 있습니까?
클라이언트 측과 서버 측 모두에서 사용할 수있는 모듈을 작성하려면 빠르고 쉬운 방법에 대한 간단한 블로그 게시물 이 있습니다 .Node.js 및 브라우저 작성 기본적으로 다음과 같습니다 ( this
와 동일 window
) :
(function(exports){
// Your code goes here
exports.test = function(){
return 'hello world'
};
})(typeof exports === 'undefined'? this['mymodule']={}: exports);
또는 Marak의 gemini 와 같이 클라이언트 측에서 Node.js API를 구현하려는 일부 프로젝트가 있습니다 .
간단한 JSON 기반 네트워크 프로토콜을 사용하여 다른 시스템에서 호출 할 수 있도록 JavaScript 함수를 노출 할 수 있는 DNode에 관심이있을 수도 있습니다 .
Epeli는 http://epeli.github.com/piler/ 여기 에 라이브러리 없이도 작동 하는 멋진 솔루션을 제공 합니다. 이것을 share.js라는 파일에 넣으십시오.
(function(exports){
exports.test = function(){
return 'This is a function from shared module';
};
}(typeof exports === 'undefined' ? this.share = {} : exports));
서버 측에서는 다음을 사용하십시오.
var share = require('./share.js');
share.test();
그리고 클라이언트 측에서 js 파일을로드 한 다음 사용하십시오.
share.test();
Node.js 모듈 패턴, AMD 모듈 패턴 및 브라우저에서 전역 적으로 작동하도록하는 jQuery 소스 코드를 확인하십시오.
(function(window){
var jQuery = 'blah';
if (typeof module === "object" && module && typeof module.exports === "object") {
// Expose jQuery as module.exports in loaders that implement the Node
// module pattern (including browserify). Do not create the global, since
// the user will be storing it themselves locally, and globals are frowned
// upon in the Node module world.
module.exports = jQuery;
}
else {
// Otherwise expose jQuery to the global object as usual
window.jQuery = window.$ = jQuery;
// Register as a named AMD module, since jQuery can be concatenated with other
// files that may use define, but not via a proper concatenation script that
// understands anonymous AMD modules. A named AMD is safest and most robust
// way to register. Lowercase jquery is used because AMD module names are
// derived from file names, and jQuery is normally delivered in a lowercase
// file name. Do this after creating the global so that if an AMD module wants
// to call noConflict to hide this version of jQuery, it will work.
if (typeof define === "function" && define.amd) {
define("jquery", [], function () { return jQuery; });
}
}
})(this)
JavaScript 함수의 문자열 표현은 해당 함수의 소스 코드를 나타냅니다. 함수와 생성자를 캡슐화 된 방식으로 작성하여 toString ()하고 클라이언트로 보낼 수 있습니다.
또 다른 방법은 빌드 시스템을 사용하고 공통 코드를 별도의 파일에 넣은 다음 서버와 클라이언트 스크립트 모두에 포함시키는 것입니다. 서버와 클라이언트가 본질적으로 동일한 게임 루프를 실행하고 클라이언트가 서버와 동기화되어 아무도 부정 행위를하지 않는 WebSockets를 통해 간단한 클라이언트 / 서버 게임 에이 접근법을 사용하고 있습니다.
게임의 빌드 시스템 은 C 전처리기를 통해 파일을 실행 한 다음 sed를 통해 정크 cpp 잎을 뒤에 정리 하는 간단한 Bash 스크립트이므로 #include, #define, #ifdef와 같은 모든 일반적인 전 처리기 항목을 사용할 수 있습니다 등
Node.js 용 RequireJS 어댑터를 살펴 보는 것이 좋습니다 . 문제는 기본적으로 Node.js가 사용하는 CommonJS 모듈 패턴이 비동기 적이 지 않으므로 웹 브라우저에서로드를 차단한다는 것입니다. RequireJS는 어댑터를 사용하는 한 비동기식이며 서버 및 클라이언트와 호환되는 AMD 패턴을 사용합니다 r.js
.
어쩌면 이것이 질문과 완전히 일치하지는 않지만 공유 할 것이라고 생각했습니다.
String.prototype에 선언 된 몇 가지 간단한 문자열 유틸리티 함수를 노드와 브라우저 모두에서 사용할 수 있도록 만들고 싶습니다. 이 함수를 간단히 utilities.js (하위 폴더에있는) 파일에 보관하고 브라우저 코드의 스크립트 태그와 Node.js 스크립트에서 require (.js 확장자 생략)를 사용하여 쉽게 참조 할 수 있습니다. :
my_node_script.js
var utilities = require('./static/js/utilities')
my_browser_code.html
<script src="/static/js/utilities.js"></script>
이것이 다른 사람에게 유용한 정보가되기를 바랍니다.
브라우저에서 사용하기 위해 webpack 과 같은 모듈 번 들러 를 사용하여 JavaScript 파일을 번들로 제공하는 경우 브라우저에서 실행되는 프론트 엔드에 Node.js 모듈을 재사용하면됩니다. 즉, Node.js 모듈은 Node.js와 브라우저간에 공유 될 수 있습니다.
예를 들어 다음 코드 sum.js가 있습니다.
일반 Node.js 모듈 : sum.js
const sum = (a, b) => {
return a + b
}
module.exports = sum
Node.js에서 모듈 사용
const sum = require('path-to-sum.js')
console.log('Sum of 2 and 5: ', sum(2, 5)) // Sum of 2 and 5: 7
프론트 엔드에서 재사용
import sum from 'path-to-sum.js'
console.log('Sum of 2 and 5: ', sum(2, 5)) // Sum of 2 and 5: 7
서버는 단순히 JavaScript 소스 파일을 클라이언트 (브라우저)에 보낼 수 있지만, 클라이언트는 exec
코드를 작성하고 모듈로 저장 하기 전에 미니 "내보내기"환경을 제공해야합니다 .
그러한 환경을 만드는 간단한 방법은 클로저를 사용하는 것입니다. 예를 들어, 서버가와 같은 HTTP를 통해 소스 파일을 제공한다고 가정하십시오 http://example.com/js/foo.js
. 브라우저는 XMLHttpRequest를 통해 필요한 파일을로드하고 다음과 같이 코드를로드 할 수 있습니다.
ajaxRequest({
method: 'GET',
url: 'http://example.com/js/foo.js',
onSuccess: function(xhr) {
var pre = '(function(){var exports={};'
, post = ';return exports;})()';
window.fooModule = eval(pre + xhr.responseText + post);
}
});
핵심은 클라이언트가 외부 코드를 익명 함수로 래핑하여 즉시 실행 (닫기)하여 "내보내기"개체를 생성하고 반환함으로써 전역 네임 스페이스를 오염시키지 않고 원하는 곳에 할당 할 수 있다는 것입니다. 이 예제에서는 fooModule
파일에서 내 보낸 코드를 포함 할 window 속성에 할당 됩니다 foo.js
.
이전 솔루션 중 어느 것도 CommonJS 모듈 시스템을 브라우저로 가져 오지 않습니다.
다른 답변에서 언급 한 바와 같이, 같은 자산 관리자 / 포장기 솔루션이 있습니다 Browserify 또는 펠리은 과 같은 RPC 솔루션이 있습니다 dnode 또는 nowjs은 .
그러나 브라우저에 대한 CommonJS 구현 ( require()
기능 및 exports
/ module.exports
객체 등 포함)을 찾을 수 없습니다 . 그래서 나는 내 자신의 글을 썼다. 나중에 다른 사람이 나보다 더 잘 썼다는 것을 발견하기 위해서만 https://github.com/weepy/brequire . Brequire (브라우저 요구의 약자)라고합니다.
인기로 판단하면 자산 관리자는 대부분의 개발자의 요구를 충족시킵니다. 그러나 CommonJS의 브라우저 구현이 필요한 경우 Brequire 가 비용에 적합 할 것입니다.
2015 업데이트 : 더 이상 Brequire를 사용하지 않습니다 (몇 년 동안 업데이트되지 않았습니다). 작은 오픈 소스 모듈을 작성하고 누구나 쉽게 사용할 수 있기를 원한다면 Caolan의 답변과 유사한 패턴을 따라갈 것입니다. 위에 몇 년 동안 블로그 게시물을 썼습니다 . 전에.
그러나 개인적으로 사용하거나 Ampersand 커뮤니티 와 같이 CommonJS에서 표준화 된 커뮤니티를 위해 모듈을 작성하는 경우 CommonJS 형식으로 작성하고 Browserify를 사용 합니다 .
now.js 도 살펴볼 가치가 있습니다. 클라이언트 측에서 서버 측을 호출하고 서버 측에서 클라이언트 측 기능을 호출 할 수 있습니다
Node.js와 같은 스타일로 브라우저를 작성하려면 dualify 을 사용해보십시오 .
브라우저 코드 컴파일이 없으므로 제한없이 애플리케이션을 작성할 수 있습니다.
코드를 RequireJS 모듈로, 테스트를 Jasmine 테스트 로 작성하십시오 .
이 방법으로 RequireJS를 사용하여 코드를 어디서나로드 할 수 있으며 테스트 는 코드 또는 테스트를 수정할 필요없이 브라우저에서 jasmine-html 및 Node.js의 jasmine-node 를 사용 하여 브라우저에서 실행됩니다 .
이에 대한 실제 예 는 다음과 같습니다 .
사용 사례 : Node.js와 브라우저간에 앱 구성을 공유합니다 (이것은 단지 예시 일 뿐이며 앱에 따라 최선의 방법은 아닙니다).
문제점 : window
(Node.js에 존재하지 않음) 또는 global
(브라우저에 존재하지 않음 )을 사용할 수 없습니다 .
해결책:
파일 config.js :
var config = { foo: 'bar' }; if (typeof module === 'object') module.exports = config;
브라우저 (index.html)에서 :
<script src="config.js"></script> <script src="myApp.js"></script>
이제 개발자 도구를 열고 전역 변수에 액세스 할 수 있습니다
config
Node.js (app.js)에서 :
const config = require('./config'); console.log(config.foo); // Prints 'bar'
Babel 또는 TypeScript를 사용하는 경우 :
import config from './config'; console.log(config.foo); // Prints 'bar'
내가 쓴 간단한 모듈 은 클라이언트에서 서버에서 모두로드 모듈에 사용할 수있는, (두 노드에 필요하거나 브라우저에서 스크립트 태그 사용) 가져올 수 있습니다.
사용법 예
1. 모듈 정의
log2.js
정적 웹 파일 폴더 안의 파일에 다음을 배치하십시오.
let exports = {};
exports.log2 = function(x) {
if ( (typeof stdlib) !== 'undefined' )
return stdlib.math.log(x) / stdlib.math.log(2);
return Math.log(x) / Math.log(2);
};
return exports;
그렇게 간단합니다!
2. 모듈 사용
그것이이기 때문에 양자 모듈 로더, 우리는 양쪽 (클라이언트 및 서버)에서로드 할 수 있습니다. 따라서 다음을 수행 할 수 있지만 한 번에 둘 다 수행 할 필요는 없습니다 (특정 순서로 단독으로 수행).
- 노드에서
노드에서는 간단합니다.
var loader = require('./mloader.js');
loader.setRoot('./web');
var logModule = loader.importModuleSync('log2.js');
console.log(logModule.log2(4));
이 반환되어야합니다 2
.
파일이 노드의 현재 디렉토리에 없으면 loader.setRoot
정적 웹 파일 폴더의 경로 (또는 모듈이있는 곳) 를 호출해야합니다 .
- 브라우저에서 :
먼저 웹 페이지를 정의하십시오.
<html>
<header>
<meta charset="utf-8" />
<title>Module Loader Availability Test</title>
<script src="mloader.js"></script>
</header>
<body>
<h1>Result</h1>
<p id="result"><span style="color: #000088">Testing...</span></p>
<script>
let mod = loader.importModuleSync('./log2.js', 'log2');
if ( mod.log2(8) === 3 && loader.importModuleSync('./log2.js', 'log2') === mod )
document.getElementById('result').innerHTML = "Your browser supports bilateral modules!";
else
document.getElementById('result').innerHTML = "Your browser doesn't support bilateral modules.";
</script>
</body>
</html>
당신이 있는지 확인 하지 않는 브라우저에서 직접 파일을 열; AJAX를 사용하기 때문에 대신 Python 3의 http.server
모듈 (또는 초고속, 명령 줄, 폴더 웹 서버 배포 솔루션이 무엇이든)을 살펴 보는 것이 좋습니다 .
모든 것이 잘되면 다음과 같이 나타납니다.
나는 이것을 작성했다. 모든 변수를 전역 범위로 설정하려면 사용하는 것이 간단하다.
(function(vars, global) {
for (var i in vars) global[i] = vars[i];
})({
abc: function() {
...
},
xyz: function() {
...
}
}, typeof exports === "undefined" ? this : exports);
참고 URL : https://stackoverflow.com/questions/3225251/how-can-i-share-code-between-node-js-and-the-browser
'Programing' 카테고리의 다른 글
npm 피어 종속성을 자동으로 설치하는 방법은 무엇입니까? (0) | 2020.04.13 |
---|---|
C ++ 11을 활성화 할 때 std :: vector 성능 회귀 (0) | 2020.04.13 |
실제로 스택 오버플로 오류의 원인은 무엇입니까? (0) | 2020.04.13 |
새로운 언어 기능을 사용하는 프로그램에서 Python 버전을 확인하려면 어떻게해야합니까? (0) | 2020.04.13 |
std :: string length () 및 size () 멤버 함수 (0) | 2020.04.13 |