Browserify - ब्राउज़र में Browserify के माध्यम से उत्पन्न फ़ाइल में बंधे फ़ंक्शन को कैसे कॉल करें


96

मैं नोडज और ब्राउजर के लिए नया हूं। मैंने इस लिंक के साथ शुरुआत की ।

मेरे पास फाइल 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 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 पेज में बंडल.जेएस फ़ाइल को शामिल करने के बाद, मैं लॉगडैट फ़ंक्शन को कैसे कॉल करूं ??


आप इसे कहां बुलाना चाहते हैं? और आप इसे कॉल क्यों करना चाहते हैं?
Artur grzesiak

2
@arturgrzesiak: मैं अपने किसी अन्य प्रोजेक्ट में इस फ़ंक्शन का उपयोग करना चाहता हूं जिसे मैं ब्राउज़र में चला रहा हूं।
शार्प कोडर

जवाबों:


83

डिफ़ॉल्ट रूप से, ब्राउज़राइज़ आपको ब्राउज़र किए गए कोड के बाहर से मॉड्यूल का उपयोग करने की अनुमति नहीं देता है - यदि आप किसी ब्राउज़र मॉड्यूल में कोड को कॉल करना चाहते हैं, तो आपको मॉड्यूल के साथ अपने कोड को ब्राउज़ करना चाहिए। Http://browserify.org/ देखेंउस के उदाहरणों के लिए ।

बेशक, आप स्पष्ट रूप से अपनी पद्धति को इस तरह से बाहर से सुलभ बना सकते हैं:

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

तब आप LogData()पृष्ठ पर कहीं और से कॉल कर सकते थे ।


1
धन्यवाद। यह काम। क्या यह कहने के बजाय फ़ंक्शंस बनाते समय इसका मतलब है। FunctionName, मुझे window.functionName लिखना चाहिए? क्या हमारे पास इसके लिए कोई और काम है? Window.functionName का उपयोग करने के लिए कोई कारण?
शार्प कोडर

21
"आप मॉड्यूल के साथ मिलकर अपने कोड को ब्राउज़ करने वाले हैं" - उघ, अगर मैं कुछ ऐसा करना चाहता हूं तो क्या होगा onclick="someFunction()"। आप संभवतः तर्क नहीं दे सकते कि यह एक दुर्लभ उपयोग-मामला है ?!
ब्लूराजा - डैनी पफ्लुगुएफ्ट

57
वास्तव में क्लाइंट पर Browserify का उपयोग कैसे करें, इसके लिए कहीं भी प्रलेखन की गंभीर कमी है।
ओलिवर डिक्सन

1
हाँ, दस्तावेज़ीकरण में स्पष्ट रूप से कहा जाना चाहिए कि यह एक डिज़ाइन निर्णय है जिसे टाला जाना चाहिए, लेकिन इसे वैकल्पिक बनाने के लिए एक स्पष्ट रास्ता प्रदान करें जब आपके पास कोई विकल्प न हो (मेरे मामले में, जेएस ऑब्जेक्ट को पॉप्युलेट करने के लिए टेम्पलेट से डेटा का उपयोग करके) ... एक सरल समाधान की ओर इशारा करने के लिए @ @ धन्यवाद! ;)
अलेक्जेंड्रे मार्टिनी

1
मैं ऐसी स्थिति के बारे में भी नहीं सोच सकता जहाँ आप मॉड्यूल के बाहर अपने प्रमुख कार्यों को उपलब्ध कराना चाहते हों। यह कैसे डिफ़ॉल्ट व्यवहार नहीं है? वेब एप्लिकेशन किस प्रकार के कार्यों को कॉल नहीं करता है?
साइबरनेटिक

101

Browserify के साथ स्टैंडअलोन मॉड्यूल को बंडल करने का महत्वपूर्ण हिस्सा --sविकल्प है। यह नोड के module.exportsवैश्विक चर के रूप में आपके मॉड्यूल से जो भी आप निर्यात करता है, उसे उजागर करता है । फ़ाइल को तब a में शामिल किया जा सकता है<script> टैग ।

