12

我开发了一个 node NPM 包,它主要是特定 JSON API的包装器(使用 node 和http模块)。它在 Coffeescript 中构建,使 Node.js 服务器能够与此 API 进行通信。Api 主要是 REST。httpsquerystring

现在我希望这个库也可用于浏览器。这意味着对模块的调用http需要替换为XMLHttpRequest(异步)。在我看来,我会为适配器制作一个包装器。对于 Node 环境,此适配器会将所有调用传递给http模块,对于浏览器环境,此适配器会将所有调用传递给XMLHttpRequest对象。

有没有一种很好的方法来构建构建系统,以便 npm 包包含两个版本,并且我也可以在 Github 上发布普通的“浏览器版本”?然后节点包可以通过require('package-name')并且应该在目录中放置一个 JS 文件(用于浏览器)。

我查看了Component,它非常适合客户端包管理,但问题仍然是如何创建不同的构建环境。

4

4 回答 4

5

使用 browserify 对 node.js 和浏览器进行交叉开发的示例解决方案:https ://github.com/amitayd/grunt-browserify-jasmine-node-example (以及我的博客文章中的讨论)。

特别是对于 Browser/Node.js 的不同实现,请检查PersistentReaderWriter.js

一旦你有了一些模板来开始使用 browserify,并且你意识到了一些陷阱,你可能会发现你也想将它用于小型库。

编辑:请注意,如果您浏览模块,则 isBrowser() 检查不应该通过检查模块和 module.exports 是否已定义,因为 Browserify 的包装器将在模块上下文中定义它们。相反,在我的示例中,我检查要定义的窗口。

于 2013-05-16T23:54:57.787 回答
1

您可以使用node-browser-resolvewhich 添加一个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/

于 2017-06-30T08:46:36.740 回答
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;
  }
}
于 2018-01-03T20:41:01.953 回答
0

我找到了一个解决方案,尽管它不是最初想到的,但具有不同的构建环境。

就我而言,我有一个非常小的库,它使用 Node 的、httphttps包。我不想使用Browserify之类的东西,因为将所有这些包捆绑到一个小型 api 库中似乎不合适。相反,我用XMLHttpRequest包替换了and功能。由提供的小功能可以很容易地重写。querystringurlhttphttpsquerystringurl

在我的库中,我检查运行时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 打包库或为(例如)Bower 时创建不同的构建环境。

于 2013-05-10T07:49:25.490 回答