@c4dt/nativescript-nodeify
由 c4dt 编写 | v0.8.0
尝试让大多数 npm 模块与 NativeScript 兼容
npm i --save @c4dt/nativescript-nodeify

NativeScript Nodeify

使大多数 npm 包与 NativeScript 兼容

问答

问:WTF?

答:好问题,很高兴你问了!你不能直接使用任何 npm 包与 NativeScript 兼容,因为它们可能依赖于内置的 Node 模块(如 fspathcrypto 等)。这些模块不是普通的 JavaScript 文件,所以它们不能在 {N} 运行时中执行。

问:那么这个插件是如何克服这种情况的呢?

答:你可以像平常一样安装依赖项,包括这个插件,然后在构建时,这个插件安装的钩子会扫描并修改你的 npm 模块(在 平台文件夹 中),使其适合 {N} 兼容。

问:Lol. Wut?修改我珍贵的模块!?

答:是的。钩子会检查在 <app>/platforms/<ios|android>/.../tns_modules 中安装的包,并对每个依赖项执行一些操作:

  • 在它们的 package.json 中查找 browser 节点,并替换该包及其依赖项中匹配的任何 require() 调用。
  • 如果 browser 节点中有 main 替换,它也会处理这个。
  • 如果任何依赖项(这可能很深——记得 left-pad?)包含我们需要模拟的东西,我们将基于 这个列表 进行操作。
  • 还有更多的技巧,可能还需要更多,所以这个列表目前正在不断发展。

问:但浏览器ify / Webpack 不是已经为我们解决这个问题了吗?

答:在这个情况下不是,至少不是没有进一步的修改。想想那些没有在 package.json 中包含 browser 节点的模块,或者那些确实包含但用一些需要在真实浏览器中运行的东西来模拟 Node 依赖的模块。你可以自由地提交一个 PR 以获得更优雅的实现,但这是我所能想到的最好的办法。

问:实际上还不错,但不会带来性能损失吗?

答:谢谢。这是个好问题。最重要的是,在运行时,这应该没有区别,因为你没有 'require' 更多的东西,只是不同的实现(希望实际上可行)。在构建时,你会看到构建时间增加了几秒钟(但这不应该影响 livesync)。钩子会跳过检查 tns-core-modules 和以 nativescript 开头的任何内容。

安装

从命令提示符进入你的应用程序根目录并执行

tns plugin add nativescript-nodeify

使用方法

在要求有问题的 npm 模块之前,将此包含在代码中。

require("nativescript-nodeify");

演示应用程序

演示 测试了一些流行的库,这些库依赖于 Node 内置模块,在 NativeScript 运行时环境中通常无法工作。

从项目的根目录运行演示应用程序: npm run demo.iosnpm run demo.android

已知问题

此插件并不完美,但它试图解决成千上万 npm 包中的问题。已知一些问题,如果你的问题不在这个列表中,请 创建一个问题

  • 与Browserify类似,我们使用shims来填补Node和浏览器之间的差距,但与Browserify的shims不同,我们不在浏览器中运行,因此一些API可能不可用。例如,任何接触DOM的东西。
  • http shim并不完美(例如,使用global.location.protocol.search),所以可能需要像RN所做的那样,自行实现(如果有人需要的话)。

食谱

为了帮助你开始使用一些流行的npm模块,这里有一些食谱。请通过向这个仓库发送PR分享你自己的食谱!

所有食谱都假设你已经做了

$ tns create awssdk
$ cd awssdk
$ tns platform add ios
$ tns platform add android
$ tns plugin add nativescript-nodeify

node-uuid

$ npm install node-uuid --save

Boom!完成了。

jsonwebtoken

$ npm install jsonwebtoken --save

Boom!再次完成。

aws-sdkamazon-cognito-identity-js(它包括aws-sdk

这个需要一点更多的设置,但并不太难

永远不要将你的AWS密钥提交到代码库!机器人会扫描公开的仓库,并为你创建服务器实例,你将为此付费。

根据你的需要

$ npm install aws-sdk --save

或者

$ npm install amazon-cognito-identity-js --save

为了正确解析AWS返回的XML(例如,在列出S3存储桶内容时),我们需要修补一个额外的库,因为浏览器shim期望一个...嗯...浏览器。

所以打开你的应用的package.json,将这个nodeify节点添加到现有的nativescript节点中

{
"nativescript": {
"nodeify": {
"package-dependencies": {
"aws-sdk": [
{
"xml/browser_parser": "xml/node_parser",
"lib/node_loader": "lib/browser_loader"
}
]
}
}
}
}

然后在你的amazon-cognito-identity-js代码中

// require this to fix an issue with xhr event states
require('nativescript-nodeify');

// register a user (here's a bit, but see the demo and https://github.com/aws/amazon-cognito-identity-js for details)
var AmazonCognitoIdentity = require('amazon-cognito-identity-js');
var CognitoUserPool = AmazonCognitoIdentity.CognitoUserPool;
var userPool = new CognitoUserPool({UserPoolId: 'foo', ClientId: 'bar'});

现在就可以像往常一样使用AWS了

// then require AWS and interact with s3, dynamo, whatnot
var AWS = require('aws');