आपको केवल ऐसा करने की आवश्यकता है यदि किसी कारण से आपको उस वैश्विक चर को उजागर करने की आवश्यकता है। मेरे मामले में क्लाइंट को एक स्टैंडअलोन मॉड्यूल की आवश्यकता होती है जिसे इस ब्राउज़राइज़ व्यवसाय के बारे में चिंता करने की आवश्यकता के बिना वेब पृष्ठों में शामिल किया जा सकता है।

यहाँ एक उदाहरण है जहाँ हम --sविकल्प का उपयोग तर्क के साथ करते हैं module:

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

यह हमारे मॉड्यूल को एक वैश्विक चर नाम के रूप में उजागर करेगा module
स्रोत

अपडेट: @fotinakis के लिए धन्यवाद। सुनिश्चित करें कि आप गुजर रहे हैं --standalone your-module-name। अगर आप उसे भूल जाते हैं--standalone कोई तर्क लेता है, तो Browserify चुपचाप एक खाली मॉड्यूल उत्पन्न कर सकता है क्योंकि यह नहीं मिल रहा है।

आशा है कि यह आपको कुछ समय बचाता है।


2
मैं babelified ES6 कोड को ब्राउज़ करने की कोशिश कर रहा हूं। लेकिन जब मैं इसे ब्राउज़र में कंसोल करने का प्रयास करता हूं तो स्टैंडअलोन ऑब्जेक्ट खाली होता है। सरल ईएस 6 कोड बिना किसी मॉड्यूल के स्टैंडअलोन मोड में ठीक काम करता है। इस पर कोई संकेत?
जॉन

@jackyrudetsky कोई विचार नहीं है, मैं एसओ पर एक सवाल जोड़ने की सलाह दूंगा, एक दिलचस्प मुद्दे की तरह लगता है। इससे संबंधित हो सकता है। github.com/substack/node-browserify/issues/1357
Matas Vaitkevicius

1
@fotinakis यह वास्तव में Browserify github.com/substack/node-browserify/issues/1537
जॉन

3
IMO यह स्वीकृत उत्तर होना चाहिए। यदि आप एक वैश्विक फ़ंक्शन का उपयोग कर रहे हैं, तो विंडो के प्रत्येक फ़ंक्शन को हैंग करने की तुलना में अपने स्वयं के नाम स्थान होना बेहतर है।
विक्टरबी

1
@VictorB जावास्क्रिप्ट में सभी वैश्विक चर खिड़की के तत्व हैं, इसलिए दोनों विधियाँ एक ही चीज़ को प्राप्त करती हैं (वैश्विक चर को विंडो में जोड़ते हुए)
डेविड लोपेज़

37

@Masas Vaitkevicius का Browserify के स्टैंडअलोन विकल्प के साथ उत्तर सही है (@ thejh का जवाब विंडो वैश्विक चर का उपयोग करके भी काम करता है, लेकिन जैसा कि अन्य ने नोट किया है, यह वैश्विक नाम स्थान को प्रदूषित करता है, इसलिए यह आदर्श नहीं है)। मैं स्टैंडअलोन विकल्प का उपयोग करने के तरीके पर थोड़ा और विस्तार जोड़ना चाहता था।

स्रोत स्क्रिप्ट में जिसे आप बंडल करना चाहते हैं, मॉड्यूल.एक्सपोर्ट्स के माध्यम से उन फ़ंक्शन को उजागर करना सुनिश्चित करें जिन्हें आप कॉल करना चाहते हैं। क्लाइंट स्क्रिप्ट में, आप इन उजागर कार्यों को <बंडल-नाम> <func-name> के माध्यम से कॉल कर सकते हैं । यहाँ एक उदाहरण है:

मेरे स्रोत फ़ाइल src / script.js में यह होगा:
module.exports = {myFunc: func};

