node.js Browserify - 如何在浏览器中调用通过 browserify 生成的文件中捆绑的函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23296094/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Browserify - How to call function bundled in a file generated through browserify in browser
提问by SharpCoder
I am new to nodejs and browserify. I started with this link.
我是 nodejs 和 browserify 的新手。我从这个链接开始。
I have file main.js which contains this code
我有包含此代码的文件 main.js
var unique = require('uniq');
var data = [1, 2, 2, 3, 4, 5, 5, 5, 6];
this.LogData =function(){
console.log(unique(data));
};
Now I Install the uniq module with npm:
现在我用 npm 安装 uniq 模块:
npm install uniq
Then I bundle up all the required modules starting at main.js into a single file called bundle.js with the browserify command:
然后我使用 browserify 命令将所有需要的模块从 main.js 开始打包到一个名为 bundle.js 的文件中:
browserify main.js -o bundle.js
The generated file looks like this:
生成的文件如下所示:
(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])
After including bundle.js file into my index.htm page, how do I call logData function ??
将 bundle.js 文件包含到我的 index.htm 页面后,如何调用 logData 函数?
采纳答案by thejh
By default, browserify doesn't let you access the modules from outside of the browserified code – if you want to call code in a browserified module, you're supposed to browserify your code together with the module. See http://browserify.org/for examples of that.
默认情况下,browserify 不允许您从浏览器代码之外访问模块——如果您想调用浏览器模块中的代码,您应该将代码与模块一起浏览。有关示例,请参阅http://browserify.org/。
Of course, you could also explicitly make your method accessible from outside like this:
当然,您也可以像这样明确地从外部访问您的方法:
window.LogData =function(){
console.log(unique(data));
};
Then you could call LogData()from anywhere else on the page.
然后你可以LogData()从页面上的任何其他地方调用。
回答by Matas Vaitkevicius
The key part of bundling standalone modules with Browserify is the --soption. It exposes whatever you export from your module using node's module.exportsas a global variable. The file can then be included in a <script>tag.
使用 Browserify 捆绑独立模块的关键部分是--s选项。它使用节点module.exports作为全局变量公开您从模块中导出的任何内容。然后可以将该文件包含在<script>标签中。
You only need to do this if for some reason you need that global variable to be exposed. In my case the client needed a standalone module that could be included in web pages without them needing to worry about this Browserify business.
只有在出于某种原因需要公开该全局变量时才需要这样做。就我而言,客户需要一个独立的模块,可以将其包含在网页中,而无需担心此 Browserify 业务。
Here's an example where we use the --soption with an argument of module:
这是我们使用--s参数为的选项的示例module:
browserify index.js --s module > dist/module.js
This will expose our module as a global variable named module.
Source.
这会将我们的模块公开为一个名为module.
来源。
Update:Thanks to @fotinakis. Make sure you're passing --standalone your-module-name. If you forget that --standalonetakes an argument, Browserify might silently generate an empty module since it couldn't find it.
更新:感谢@fotinakis。确保你通过--standalone your-module-name。如果你忘记了它--standalone需要一个参数,Browserify 可能会默默地生成一个空模块,因为它找不到它。
Hope this saves you some time.
希望这可以为您节省一些时间。
回答by Galen Long
@Matas Vaitkevicius's answer with Browserify's standalone optionis correct (@thejh's answer using the window global variablealso works, but as others have noted, it pollutes the global namespace so it's not ideal). I wanted to add a little more detail on how to use the standalone option.
@Matas Vaitkevicius 对Browserify 的独立选项的回答是正确的(@thejh使用 window 全局变量的回答也有效,但正如其他人所指出的,它会污染全局命名空间,因此并不理想)。我想添加更多关于如何使用独立选项的细节。
In the source script that you want to bundle, make sure to expose the functions you want to call via module.exports. In the client script, you can call these exposed functions via <bundle-name>.<func-name>. Here's an example:
在要捆绑的源脚本中,确保通过 module.exports 公开要调用的函数。在客户端脚本中,您可以通过<bundle-name>.<func-name>调用这些公开的函数。下面是一个例子:
My source file src/script.jswill have this:module.exports = {myFunc: func};
我的源文件 src/script.js将包含以下内容:module.exports = {myFunc: func};
My browserify commandwill look something like this:browserify src/script.js --standalone myBundle > dist/bundle.js
我的browserify 命令看起来像这样:browserify src/script.js --standalone myBundle > dist/bundle.js
And my client script dist/client.jswill load the bundled script<script src="bundle.js"></script>
and then call the exposed function like this:<script>myBundle.myFunc();</script>
我的客户端脚本 dist/client.js将加载捆绑脚本<script src="bundle.js"></script>
,然后像这样调用公开的函数:<script>myBundle.myFunc();</script>
There's no need to require the bundle name in the client script before calling the exposed functions, e.g. isn't necessary and won't work. <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>
In fact, just like all functions bundled by browserify without standalone mode, the require function won't be available outside of the bundled script. Browserify allows you to use some Node functions client-side, but only in the bundled script itself; it's not meant to create a standalone module you can import and use anywhere client-side, which is why we have to go to all this extra trouble just to call a single function outside of its bundled context.
事实上,就像没有独立模式的 browserify 捆绑的所有函数一样,require 函数在捆绑的 script 之外将不可用。Browserify 允许您在客户端使用一些 Node 函数,但仅限于捆绑脚本本身;它并不意味着创建一个独立的模块,您可以在客户端的任何地方导入和使用,这就是为什么我们必须去处理所有这些额外的麻烦,只是为了在其捆绑上下文之外调用单个函数。
回答by DDD
I just read through the answers and seems like nobody mentioned the use of the global variable scope? Which is usefull if you want to use the same code in node.js and in the browser.
我只是通读了答案,似乎没有人提到使用全局变量作用域?如果你想在 node.js 和浏览器中使用相同的代码,这很有用。
class Test
{
constructor()
{
}
}
global.TestClass = Test;
Then you can access the TestClassanywhere.
然后您可以在任何地方访问TestClass。
<script src="bundle.js"></script>
<script>
var test = new TestClass(); // Enjoy!
</script>
Note:The TestClass then becomes available everywhere. Which is the same as using the window variable.
注意:然后 TestClass 可以在任何地方使用。这与使用 window 变量相同。
Additionally you can create a decorator that exposes a class to the global scope. Which is really nice but makes it hard to track where a variable is defined.
此外,您可以创建一个装饰器,将类暴露给全局范围。这真的很好,但很难跟踪变量的定义位置。
回答by undoZen
Read README.md of browserify about --standaloneparameter
or google "browserify umd"
阅读 browserify 的 README.md 关于--standalone参数或谷歌“browserify umd”
回答by Ori Miller
To have your function available from both the HTML and from server-side node:
要从 HTML 和服务器端节点都可以使用您的函数:
main.js:
主要.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
and you should get same results when opening main.html in a browser as when running
并且在浏览器中打开 main.html 时应该得到与运行时相同的结果
node main.js
回答by deepelement
You have a few options:
您有几个选择:
Let plugin browserify-bridgeauto-export the modules to a generated entry module. This is helpful for SDK projects or situations where you don't have to manually keep up with what is exported.
Follow a pseudo-namespace pattern for roll-up exposure:
让插件browserify-bridge自动将模块导出到生成的入口模块。这对于 SDK 项目或您不必手动跟上导出内容的情况很有帮助。
遵循伪命名空间模式进行汇总曝光:
First, arrange your library like this, taking advantage of index look-ups on folders:
首先,像这样安排你的库,利用文件夹上的索引查找:
/src
--entry.js
--/helpers
--- index.js
--- someHelper.js
--/providers
--- index.js
--- someProvider.js
...
With this pattern, you define entry like this:
使用此模式,您可以像这样定义条目:
exports.Helpers = require('./helpers');
exports.Providers = require('./providers');
...
Notice the require automatically loads the index.js from each respective sub-folder
请注意 require 会自动从每个子文件夹中加载 index.js
In your subfolders, you can just include a similar manifest of the available modules in that context:
在您的子文件夹中,您可以只包含该上下文中可用模块的类似清单:
exports.SomeHelper = require('./someHelper');
This pattern scales really well and allows for contextual (folder by folder) tracking of what to include in the rolled-up api.
这种模式的扩展性非常好,并允许上下文(逐个文件夹)跟踪要包含在汇总 api 中的内容。
回答by BG Bruno
it takes me a while figure out and understand this issue even with these answers
即使有了这些答案,我也需要一段时间才能弄清楚并理解这个问题
it's really simple - it's about wrapping
这真的很简单 - 它是关于包装
for this purpose I'll assume you have only 1 script for whole app {{app_name}}
为此,我假设整个应用程序 {{app_name}} 只有 1 个脚本
1 alternative
1 个选择
add function to object "this"
向对象“this”添加函数
function somefunction(param) {}
->
this.somefunction = function(param) {}
then you have to name that object to be available - you will do it add param "standalone with name" like others advised
然后你必须命名该对象可用 - 你会像其他人建议的那样添加参数“独立名称”
so if you use "watchify" with "browserify"use this
因此,如果您将“watchify”与“browserify”一起使用,请使用它
var b = browserify({
...
standalone: '{{app_name}}'
});
or command line
或命令行
browserify index.js --standalone {{app_name}} > index-bundle.js
then you can call your function from browser
然后你可以从浏览器调用你的函数
app_name.somefunction(param);
window.app_name.somefunction(param);
2 alternative
2 备选
add function to object "window"
向对象“窗口”添加函数
function somefunction(param) {}
->
window.somefunction = function(param) {}
then you can call your function from browser
然后你可以从浏览器调用你的函数
somefunction(param);
window.somefunction(param);
--
——
maybe I help someone
也许我帮助某人
回答by Pratik Khadtale
回答by Karveiani
For debugging purposes I added this line to my code.js:
出于调试目的,我将此行添加到我的 code.js 中:
window.e = function(data) {eval(data);};
Then I could run anything even outside the bundle.
然后我甚至可以在包之外运行任何东西。
e("anything();");

