NodeJS /浏览器交叉开发

我正在研究针对浏览器和NodeJS应用程序的库。 模块使用AMD惯例,它在理论上足够灵活,足以映射今天的任何情况。 源文件然后将被转换为工具分发给不同的平台 – 再次浏览器和NodeJS。 顺便说一下,有一个叫做uRequire的奇妙工具可以帮助我,但是我仍然不确定我的最佳select,所以我在这里要求相关的经验。

这里是我有的文件层次结构:

- bower_components/ - eventemitter2/ ... - lodash/ ... - source/ - library/ - lodash.js -> ../../bower_components/lodash/dist/lodash.js - EventEmitter.js -> ../../bower_components/eventemitter2/lib/eventemitter2.js - Observable.js: define(["lodash", "EventEmitter"], function(Utility, EventEmitter) { function Observable(options) { ... }; return Observable; }); 

最后,浏览器和NodeJS双方的最大区别是:

  • 浏览器端: EventEmitter实现只是被configuration为“library / EventEmitter”的eventemitter2浏览器模块。
  • EventEmitter端: EventEmitterrequire("events").EventEmitterevents是本地包,不是本地文件或模块。

所以,我的问题是:我怎么可以有Observable对象与NodeJS工作没有大规模的修补? 我不知道如何使EventEmitter实现可用于我的模块,因为它不是一个本地模块(因为我不能写任何path映射),而且它不是直接模块本身,我们将使用,但它的“EventEmitter”属性…

任何帮助/思考,将不胜感激。 我相信很多人都跑了类似的情况,我很想知道他们要说什么!

uRequire使得使用runtimeInfo和select性地在运行时加载替代依赖关系变得微不足道( 如果你不想像这样编写有select性的代码,你可以select在构build时select替代构build并用replace/replace代替deps )。

运行时信息在所有模板中都是相同的,包括UMD和组合 ,所以如果执行的话:

  • 的NodeJS

  • 浏览器与AMD的加载器,如requirejs或

  • 浏览器使用普通的</script>标签,

您可以使用__isAMD__isNode__isWeb运行时variables来dynamicselect每个模块的依赖关系。

你需要的是:

 - bower_components/ - eventemitter2/ ... - lodash/ ... - requirejs/ ... - source/ - library/ - EventEmitter.js - Observable.js: 

例如Observable.js

 define(["lodash", "EventEmitter"], function(_, EventEmitter) { function Observable(options) { this.myOptions = options }; Observable.EventEmitter = EventEmitter; Observable._ = _; return Observable; }); 

EventEmitter.js是:

 define(function(){ var EventEmitter2; if (__isNode) { return require("events").EventEmitter; } else { if (__isAMD) { return EventEmitter2 = require("eventemitter2"); } else if (__isWeb) { return window.EventEmitter2; } } }); 

**说明**:

  • 您不必担心试图在AMD端加载的"events" ,导致其已知的节点dep(否则您将需要列出它) 。

  • EventEmitter2 = require(...)需要build立 导出的依赖项标识符 EventEmitter2window的推断 。 最后一种情况,Web / Script使用window.EventEmitter2感谢! 或者,您可以在depsVars中列出它 。

然后用下面的grunt-urequireconfiguration(在coffeescript中):

 module.exports = gruntFunction = (grunt) -> grunt.initConfig gruntConfig = urequire: library: path: "source/library" dstPath: "build/UMD" runtimeInfo: ['EventEmitter'] # dont need it in other files template: 'UMDplain' combined: derive: 'library' main: 'Observable' dependencies: exports: root: {'Observable': 'Obs'} dstPath: "build/almond/Observable.js" template: 'combined' grunt.loadNpmTasks "grunt-urequire" 

你有两个版本:

A) library :带有单独的UMD文件,你可以在这里运行,例如从source\test\load_node.js

 var Observable = require("../../build/UMD/Observable"); console.log(Observable.EventEmitter); 

或从浏览器( source/test/Loader_unoptimized_AMD.html ):

 <!DOCTYPE html> <html> <head><title>test crossdev: RequireJs, UMD</title></head> <body>Check console!</body> <script src="../../bower_components/requirejs/require.js"></script> <script> require.config ({ baseUrl: '../../build/almond', paths: { lodash: "../../bower_components/lodash/dist/lodash.min", eventemitter2: "../../bower_components/eventemitter2/lib/eventemitter2" } }); require(["Observable" ], function(Observable){ console.log(Observable); console.log(Observable.EventEmitter); }); </script> </html> 

B) combined所有文件内联和有自己的微型加载器( 杏仁 )在nodejs,Web / AMD和Web /脚本工作。 从source/test/Loader_almondJs_plainScript.html运行:

 <!DOCTYPE html> <html> <head><title>test crossdev: plain script, combined/almond</title></head> <body>Check console!</body> <script src="../../bower_components/lodash/dist/lodash.min.js"></script> <script src="../../bower_components/eventemitter2/lib/eventemitter2.js"></script> <script src="../../build/almond/Observable.js"></script> <script> console.log(window.Obs); console.log(window.Obs.EventEmitter); </script> </html> 

或使用RequireJs作为AMD加载器( source/test/Loader_almondJs_AMD.html ):

 <!DOCTYPE html> <html> <head><title>test crossdev: RequireJs, combined/almond</title></head> <body>Check console!</body> <script src="../../bower_components/requirejs/require.js"></script> <script> require.config ({ baseUrl: '../../build/almond', paths: { lodash: "../../bower_components/lodash/dist/lodash.min", eventemitter2: "../../bower_components/eventemitter2/lib/eventemitter2" } }); require(["Observable" ], function(Observable){ console.log(Observable); console.log(Observable.EventEmitter); }); </script> </html> 

你可以在https://github.com/anodynos/nodejs-browser-cross-development中看到testing项&#x76EE;