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
端:EventEmitter
从require("events").EventEmitter
,events
是本地包,不是本地文件或模块。
所以,我的问题是:我怎么可以有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立 导出的依赖项标识符EventEmitter2
到window
的推断 。 最后一种情况,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项目