通过 Browserify 在浏览器中使用 NPM 包
Using NPM package in the browser with Browserify
我正在尝试使用 Browserify,以便我可以在浏览器中使用 npm 包。我尝试使用的包是 this
我有一个 fcs.js 文件:
// Use a Node.js core library
var FCS = require('fcs');
// What our module will return when require'd
module.exports = function(FCS) {
return FCS;
};
还有一个 index.js 文件:
var FCS = require('./fcs.js');
console.log('FCS IS ');
console.log(FCS);
然后我运行:
browserify index.js > bundle.js
并创建了一个 index.html 文件:
<html>
<script src="bundle.js"></script>
<script>
var fcs = new FCS();
</script>
</html>
但我最终遇到了错误:
Uncaught ReferenceError: FCS is not defined
也许我没有正确理解这个概念。我如何在浏览器中使用这个包?谢谢。
不要这样做:require('./fcs.js');
这样做:require('./fcs');
当您 require
某些内容时,扩展名是隐含的 .js
。还要确保您的模块 FCS
有一个入口点(默认值为 index.js
,但您可以在 package.json
的 main
条目中更改它)。
此外,在您的 index.html
文档中,您期望 FCS
是一个全局对象。我还没有看到 FCS
的内部代码,但它只有附加到 window
对象后才会全局可用。
当您 require
某些东西时,它只会让您的其余代码在需要时可用。如果你想让它 全局 可用,你必须将它附加到 window
对象,就像其他任何东西一样。
换句话说,您的 FCS
模块的内部结构可能类似于:
// node_modules -> fcs -> index.js
var FCS = function() {};
window.FCS = FCS; // this makes it globally available
module.exports = FCS; // this lets you require it
问题是您的内联脚本(在 index.html
中)期望存在一个名为 FCS
的全局变量(当您这样做时 new FCS()
)。事实并非如此,因为在 index.js
中,您的 FCS 变量的范围仅限于该文件。
您应该将所有脚本编写在单独的文件中,并使用 browserify 将它们全部捆绑在一起,避免使用内联脚本或将 FCS
附加到 window
.
使其成为全局脚本
@JoshBeam 的回答是正确的——为了公开 browserify 包内的资产,您需要将一些东西附加到 window
对象。但是我不想公开特定资产,而是想要更通用的东西。
这是我所做的:
在我的 app.js
require('this')
require('that')
require('./modules/mycode')
...
window.req = require
在我的 HTML 中的 <script>
标签中:
something = req('./modules/mycode')
请注意,我没有将 require
函数直接分配给 window.require
,而是给了它一个不同的名称。原因很简单:如果你调用它 window.require
,你将覆盖原来的 require
并且你会发现自己处于递归的无限循环中(至少直到浏览器用完堆栈space).
我正在尝试使用 Browserify,以便我可以在浏览器中使用 npm 包。我尝试使用的包是 this
我有一个 fcs.js 文件:
// Use a Node.js core library
var FCS = require('fcs');
// What our module will return when require'd
module.exports = function(FCS) {
return FCS;
};
还有一个 index.js 文件:
var FCS = require('./fcs.js');
console.log('FCS IS ');
console.log(FCS);
然后我运行:
browserify index.js > bundle.js
并创建了一个 index.html 文件:
<html>
<script src="bundle.js"></script>
<script>
var fcs = new FCS();
</script>
</html>
但我最终遇到了错误:
Uncaught ReferenceError: FCS is not defined
也许我没有正确理解这个概念。我如何在浏览器中使用这个包?谢谢。
不要这样做:require('./fcs.js');
这样做:require('./fcs');
当您 require
某些内容时,扩展名是隐含的 .js
。还要确保您的模块 FCS
有一个入口点(默认值为 index.js
,但您可以在 package.json
的 main
条目中更改它)。
此外,在您的 index.html
文档中,您期望 FCS
是一个全局对象。我还没有看到 FCS
的内部代码,但它只有附加到 window
对象后才会全局可用。
当您 require
某些东西时,它只会让您的其余代码在需要时可用。如果你想让它 全局 可用,你必须将它附加到 window
对象,就像其他任何东西一样。
换句话说,您的 FCS
模块的内部结构可能类似于:
// node_modules -> fcs -> index.js
var FCS = function() {};
window.FCS = FCS; // this makes it globally available
module.exports = FCS; // this lets you require it
问题是您的内联脚本(在 index.html
中)期望存在一个名为 FCS
的全局变量(当您这样做时 new FCS()
)。事实并非如此,因为在 index.js
中,您的 FCS 变量的范围仅限于该文件。
您应该将所有脚本编写在单独的文件中,并使用 browserify 将它们全部捆绑在一起,避免使用内联脚本或将 FCS
附加到 window
.
@JoshBeam 的回答是正确的——为了公开 browserify 包内的资产,您需要将一些东西附加到 window
对象。但是我不想公开特定资产,而是想要更通用的东西。
这是我所做的:
在我的 app.js
require('this')
require('that')
require('./modules/mycode')
...
window.req = require
在我的 HTML 中的 <script>
标签中:
something = req('./modules/mycode')
请注意,我没有将 require
函数直接分配给 window.require
,而是给了它一个不同的名称。原因很简单:如果你调用它 window.require
,你将覆盖原来的 require
并且你会发现自己处于递归的无限循环中(至少直到浏览器用完堆栈space).