Browserify-브라우저에서 browserify를 통해 생성 된 파일에 번들 된 함수를 호출하는 방법


96

나는 nodejs와 browserify를 처음 사용합니다. 나는이 링크로 시작했다 .

이 코드가 포함 된 main.js 파일이 있습니다.

var unique = require('uniq');

var data = [1, 2, 2, 3, 4, 5, 5, 5, 6];

this.LogData =function(){
console.log(unique(data));
};

이제 npm으로 uniq 모듈을 설치합니다.

 npm install uniq

그런 다음 main.js에서 시작하는 모든 필수 모듈을 browserify 명령을 사용하여 bundle.js라는 단일 파일로 묶습니다.

browserify main.js -o bundle.js

생성 된 파일은 다음과 같습니다.

(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
var unique = require('uniq');

var data = [1, 2, 2, 3, 4, 5, 5, 5, 6];

this.LogData =function(){
console.log(unique(data));
};

},{"uniq":2}],2:[function(require,module,exports){
"use strict"

function unique_pred(list, compare) {
  var ptr = 1
    , len = list.length
    , a=list[0], b=list[0]
  for(var i=1; i<len; ++i) {
    b = a
    a = list[i]
    if(compare(a, b)) {
      if(i === ptr) {
        ptr++
        continue
      }
      list[ptr++] = a
    }
  }
  list.length = ptr
  return list
}

function unique_eq(list) {
  var ptr = 1
    , len = list.length
    , a=list[0], b = list[0]
  for(var i=1; i<len; ++i, b=a) {
    b = a
    a = list[i]
    if(a !== b) {
      if(i === ptr) {
        ptr++
        continue
      }
      list[ptr++] = a
    }
  }
  list.length = ptr
  return list
}

function unique(list, compare, sorted) {
  if(list.length === 0) {
    return []
  }
  if(compare) {
    if(!sorted) {
      list.sort(compare)
    }
    return unique_pred(list, compare)
  }
  if(!sorted) {
    list.sort()
  }
  return unique_eq(list)
}

module.exports = unique
},{}]},{},[1])

내 index.htm 페이지에 bundle.js 파일을 포함시킨 후 logData 함수를 어떻게 호출합니까?


어디로 부르시겠습니까? 그리고 왜 그것을 부르고 싶습니까?
artur grzesiak 2014

2
@arturgrzesiak : 브라우저에서 실행할 다른 프로젝트 중 하나에서이 기능을 활용하고 싶습니다.
SharpCoder

답변:


83

기본적으로 browserify는 브라우저 화 된 코드 외부에서 모듈에 액세스하는 것을 허용하지 않습니다. 브라우저 화 된 모듈에서 코드를 호출하려면 모듈과 함께 코드를 브라우저 화해야합니다. 이에 대한 예는 http://browserify.org/ 를 참조하십시오 .

물론 다음과 같이 외부에서 메서드에 액세스 할 수 있도록 명시 적으로 만들 수도 있습니다.

window.LogData =function(){
  console.log(unique(data));
};

그런 다음 LogData()페이지의 다른 곳에서 전화 를 걸 수 있습니다.


1
감사합니다. 작동합니다. 이것은 this.functionName 대신 함수를 만드는 동안 window.functionName을 작성해야 함을 의미합니까? 이에 대한 다른 해결 방법이 있습니까? window.functionName을 사용하는 이유는 무엇입니까?
SharpCoder 2014

21
"모듈과 함께 코드를 브라우저 화해야합니다." -어, 만약 내가 onclick="someFunction()". 드문 사용 사례라고 주장 할 수는 없습니다!?!
BlueRaja-Danny Pflughoeft

57
클라이언트에서 실제로 Browserify를 사용하는 방법에 대한 초보자를위한 문서가 어디에도 심각하게 부족합니다.
Oliver Dixon

1
예, 문서에는 이것이 피해야 할 설계 결정이라고 명확하게 명시해야하지만 대안이 없을 때 작동하도록 명확한 경로를 제공해야합니다 (제 경우에는 템플릿의 데이터를 사용하여 JS 객체를 채움). ... 간단한 해결책을 알려준 @thejh에게 감사드립니다! ;)
Alexandre Martini

1
모듈 외부에서 주요 기능을 사용할 수 있도록하고 싶지 않은 상황도 생각할 수 없습니다. 이것이 기본 동작이 아닌 이유는 무엇입니까? 어떤 종류의 웹 애플리케이션이 함수를 호출하지 않습니까?
Cybernetic

