Browserify - вызов функции, связанной с файлом, созданным с помощью браузера в браузере

Я новичок в nodejs и браунирую. Я начал с этой .

У меня есть файл main.js, который содержит этот код

var unique = require('uniq');

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

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

Теперь я устанавливаю модуль uniq с номером npm:

 npm install uniq

Затем я собираю все необходимые модули, начиная с main.js, в один файл с именем 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])

После включения файла bundle.js на мою страницу index.htm, как мне вызвать функцию logData?

Ответ 1

По умолчанию браузер не позволяет вам получать доступ к модулям из-за прокрученного кода - если вы хотите вызвать код в браузере, вы должны прокручивать код вместе с модулем. Для примера см. http://browserify.org/.

Конечно, вы также можете явно сделать свой метод доступным извне, как это:

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

Затем вы можете вызвать LogData() из любого места на странице.

Ответ 2

Ключевой частью комплектации автономных модулей с Browserify является опция --s. Он предоставляет все, что вы экспортируете из своего модуля, используя node module.exports в качестве глобальной переменной. Затем файл можно включить в тег <script>.

Вам нужно сделать это только в том случае, если по какой-то причине вам понадобится эта глобальная переменная. В моем случае клиенту нужен отдельный модуль, который может быть включен в веб-страницы без необходимости беспокоиться об этом бизнесе Browserify.

В этом примере мы используем опцию --s с аргументом module:

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

Это откроет наш модуль как глобальную переменную с именем module.
Источник.

Update: Благодаря @fotinakis. Убедитесь, что вы проходите --standalone your-module-name. Если вы забудете, что --standalone принимает аргумент, Browserify может бесшумно генерировать пустой модуль, так как он не смог его найти.

Надеюсь, это сэкономит вам некоторое время.

Ответ 3

Ответ @Matas Vaitkevicius с автономной опцией Browserify правильный (ответ @thejh с использованием глобальной переменной window также работает, но, как отмечали другие, он загрязняет глобальное пространство имен, поэтому он не идеален). Я хотел бы добавить немного больше информации о том, как использовать автономную опцию.

В исходном скрипте, который вы хотите связать, не забудьте выставить функции, которые вы хотите вызвать, через module.exports. В клиентском скрипте вы можете вызывать эти открытые функции через <имя-пакета>. <Имя-функции>. Вот пример:

Мой исходный файл 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> <script src="bundle.js"></script><script>var bundled = require("myBundle"); bundled.myFunc();</script> не требуется и не будет работать.

На самом деле, как и все функции, связанные с browserify без автономного режима, функция require не будет доступна за пределами встроенного скрипта. Browserify позволяет использовать некоторые функции Node на стороне клиента, но только в самом сценарии; это не означало создание отдельного модуля, который вы можете импортировать и использовать в любом месте на стороне клиента, поэтому нам нужно пойти на все эти дополнительные проблемы, просто чтобы вызвать одну функцию вне ее связанного контекста.

Ответ 4

Прочитайте README.md обозревателя о параметре --standalone или google "browserify umd"

Ответ 5

Я только что прочитал ответы и похоже, что никто не упомянул об использовании глобальной переменной scope? Что полезно, если вы хотите использовать один и тот же код в node.js и в браузере.

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

Тогда вы можете получить доступ к TestClass в любом месте.

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

Примечание. TestClass становится доступным везде. Что аналогично использованию переменной окна.

Кроме того, вы можете создать декоратор, который предоставляет класс глобальной области видимости. Что действительно хорошо, но мешает отследить, где определена переменная.

Ответ 6

У вас есть несколько вариантов:

  • Пусть плагин browserify-bridge автоматически экспортирует модули в сгенерированный модуль ввода. Это полезно для проектов SDK или ситуаций, когда вам не нужно вручную следить за тем, что экспортируется.

  • Следуйте шаблону пространства псевдо-имен для вскрытия рекламы:

Сначала расположите свою библиотеку так, используя преимущества индексирования в папках:

/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');

Этот шаблон очень хорошо масштабируется и позволяет отслеживать контекстные (папки по папкам), что включать в свернутый api.

Ответ 7

мне нужно время, чтобы разобраться и понять эту проблему даже с этими ответами

это действительно просто - это об упаковке

для этого я предполагаю, что у вас есть только 1 скрипт для всего приложения {{app_name}}

1 альтернатива

добавить функцию к объекту "this"

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

тогда вы должны назвать этот объект как доступный - вы сделаете это, добавив параметр "standalone with name", как советуют другие

так что если вы используете "watchify" с "browserify", используйте этот

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

или командная строка

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

тогда вы можете вызывать свою функцию из браузера

app_name.somefunction(param);
window.app_name.somefunction(param);

2 варианта

добавить функцию к объекту "окно"

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

тогда вы можете вызывать свою функцию из браузера

somefunction(param);
window.somefunction(param);

-

может быть, я помогу кому-то

Ответ 8

Чтобы ваша функция была доступна как из 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>

Run:

npm install uniq
browserify main.js > bundle.js

и вы должны получить те же результаты при открытии main.html в браузере, что и при запуске

node main.js

Ответ 9

В целях отладки я добавил эту строку в свой код code.js:

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

Тогда я мог бы запускать что угодно даже за пределами пакета.

e("anything();");

Ответ 10

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

Вызовите функцию просто по LogData(data)

Это лишь небольшая модификация thejh в ответ, но важный один