我维持a JS library我想将其制作成 Node 模块,并与 Node 一起使用。
我的库扩展了 Canvas 上下文 API 并需要 getImageData()
,因此从包装所有代码的防御线开始:
if (window.CanvasRenderingContext2D && CanvasRenderingContext2D.prototype.getImageData){
CanvasRenderingContext2D.prototype.blendOnto = /* … */;
}
对于 Node,我使用 Node Canvas 。为了让我现有的代码正常工作,我需要编写如下所示的 Node 代码:
var Canvas = require('canvas');
GLOBAL.CanvasRenderingContext2D = Canvas.Context2d;
GLOBAL.window = GLOBAL;
require('context_blender');
然而,这显然与 Node 的模块模式背道而驰。如何最好地重写我的库并将其打包为 Node 模块,以便它 (a) 继续在 Web 浏览器中工作,但 (b) 干净地与 Node Canvas 一起工作,而无需通过全局变量传递数据?有没有办法将 Canvas.Context2d 传递给我的模块进行变异?
最佳答案
我建议将您的代码放入模块工厂函数中,如下所示:
var context_blender_factory = function(CanvasRenderingContext2D)
{
var defaultOffsets = {
// ...
};
// Applies to the parameter passed to the module factory function
CanvasRenderingContext2D.prototype.blendOnto = // ...
// ...
}
这本质上抽象了您从哪里获得 CanvasRenderingContext2D
。
然后,在声明函数后,您可以编写初始化例程,在其中检查环境并相应地调用模块工厂。
如果你只想考虑纯 NodeJS,这将是这样的:
if (typeof require === 'function') {
// Assume NodeJS environment
context_blender_factory(require('canvas').Context2d);
}
else if (window &&
window.CanvasRenderingContext2D &&
window.CanvasRenderingContext2D.prototype.getImageData)
{
// Assume browser environment
context_blender_factory(window.CanvasRenderingContext2D);
}
此模式还允许支持 AMD -风格的模块环境,例如 RequireJS或amdefine .
<小时/>背景故事
我和my JS library有类似的情况(请参阅下面的背景故事)。
我最初已经为浏览器实现了我的库。
然后人们开始询问它是否可以在 NodeJS 中工作。这一点也不难,因为 Node 拥有所有相关模块来模仿/实现功能,就像在浏览器中一样。因此,我为 NodeJS 添加了 require
/export
结构。
然后其他一些人开始询问 RequireJS/AMD -风格模块支持。我问过周围:
How to write a module that works with Node.js, RequireJS as well as without them
最后到达following solution支持浏览器、NodeJS、RequiredJS/AMD/amdefine。
关于javascript - 让 JS 库对 Node 和 Window 感到满意,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26837424/