101

Browserify와 함께 독립형 모듈을 번들링하는 핵심 부분은 --s옵션입니다. 노드를 module.exports전역 변수로 사용하여 모듈에서 내보내는 모든 것을 노출 합니다. 그런 다음 파일을 <script>태그에 포함 할 수 있습니다 .

어떤 이유로 해당 전역 변수를 노출해야하는 경우에만이 작업을 수행하면됩니다. 제 경우 클라이언트는이 Browserify 비즈니스에 대해 걱정할 필요없이 웹 페이지에 포함될 수있는 독립형 모듈이 필요했습니다.

다음 --s은 인수와 함께 옵션을 사용하는 예 입니다 module.

browserify index.js --s module > dist/module.js

그러면 모듈이라는 전역 변수로 노출됩니다 module.
소스 .

업데이트 : @fotinakis 덕분입니다. 통과하고 있는지 확인하십시오 --standalone your-module-name. --standalone인수를받는 것을 잊은 경우 Browserify는 찾을 수 없기 때문에 빈 모듈을 자동으로 생성 할 수 있습니다.

이것이 시간을 절약하기를 바랍니다.


2
babelified ES6 코드를 브라우저 화하려고합니다. 그러나 브라우저에서 콘솔을 시도 할 때 독립 실행 형 개체가 비어 있습니다. 모듈이없는 간단한 ES6 코드는 독립형 모드에서 잘 작동합니다. 이것에 대한 어떤 조언?
John

@ jackyrudetsky 전혀 모르겠습니다. 질문을 추가하는 것이 좋습니다. 흥미로운 문제처럼 들립니다. 이것과 관련이있을 수 있습니다. github.com/substack/node-browserify/issues/1357
마타스 Vaitkevicius

1
@fotinakis 실제로 Browserify의 문제였습니다. github.com/substack/node-browserify/issues/1537
John

3
IMO 이것은 받아 들여진 대답이어야합니다. 전역 함수를 사용하는 경우 모든 함수를 창에서 중단하는 것보다 고유 한 네임 스페이스를 갖는 것이 훨씬 낫습니다.
VictorB

1
@VictorB 자바 스크립트의 모든 글로벌 변수는 윈도우의 요소는, 둘 방법은 (창으로 전역 변수를 추가) 같은 일을 달성 할 수 있도록
데이빗 로페즈

37

Browserify 의 독립형 옵션에 대한 @Matas Vaitkevicius의 대답 은 정확합니다 (@thejh의 창 전역 변수를 사용하는 대답 도 작동하지만 다른 사람들이 지적했듯이 전역 네임 스페이스를 오염시켜 이상적이지 않습니다). 독립형 옵션을 사용하는 방법에 대해 좀 더 자세히 설명하고 싶었습니다.

번들링하려는 소스 스크립트에서 module.exports를 통해 호출하려는 함수를 노출해야합니다. 클라이언트 스크립트에서 <bundle-name>. <func-name>을 통해 이러한 노출 된 함수를 호출 할 수 있습니다 . 예를 들면 다음과 같습니다.

소스 파일 src / script.js 는 다음과 같습니다.
module.exports = {myFunc: func};

browserify 명령 은 다음과 같습니다.
browserify src/script.js --standalone myBundle > dist/bundle.js

그리고 내 클라이언트 스크립트 dist / client.js 는 번들 스크립트를로드
<script src="bundle.js"></script>
한 다음 다음과 같이 노출 된 함수를 호출합니다.
<script>myBundle.myFunc();</script>


노출 된 함수를 호출하기 전에 클라이언트 스크립트에서 번들 이름을 요구할 필요 <script src="bundle.js"></script><script>var bundled = require("myBundle"); bundled.myFunc();</script>가 없습니다. 예를 들어 필요하지 않으며 작동하지 않습니다.

실제로 독립 실행 형 모드없이 browserify에서 번들로 제공하는 모든 함수와 마찬가지로 require 함수는 번들 ​​스크립트 외부에서 사용할 수 없습니다 . Browserify를 사용하면 일부 노드 기능을 클라이언트 측에서 사용할 수 있지만 번들 스크립트 자체에서만 사용할 수 있습니다 . 클라이언트 측 어디에서나 가져 와서 사용할 수있는 독립형 모듈을 만드는 것이 아닙니다. 이것이 바로 번들 컨텍스트 외부에서 단일 함수를 호출하기 위해이 모든 추가 문제를 해결해야하는 이유입니다.