मेरा ब्राउज़र कमांड कुछ इस तरह दिखाई देगा:
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 आपको कुछ नोड फ़ंक्शन क्लाइंट-साइड का उपयोग करने की अनुमति देता है, लेकिन केवल बंडल स्क्रिप्ट में ही ; इसका मतलब यह नहीं है कि आप एक स्टैंडअलोन मॉड्यूल बना सकते हैं जिसे आप क्लाइंट-साइड में कहीं भी आयात और उपयोग कर सकते हैं, यही कारण है कि हमें इस सभी अतिरिक्त परेशानी के लिए जाना जाता है बस इसके बंडल्ड संदर्भ के बाहर एक फ़ंक्शन को कॉल करने के लिए।


3
वाह! अंत में एक व्यावहारिक उदाहरण।
N73k

1
अच्छा उदाहरण है, लेकिन जहां तक ​​"यह वैश्विक नाम स्थान को प्रदूषित करता है इसलिए आदर्श नहीं है" स्वचालित रूप से पालन नहीं करता है, तो यह स्वीकार्य हो सकता है यदि यह केवल एक ही फ़ंक्शन है; बस धुआं और दर्पण, यहां तक ​​कि window.myFunc () के बजाय myBundleविंडो ऑब्जेक्ट से जुड़ी हुई है window.myBundle.myFunc()
joedotnot

1
एंड-टू-एंड उदाहरण देने वाले लोगों के लिए अतिरिक्त अंक होने चाहिए।
शारुड़

इस तरह प्रलेखन को लिखा जाना चाहिए
एलेरी लेउंग

8

मैं सिर्फ उत्तरों के माध्यम से पढ़ता हूं और ऐसा लगता है जैसे किसी ने वैश्विक चर क्षेत्र के उपयोग का उल्लेख नहीं किया है? यदि आप नोड में एक ही कोड का उपयोग करना चाहते हैं तो उपयोगी है। js और ब्राउज़र में।

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

तब आप कहीं भी टेस्टक्लास का उपयोग कर सकते हैं ।

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

नोट: टेस्टक्लास तब हर जगह उपलब्ध हो जाता है। जो कि विंडो वेरिएबल का उपयोग करने के समान है।

इसके अतिरिक्त आप एक डेकोरेटर बना सकते हैं जो एक वर्ग को वैश्विक दायरे में उजागर करता है। जो वास्तव में अच्छा है, लेकिन यह ट्रैक करना मुश्किल है कि एक चर को कहां परिभाषित किया गया है।


जैसा कि आप स्वयं कहते हैं, फंक्शन को globalजोड़ने से जोड़ने के समान प्रभाव पैदा होता है window, जो पहले से ही ajh द्वारा कवर किया गया था। यह उत्तर कोई नई जानकारी नहीं जोड़ता है।
गेलन लांग

@GalenLong शायद आप भूल गए कि नोड.जेएस में कोई विंडो चर नहीं है? और नोड और ब्राउज़र को लक्षित करने वाले कुछ पुस्तकालय इसके बजाय वैश्विक उपयोग करना चाह सकते हैं। मेरे उत्तर में कुछ उथल-पुथल हुई और अभी तक माइनस में नहीं हूं इसलिए मुझे लगता है कि दूसरों के लिए इसकी सूचनात्मकता यदि आपके लिए नहीं है।
डीडीडी

तुम सही हो, @Azarus। पृष्ठ पर दो अन्य डुप्लिकेट उत्तर थे और मैंने आपको गलत तरीके से गुच्छा के साथ शामिल किया था। मैं क्षमाप्रार्थी हूं।
गैलेन लॉन्ग

बस यह नोट करना चाहते हैं कि यहां हैंगिंग पैरेंस जावास्क्रिप्ट के लिए एक बहुत बुरा अभ्यास है, उदाहरण के लिए: इस पैटर्न को रिटर्न कीवर्ड पर लागू करें और रोने के लिए तैयार करें। उदाहरण के लिए, return {}लेकिन अगली पंक्ति के लिए प्रारंभिक घुंघराले ब्रेस को छोड़ दें
Sgnl

