我开发了一个节点NPM包,它主要是一个特定JSON API的包装器(使用节点的http
,https
和querystring
模块)。它是在Coffeescript中构建的,并使Node.js服务器能够与此API通信。 Api主要是REST。
现在我希望这个库也可用于浏览器。这意味着对http
模块的调用需要替换为XMLHttpRequest
(异步)。在我看来,我会为适配器做一个包装器。对于Node环境,此适配器会将所有调用传递给http
模块,将浏览器环境传递给XMLHttpRequest
对象。
有没有一个很好的方法来构建一个构建系统,以便npm包包含两个版本,我也可以在Github上发布简单的“浏览器版本”?然后,节点包可以通过require('package-name')
获得,并且应该将JS文件(用于浏览器)放在目录中。
我查看了Component,这对于客户端软件包管理非常好,但问题仍然是如何创建不同的构建环境。
答案 0 :(得分:5)
使用browserify对node.js和浏览器进行交叉开发的示例解决方案:https://github.com/amitayd/grunt-browserify-jasmine-node-example(and discussion at my blog post)。
特别是对于Browser / Node.js的不同实现,请检查PersistentReaderWriter.js。
一旦你有一些模板开始使用browserify,并且你意识到一些陷阱,你可能会发现你也想将它用于小型库。
编辑:请注意,如果浏览模块,则不应通过检查是否定义了module和module.exports来检查isBrowser(),因为Browserify的包装器将在模块上下文中定义它们。相反,在我的例子中,我检查要定义的窗口。
答案 1 :(得分:1)
在模块的末尾添加它。并像这样导出你的模块。
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
module.exports = YourModule;
}
else {
if (typeof define === 'function' && define.amd) {
define([], function() {
return YourModule;
});
}
else {
window['YourModule'] = YourModule;
}
}
答案 2 :(得分:0)
我找到了一个解决方案,虽然它不是第一个想到的,具有不同的构建环境。
在我的情况下,我有一个非常小的库,它使用Node的http
,https
,querystring
和url
包。我不想使用Browserify这样的东西,因为将所有这些包捆绑在一个小的api库中似乎不合适。相反,我将http
和https
功能替换为XMLHttpRequest包。 querystring
和url
提供的小功能很容易被重写。
在我的库中,如果window.XMLHttpRequest
对象可用,我会检查运行时。如果是这样,请使用该(本机)对象。否则,它使用包提供的那个。就这样:
_getRequestObject: () ->
if window? and window.XMLHttpRequest?
return new window.XMLHttpRequest()
if window? and window.ActiveXObject?
try
request = new ActiveXObject('Msxml2.XMLHTTP')
catch e
try
request = new ActiveXObject('Microsoft.XMLHTTP')
catch e
XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest
return new XMLHttpRequest()
另一个问题是浏览器中未定义exports
。有一些软件包可以模拟这种行为,但同样,它不想让文件库膨胀。所以我再次检查运行时是否设置了module
变量。如果是这样,我定义的对象设置为,否则设置为window
对象:
if typeof module is 'undefined'
window['My-module'] = My_module_object
else
module.exports = exports = My_module_object
这一切都适合我,因为我没有真正需要的Node.js依赖项,这些依赖项在浏览器环境中不存在。我担心,对于较大的项目,确实需要像Browserify这样的解决方案,但我仍然很好奇是否有其他解决方案,例如在为Node.js打包库时创建不同的构建环境或者(例如)亭子。
答案 3 :(得分:0)
您可以使用node-browser-resolve
向browser
添加package.json
部分:
{
"browser": {
"./index.js": "./browser.js"
}
}
请参阅https://nolanlawson.com/2017/01/09/how-to-write-a-javascript-package-for-both-node-and-the-browser/