3
와! 마지막으로 실용적인 예입니다.
N73k

1
좋은 예입니다. 그러나 "전역 네임 스페이스를 오염 시키므로 이상적이지 않습니다."가 자동으로 따르지 않는 한, 하나의 함수 만 허용 될 수도 있습니다. 그냥 연기와 거울, 심지어 window.myFunc () 대신 myBundle창 개체에 연결됩니다 window.myBundle.myFunc()
joedotnot

1
종단 간 예제를 제공하는 사람들에게는 추가 점수가 있어야합니다.
Sharud

이것이 문서 작성 방법입니다
Ellery Leung

8

나는 대답을 읽었고 아무도 전역 변수 범위의 사용을 언급하지 않은 것 같습니다. node.js와 브라우저에서 동일한 코드를 사용하려는 경우 유용합니다.

class Test
{
  constructor()
  {
  }
}
global.TestClass = Test;

그런 다음 어디에서나 TestClass에 액세스 할 수 있습니다 .

<script src="bundle.js"></script>
<script>
var test = new TestClass(); // Enjoy!
</script>

참고 : TestClass는 모든 곳에서 사용할 수 있습니다. window 변수를 사용하는 것과 같습니다.

또한 클래스를 전역 범위에 노출하는 데코레이터를 만들 수 있습니다. 정말 훌륭하지만 변수가 정의 된 위치를 추적하기 어렵습니다.


직접 말했듯이, 함수를 추가하면에 추가하는 global것과 동일한 효과 가 생성 window됩니다. 이 답변은 새로운 정보를 추가하지 않습니다.
Galen Long

@GalenLong 아마도 node.js에 창 변수가 없다는 것을 잊었습니까? 그리고 노드와 브라우저를 대상으로하는 일부 라이브러리는 대신 전역을 사용할 수 있습니다. 내 대답은 몇 가지 upvotes를 받았지만 아직 마이너스가 아니므로 다른 사람들에게 유익하다고 생각합니다.
DDD

맞아요, @Azarus. 페이지에 다른 두 개의 중복 답변이 있었고 나는 당신의 답변을 무리에 잘못 포함했습니다. 죄송합니다.
Galen Long

여기에 매달려있는 괄호는 자바 스크립트에 매우 나쁜 습관이라는 점을 주목하고 싶습니다. 예를 들어,이 패턴을 return 키워드에 적용하고 울 준비를하십시오. 예를 들어 return {}여는 중괄호를 다음 줄로 떨어 뜨립니다.
Sgnl

1
@Azarus 나는 내가 의미하는 바를 보여주기 위해 바이올린을 만들었습니다 -jsfiddle.net/cubaksot/1
Sgnl

6

--standalone매개 변수 또는 Google "browserify umd"에 대한 browserify의 README.md를 읽어 보세요.


19
이것은 답보다 답을 찾을 수있는 위치에 대한 힌트입니다.
user2314737

이로 인해 이틀 동안 찾고 있던 솔루션 (require.js 환경에서 browserify 출력을 사용하는 방법)으로 연결됩니다. 감사합니다!
Flion 2014-08-25

2

HTML과 서버 측 노드 모두에서 함수를 사용할 수 있도록하려면 :

main.js :

var unique = require('uniq');

function myFunction() {
    var data = [1, 2, 2, 4, 3];
    return unique(data).toString();
}
console.log ( myFunction() );

// When browserified - we can't call myFunction() from the HTML, so we'll externalize myExtFunction()
// On the server-side "window" is undef. so we hide it.
if (typeof window !== 'undefined') {
    window.myExtFunction = function() {
        return myFunction();
    }
}

main.html :

<html>
    <head>
        <script type='text/javascript' src="bundle.js"></script>
    <head>
    <body>
        Result: <span id="demo"></span>
        <script>document.getElementById("demo").innerHTML = myExtFunction();</script>
    </body>
</html>

운영:

npm install uniq
browserify main.js > bundle.js

브라우저에서 main.html을 실행할 때와 동일한 결과를 얻을 수 있습니다.

node main.js

2

최소 실행 가능 예

이것은 기본적으로 https://stackoverflow.com/a/43215928/895245 와 동일 하지만 직접 실행하고 쉽게 재현 할 수있는 구체적인 파일이 있습니다.