1
@Azarus मैंने यह दिखाने के लिए एक फिडेल बनाया कि मेरा क्या मतलब है - jsfiddle.net/cubaksot/1
Sgnl

6

--standaloneपैरामीटर या Google के बारे में पढ़ें ब्राउज़र का README.md "ब्राउजर umd"


19
यह एक उत्तर की तुलना में उत्तर खोजने के लिए अधिक संकेत है।
user2314737

यह मुझे उस समाधान की ओर ले जाता है जिसे मैं दो दिनों से देख रहा था (कैसे एक आवश्यकता से ब्राउज़र उत्पादन का उपयोग करें)। धन्यवाद!
२३:१६ पर फ्लिन

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>

Daud:

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. वैकल्पिक - वस्तु "यह"

इस उद्देश्य के लिए मैं आपको "पूरे ऐप के लिए केवल 1 स्क्रिप्ट {{app_name}}" और "1 फ़ंक्शन {{function_name}}" मानूंगा

फ़ंक्शन "{function_name}} को ऑब्जेक्ट" इस "में जोड़ें

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

फिर आपको उस वस्तु का नाम उपलब्ध करवाना होगा - आप यह करेंगे कि वह दूसरों की सलाह के समान "नाम के साथ स्टैंडअलोन" को जोड़े

इसलिए यदि आप "ब्राउज़राइज़" के साथ "वॉचवाइज़" का उपयोग करते हैं, तो इसका उपयोग करें

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. वैकल्पिक - ऑब्जेक्ट "विंडो"

ऑब्जेक्ट "विंडो" में फ़ंक्शन {{function_name}} जोड़ें

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

फिर आप अपने फ़ंक्शन को ब्राउज़र से कॉल कर सकते हैं

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

-

शायद मैं किसी की मदद करूं


1

आपके पास कुछ विकल्प हैं:

  1. प्लग - इन ब्राउजर-ब्रिज को जेनरेट किए गए एंट्री मॉड्यूल के लिए मॉड्यूल निर्यात करें। यह SDK प्रोजेक्ट्स या उन स्थितियों के लिए मददगार है, जहाँ आपको एक्सपोर्ट होने वाली चीज़ों को मैन्युअली नहीं रखना है।

  2. रोल-अप प्रदर्शन के लिए एक छद्म नाम स्थान पैटर्न का पालन करें:

सबसे पहले, अपनी लाइब्रेरी को इस तरह व्यवस्थित करें, जिसमें फ़ोल्डरों पर इंडेक्स लुक-अप का लाभ उठाया जाए:

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

इस पैटर्न के साथ, आप प्रविष्टि को इस तरह परिभाषित करते हैं:

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

सूचना को स्वचालित रूप से प्रत्येक संबंधित उप-फ़ोल्डर से index.js को लोड करने की आवश्यकता है

अपने सबफ़ोल्डर्स में, आप उस संदर्भ में उपलब्ध मॉड्यूल का एक समान रूप शामिल कर सकते हैं:

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

यह पैटर्न वास्तव में अच्छी तरह से मापता है और रोल-अप एप में शामिल करने के लिए प्रासंगिक (फ़ोल्डर द्वारा फ़ोल्डर) ट्रैकिंग की अनुमति देता है।


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

फ़ंक्शन को केवल कॉल करें LogData(data)

यह सिर्फ एक छोटा सा संशोधन है जो उत्तर के लिए महत्वपूर्ण है, लेकिन महत्वपूर्ण है


यह संशोधन प्रश्न पूछने वाले की चिंताओं के लिए अप्रासंगिक है और पहले से मौजूद उत्तरों को देखते हुए कोई नई जानकारी नहीं जोड़ता है।
गेलन लांग

-2

डीबगिंग उद्देश्यों के लिए मैंने इस कोड को अपने कोड में जोड़ा। js:

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

फिर मैं बंडल के बाहर भी कुछ भी चला सकता था।

e("anything();");
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.