gpt4 book ai didi

javascript - NodeJS/浏览器交叉开发

转载 作者:行者123 更新时间:2023-11-30 05:37:49 24 4
gpt4 key购买 nike

我正在开发一个同时针对浏览器和 NodeJS 应用程序的库。模块使用 AMD 约定,该约定在理论上足够灵活,可以映射当今几乎所有情况。然后使用工具转换源文件以分发给不同的平台——同样是浏览器和 NodeJS。顺便说一下,有一个很棒的工具叫做 uRequire来帮助解决这个问题,但我仍然不确定我的最佳选择是什么,所以我在这里询问相关经验。

这是我的文件层次结构:

- 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 实现只是配置为“library/EventEmitter”的eventemitter2 浏览器模块;
  • NodeJS 端:EventEmitter 是从 require("events").EventEmitter 获取的,其中 events 是一个原生包,而不是一个本地文件或模块;

所以,我的问题是:如何让 Observable 对象在不进行大量修改的情况下与 NodeJS 一起工作?我不确定如何使 EventEmitter 实现对我的模块可用,因为它不是本地模块(因此我不能编写任何路径映射)而且它不是直接的模块我们将使用它本身,但它的“EventEmitter”属性...

任何帮助/想法将不胜感激。我相信很多人都遇到过类似的情况,我很想知道他们有什么要说的!

最佳答案

uRequire使用 runtimeInfo 变得简单并在运行时选择性地加载替代依赖项(如果您不想像这样编写选择性代码,您总是可以选择在构建时使用替代构建和 replace deps with alternative/mocks)。

Runtime info在所有模板中工作相同,包括 UMDcombined ,所以如果执行于:

  • Node

  • 浏览器 带有 AMD 加载器,如 requirejs或者

  • 浏览器 显示 </script>标记,

您可以使用 __isAMD 动态选择每个模块依赖项在每种情况下的含义。 , __isNode & __isWeb运行时变量。

你需要的是:

- 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;
}
}
});

** 注释** :

然后用下面的grunt-urequire配置(在 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内联所有文件并拥有自己的迷你加载器(almond),适用于 nodejs、Web/AMD 和 Web/Script。从 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可以看到测试项目

关于javascript - NodeJS/浏览器交叉开发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22512486/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com