이 코드는 https://github.com/cirosantilli/browserify-hello-world 에서도 확인할 수 있습니다.

index.js

const uniq = require('uniq');

function myfunc() {
  return uniq([1, 2, 2, 3]).join(' ');
}
exports.myfunc = myfunc;

index.html

<!doctype html>
<html lang=en>
<head>
<meta charset=utf-8>
<title>Browserify hello world</title>
</head>
<body>
<div id="container">
</body>
</div>
<script src="out.js"></script>
<script>
document.getElementById('container').innerHTML = browserify_hello_world.myfunc();
</script>
</html>

Node.js 사용법 :

#!/usr/bin/env node

const browserify_hello_world = require('./index.js');

console.log(browserify_hello_world.myfunc());

out.js브라우저 사용을 위해 생성 :

npx browserify --outfile out.js --standalone browserify_hello_world index.js

브라우저와 명령 줄 모두 예상되는 출력을 표시합니다.

1 2 3

Browserify 16.5.0, Node.js v10.15.1, Chromium 78, Ubuntu 19.10으로 테스트되었습니다.


1
이것의 exports.myfunc.= myfunc부분은 절대적으로 비판적이었고 다른 답변에서 누락되었습니다.
parttimeturtle

2

정말 간단합니다. 전체 개념은 포장에 관한 것입니다.

1. 대안-개체 "this"

이 목적을 위해 "전체 앱 {{app_name}}에 대한 스크립트 1 개만"및 "1 함수 {{function_name}}"가 있다고 가정하겠습니다.

"this"개체에 {{function_name}} 함수 추가

function {{function_name}}(param) {}
->
this.{{function_name}} = function(param) {}

그런 다음 사용할 수 있도록 해당 개체의 이름을 지정해야합니다. 다른 사용자가 권장하는 것처럼 "이름이있는 독립 실행 형"매개 변수를 추가합니다.

그래서 "browserify"와 함께 "watchify" 를 사용한다면 이것을 사용하세요

var b = browserify({
    ...
    standalone: '{{app_name}}'
});

또는 명령 줄

browserify index.js --standalone {{app_name}} > index-bundle.js

그런 다음 브라우저에서 함수를 호출 할 수 있습니다.

{{app_name}}.{{function_name}}(param);
window.{{app_name}}.{{function_name}}(param);

2. 대안-개체 "창"

"window"개체에 {{function_name}} 함수 추가

function {{function_name}}(param) {}
->
window.{{function_name}} = function(param) {}

그런 다음 브라우저에서 함수를 호출 할 수 있습니다.

{{function_name}}(param);
window.{{function_name}}(param);

-

내가 누군가를 도울지도 몰라


1

몇 가지 옵션이 있습니다.

  1. 플러그인 browserify-bridge 가 모듈을 생성 된 항목 모듈로 자동 내보내도록합니다. 이는 내보내는 내용을 수동으로 따라갈 필요가없는 SDK 프로젝트 또는 상황에 유용합니다.

  2. 롤업 노출을 위해 의사 네임 스페이스 패턴을 따릅니다.

먼저 폴더에 대한 색인 조회를 활용하여 다음과 같이 라이브러리를 정렬합니다.

/src
--entry.js
--/helpers
--- index.js
--- someHelper.js
--/providers
--- index.js
--- someProvider.js
...

이 패턴을 사용하여 다음과 같은 항목을 정의합니다.

exports.Helpers = require('./helpers');
exports.Providers = require('./providers');
...

require는 각 하위 폴더에서 index.js를 자동으로로드합니다.

하위 폴더에 해당 컨텍스트에서 사용 가능한 모듈의 유사한 매니페스트를 포함 할 수 있습니다.

exports.SomeHelper = require('./someHelper');

이 패턴은 정말 잘 확장되며 롤업 된 API에 포함 할 내용의 컨텍스트 (폴더 별) 추적을 허용합니다.


-1
window.LogData =function(data){
   return unique(data);
};

간단히 함수를 호출하십시오. LogData(data)

이것은 thejh의 대답에 대한 약간의 수정 이지만 중요한 것입니다.


이 수정은 질문 요청자의 우려 사항과 관련이 없으며 이미 존재하는 답변이 주어지면 새로운 정보를 추가하지 않습니다.
Galen Long

-2

디버깅 목적으로이 줄을 내 code.js에 추가했습니다.

window.e = function(data) {eval(data);};

그러면 번들 외부에서도 무엇이든 실행할 수 있습니다.

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